Custom SPI protocol kernel module and device tree

117 views
Skip to first unread message

Георгий Одишария

unread,
May 29, 2017, 1:44:09 PM5/29/17
to BeagleBoard
Hello. I have trouble trying to get information from DT in my kernel module.

I made and built device tree overlay similar to one for spidev kernel module. Here it is:
/dts-v1/;
/plugin/;


/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";


    /
* identification */
    part-number = "BB-ARDUINO-ECHO";
    version = "00A0";
 
    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            spi0_pins_s0: spi0_pins_s0 {
 pinctrl-single,pins = <
 0x150 0x30      /
* mcasp0_aclkx.spi0_sclk, INPUT_PULLUP  | MODE0 */
 0x154 0x30      /
* mcasp0_fsx.spi0_d0,     INPUT_PULLUP  | MODE0 */
 0x158 0x10      /
* mcasp0_axr0.spi0_d1,    OUTPUT_PULLUP | MODE0 */
 0x15c 0x10      /
* mcasp0_ahclkr.spi0_cs0, OUTPUT_PULLUP | MODE0 */
 
>;
           
};
       
};
   
};


    fragment@1
{
        target
= <&spi0>;
        __overlay__
{


           
#address-cells = <1>;
           
#size-cells = <0>;
            status
= "okay";
            pinctrl
-names = "default";
            pinctrl
-0 = <&spi0_pins_s0>;
           
            ardiuno_echo@0
{
                compatible
= "arduino,pro-mini-spi-generic";
                reg
= <0>;
                spi
-max-frequency = <100000>;
           
};
       
};
   
};
};

And here I trying to access spi-max-frequency property from my probe() function of device driver:
static int spi_protocol_generic_probe(struct spi_device *spi)
{
 
int err, ret;
 
int devData = 0;
 
const struct of_device_id *match;


 
struct device_node *of_target_node;
 u32 max_speed_arduino
= 0;


 
const char *of_compt_str = kcalloc(sizeof(char), 255, GFP_KERNEL);


 __spi_device_internal
= spi;
 default_values
.speed_hz = spi->max_speed_hz;
 default_values
.mode = spi->mode;
 default_values
.bits_per_word = spi->bits_per_word;


 debug_printk
("spi-protocol-generic: default speed is %d Hz\n",
     default_values
.speed_hz);


 
// check and read data from of_device_id...
 match
= of_match_device(spi_protocol_generic_of_match, &spi->dev);
 
if (!match) {
 debug_printk
("device not found in device tree...\n");
 
return -1;
 
}
 of_target_node
= of_find_compatible_node(NULL, NULL, match->compatible);
 
if (!of_target_node) {
 of_node_put
(of_target_node);
 debug_printk
("no compatible devices in DT!\n");
 
}


 
// Here we can use of_get_property, but I prefer more readable
 
// code insted of mire obvious
 ret
= of_property_read_u32(of_target_node, "spi-max-frequency",
   
&max_speed_arduino);


 
if (ret) {
 debug_printk
("cannot find property in DT node, status %d\n",
     ret
);
 
return ret;
 
} else {
 debug_printk
("freq is %x Hz\n", max_speed_arduino);
 
}


 spi
->bits_per_word = 8;
 spi
->mode = SPI_MODE_0;
 spi
->max_speed_hz = max_speed_arduino;
 err
= spi_setup(spi);


 
if (err < 0) {
 printk
(KERN_DEBUG "spi-protocol-generic: spi_setup failed!\n");
 
return err;
 
} else {
 printk
(KERN_DEBUG "spi-protocol-generic: now speed is %d Hz\n",
       spi
->max_speed_hz);
 
}
       
// ... and so on ...
}

I can access other properties such as reg and compatible. But even if I am trying to get the property of DT from sysfs, this property seems to have invalid value.
For example, if I set spi-max-frequency to 1000000 (1 MHz), value from sysfs will be invalid and it won't equal 1000000. This value is not depending from my value in DT overlay.

How can I set this property correctly?

Георгий Одишария

unread,
May 29, 2017, 5:29:07 PM5/29/17
to BeagleBoard
Also:

root@arm:~# cat /sys/bus/spi/devices/spi1.0/of_node/spi-max-frequency | hexdump
0000000 6e01 0036                               
0000004
Reply all
Reply to author
Forward
0 new messages