binding for nvec mfd device

Marc Dietrich marvin24 at gmx.de
Fri Jun 28 04:26:08 EST 2013


Hi,

I'm puzzling for some time now to find a binding for a mfd device. So let's 
start with something I think I have learned already, let's describe the 
hardware.

Here the problem starts, because the nvec (nvidia [protocol] compliant 
embedded controller) isn't a well defined piece of silicon at all, but more a 
protocol which specifies how to communicate with certain devices (keyboard, 
mouse, gpio, system state, battery, oem specific hw ...). Even worse, the 
number of "attached" devices may vary for each implementation and there is no 
way to sanely probe which which devices exist or not.

For example, the "hardware" in my case is an ENE KB926 keyboard controller 
with an additional ps/2 port (for the touchpad) and a number of gpio's for 
connecting leds, spi bus, a charger chip and some other stuff. Most gpio's 
cannot be controlled directly, but only through certain ec commands. The i2c 
protocol used for communication with the host cpu is handled by a good old 
8051 type integrated in the keyboard controller.

Other vendors may implement this in totally different hardware, keeping only 
the protocol. So I think this is a case where the "describe the hardware" 
principle just fails.

So I thought ok - forget this principle for now and describe it from a higher 
protocol point of view. We currently have something like this:

        nvec at 7000c500 {
                compatible = "nvidia,nvec";
                reg = <0x7000c500 0x100>;
                interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                clock-frequency = <80000>;
                request-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
                slave-addr = <138>;
                clocks = <&tegra_car TEGRA20_CLK_I2C3>,
                         <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
                clock-names = "div-clk", "fast-clk";
        };

which describes how the host cpu should setup the i2c communication. The 
devices are currently hard coded in the driver, but I like to make them more 
flexible through a device tree binding, eg. something like this:

		nvec {
				...
				<properties from above>
				...

				keyboard {
						<add some key bindings here>
				};

				ps2 {
						packet-size = 6; /* for the ac100 tp */
				};

				events {
						<add some system events here, e.g. lid switch,
						power button>
				};

				charger: ac {
						<nothing here>
				};

				battery {
						charger = <&charger>;
				};

				oem {
						name = "paz00"; /* ac100 specific extentions to the
											protocol */
				};
		};

One question is now how to instantiate the mfd children from this. I see three 
different methods used in different drivers:

		a) just add a "compatible =" property to the child nodes and a 
			"simple-bus" property to the the driver
		b) search for sub-nodes and instantiate the children "manually" by
			"guessing" some driver name from the node name and use 
			platform_add_device
		c) use an mfd_cell struct hard coded in the driver and "enable" only
			the children found in the sub-node list and use mfd_add_devices.

All these methods above have their advantages and disadvantages. But lets 
ignore them for now and ask what's the preferred way to do this?

Another question is how the children will get their platform data. I guess 
they will just walk the device tree of their parent node and search for it, 
but maybe there is a better way?

Sorry for the lengthly posting...

Marc



More information about the devicetree-discuss mailing list