Jump to content

Device Tree and Pinctrl question


Zeiss

Recommended Posts

Hello guys,

 

hope I'm in the right subforum. If not, please postpone. I have a question about the device tree and pinctrl...

 

I have added a chip to my I2C-0, the configuration looks like this:

 

&i2c0 {
	clock-frequency = <400000>;
	status = "okay";
	
	os8104: os8104@41 {
		compatible = "smsc,os8104";
		reg = <0x41>;
		master = <0>;					/* slave mode*/
		bypass = <0>;					/* /ABY (all bypass mode) im register bXCR */
		
		pinctrl-names = "default";
		pinctrl-0 = <&os8104_reset &os8104_int &os8104_aint &os8104_error &os8104_3dB>;
		
	};
};

 

Then, under pinctrl I have added this block:

&pinctrl {
	ir {
		ir_int: ir-int {
			rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};

...
	
	os8104 {
		os8104_reset: os8104-reset {
			rockchip,pins = <RK_GPIO2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
		};
		
		os8104_int: os8104-int {
			rockchip,pins = <RK_GPIO3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
		};
		
		os8104_aint: os8104-aint {
			rockchip,pins = <RK_GPIO3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
		};
		
		os8104_error: os8104-error {
			rockchip,pins = <RK_GPIO3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>;
		};
		
		os8104_3dB: os8104-3dB {
			rockchip,pins = <RK_GPIO3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>;
		};
	};
};

But, how can I access these pins from the LKM? I'm using of_find_node_by_name to find the device node.

 

Board is Rock64 and kernel is 4.4.143

 

Many thanks.

Link to comment
Share on other sites

OS8104 is a network IC for MOST bus, but it doesn't matter.... this is a fundamental question. 

 

It is possibile to reference the pins directly in device section or go throw pinctrl section. In first case te pins are accessible by devm_gpiod_get (...). But how can I do this, if a go throw pinctrl?

 

And www.mein-bmw-rudel.de (or www.bmw-rudel.de) is my homepage :)

Link to comment
Share on other sites

16 hours ago, Zeiss said:

And www.mein-bmw-rudel.de (or www.bmw-rudel.de) is my homepage

Oh ! This means Google made you popular by being the first link ... ;)

 

I'm not sure I really understand your question. If you are writing your own kernel driver, the pins can be control with gpio_request() followed by gpio_direction_output() and then toggled with gpio_set_value().

Link to comment
Share on other sites

1 hour ago, martinayotte said:

Oh ! This means Google made you popular by being the first link ... ;)

 

I'm not sure I really understand your question. If you are writing your own kernel driver, the pins can be control with gpio_request() followed by gpio_direction_output() and then toggled with gpio_set_value().

Seems to be so.

 

Okay, I try to explain it. Yes, I'm writing my own LKM for this chip.

 

It is possible to "reference" pins directly in the section, like this:

 

	os8104: os8104@41 {
		compatible = "smsc,os8104";
		reg = <0x41>;
		master = <0>;					/* slave mode*/
		bypass = <0>;					/* /ABY (all bypass mode) im register bXCR */
		
		reset-gpios = <&pio 8 17 0>;	/* PI17 */
		int-gpios = <&pio 8 16 0>;		/* PI16 */
		aint-gpios = <&pio 8 19 0>;		/* PI19 */
		error-gpios = <&pio 8 18 0>;	/* PI18 */
		3db-gpios = <&pio 8 20 0>;		/* PI20 */
	};

To get access to those pins (PI 17,  PI 19 and so one), just do:

 

devm_gpiod_get (&client->dev, "reset", GPIOD_OUT_HIGH);

This means "give me the pin named reset and initialize them as output with logic 1", the third parameter is optional and can be done later by calling gpiod_direction_output() (check include/linux/gpio/consumer.h for this).

 

I would like to do the same, but throw pinctrl, so configure the GPIOs in pinctrl section and reference them from chip section, like in example in first post.

 

Why? In rockchip dtbs it seems to be the way.

Link to comment
Share on other sites

BTW, I'm not fluent with Rockchip...

I did something similar recently with gpios defined directly in device node, like your example, but I've used of_get_named_gpio() instead of devm_gpiod_get(), followed by gpio_is_valid() and finally gpio_request()/gpio_direction_output().

Maybe devm_gpiod_get() is good too, but I'm not fluent with it, I've learn those stuff only recently ...

 

Link to comment
Share on other sites

Mmh, the first question that arise to me is if you are really sure about your setup.

Looking at the device tree you described I see that:

1) you attached the os8104 to the i2c bus 0 and configured it to use address 0x41 on that bus

2) you attached some pins of os8104 to the board gpio

3) you describe a "default" pin configuration using pinctrl-names and pinctrl-0 properties. What you do with these directives is more like: "Setup the board pins with those settings at default", and not "my device uses these pins and I want to control them from the kernel".

 

Actually your kernel module does not know about the "default pins configuration", you should instead also describe the GPIO bank and pins used with some proprietary codes. Something like this:

&i2c0 {
	clock-frequency = <400000>;
	status = "okay";
	
	os8104: os8104@41 {
		compatible = "smsc,os8104";
		reg = <0x41>;
		master = <0>;					/* slave mode*/
		bypass = <0>;					/* /ABY (all bypass mode) im register bXCR */
        os8104,reset-gpio = <&gpio2 RK_PD7 ACTIVE_HIGH>;
        os8104,int-gpio = <&gpio3 RK_PA4 ACTIVE_HIGH>;
        .
        .
        .
		
		pinctrl-names = "default";
		pinctrl-0 = <&os8104_reset &os8104_int &os8104_aint &os8104_error &os8104_3dB>;
		
	};
};

 

Then you should be able to grab the gpio from your kernel module using the OF functions.

You may take a look to the other device trees and drivers combo shipped with the linux kernel for other examples

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines