[lm-sensors] [PATCH 2/2] hwmon: (ltc4245) expose all GPIO pins as analog voltages

Ira W. Snyder iws at ovro.caltech.edu
Wed May 26 19:22:44 CEST 2010


On Wed, May 26, 2010 at 06:36:59PM +0200, Jean Delvare wrote:
> Hi Ira,
> 
> On Wed, 26 May 2010 08:42:26 -0700, Ira W. Snyder wrote:
> > On Wed, May 26, 2010 at 01:31:44PM +0200, Jean Delvare wrote:
> > > On Tue, 13 Apr 2010 15:59:29 -0700, Ira W. Snyder wrote:
> > > > +
> > > > +	/* Update saved data */
> > > > +	data->cregs[LTC4245_GPIO] = gpio;
> > > > +	data->last_gpio = gpio_next;
> > > > +}
> > > > +#else
> > > > +static void ltc4245_update_gpios(struct device *dev)
> > > > +{
> > > > +	struct i2c_client *client = to_i2c_client(dev);
> > > > +	struct ltc4245_data *data = i2c_get_clientdata(client);
> > > > +
> > > > +	/* Just copy the data from the the GPIOADC register */
> > > > +	data->gpios[0] = data->vregs[LTC4245_GPIOADC - 0x10];
> > > > +}
> > > > +#endif
> > > 
> > > Not sure why you define this stub function. If you want your patch to
> > > be as little intrusive as possible, you can skip ltc4245_update_gpios
> > > altogether in the general case, and handle in9 as every other voltage
> > > input as the driver was doing before your patch.
> > 
> > I did it so ltc4245_update_gpios() could be called in both cases,
> > without any conditional logic. See the hunk below. I just call
> > ltc4245_update_gpios() without any #ifdef, it "just works" in both
> > cases.
> > 
> > This is the usual thing Linux does with headers. For example, see
> > include/linux/pci.h pci_enable_msix() function. When CONFIG_PCI_MSI=n
> > they stub out the function so it does the right thing: return an error.
> 
> Sorry for not being clear. I wasn't objecting to the stub's existence,
> but to the fact that it was doing something. I expected it to do
> nothing at all, and ltc4245_show_voltage() would be used for in9.
> 

Oh, ok. The ltc4245_show_voltage() function reads the voltage register
values directly from data->vregs[]. When the extra GPIO inputs are
enabled, I have two choices:

1) store them in the new data->gpios[] array
2) store them in data->vregs[]

For #1, ltc4245_show_voltage() doesn't work anymore, since it reads
voltage register values from data->vregs[].

For #2, I would have to re-expand data->vregs[] to include all of the
GPIO inputs, like it was before. Also, I would need to make
ltc4245_get_voltage() handle the -EAGAIN error code.

I think the code is easier to understand if all the GPIOs are treated in
the same way, and not completely special for GPIOADC1 vs GPIOADC[23].
That's why I chose #1.

If I do a hybrid approach (store GPIOADC1 in data->vregs[] and
GPIOADC[23] in data->gpios[]), then I have to make ltc4245_get_voltage()
robust against errors too. Is this what you're suggesting?

> > > > (...)
> > > > +#define LTC4245_GPIO(name, gpio_num) \
> > > > +	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
> > > > +	ltc4245_show_gpio, NULL, gpio_num)
> > > 
> > > You already have an enum value by that name, this is confusing. That's
> > > what you get for prefixing your register names with only LTC4245_
> > > instead of LTC4245_REG_ as most drivers are doing.
> > 
> > The driver works, so I guess the compiler isn't confused. How about I
> > rename the macro? Is there a different name you would suggest?
> 
> I was about to suggest LTC4245_GPIOADC, you that one already exists
> too. LTC4245_VOLTAGE_GPIO maybe?
> 

Seems fine.

> > > > @@ -336,6 +425,10 @@ static struct attribute *ltc4245_attributes[] = {
> > > >  	&sensor_dev_attr_in8_min_alarm.dev_attr.attr,
> > > >  
> > > >  	&sensor_dev_attr_in9_input.dev_attr.attr,
> > > > +#ifdef CONFIG_SENSORS_LTC4245_EXTRA_GPIOS
> > > > +	&sensor_dev_attr_in10_input.dev_attr.attr,
> > > > +	&sensor_dev_attr_in11_input.dev_attr.attr,
> > > > +#endif
> > > >  
> > > >  	&sensor_dev_attr_power1_input.dev_attr.attr,
> > > >  	&sensor_dev_attr_power2_input.dev_attr.attr,
> > > 
> > 
> > One more question: if I use a module parameter or platform data to
> > enable the extra GPIOs, how would I handle this array? I don't see how I
> > can make it work other than generating two different (mostly redundant)
> > arrays and registering a different one for each configuration.
> 
> No, you would move in10 and in11 to a separate array of attributes,
> with a dedicated attribute group. The general code path would register
> ltc4245_group, and your platform specific code path would additionally
> register that other group. See drivers/hwmon/adm1025.c for an example,
> the in4* attributes are in a separate group.
> 

Ok.

Any thoughts about the kernel config option vs. platform data, and how
it relates to the OF bindings?

Ira




More information about the lm-sensors mailing list