Re: [PATCH v5 5/5] iio: humidity: si7020: add No Hold read mode
On 30/11/15 17:33, Wolfram Sang wrote: > On Sat, Oct 31, 2015 at 10:21:56AM +0000, Jonathan Cameron wrote: >> On 29/10/15 11:34, Nicola Corna wrote: >>> The Si7013/20/21 modules support 2 read modes: >>> * Hold mode (blocking), where the device stretches the clock until the end >>> of the measurement >>> * No Hold mode (non-blocking), where the device replies NACK for every I2C >>> call during the measurement >>> Here the No Hold mode is implemented, selectable with the blocking_io >>> variable within si7020_platform_data. The default mode is Hold, unless the >>> adapter does not support clock stretching, in which case the No Hold mode >>> is used. >>> >>> Signed-off-by: Nicola Corna <nic...@corna.info> >> I'm fine with this. The dependency below should I think show up in the >> coming merge window, so this lot might as well go via Wolfram. >> >> Acked-by: Jonathan Cameron <ji...@kernel.org> > > Not sure, will think about it... > Nicola, If Wolfram doesn't pick this up, please ping me after the next merge window. Whilst I'll still have it in my queue, it'll be so long ago by then I'll probably miss it! Jonathan -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 5/5] iio: humidity: si7020: add No Hold read mode
On 29/10/15 11:34, Nicola Corna wrote: > The Si7013/20/21 modules support 2 read modes: > * Hold mode (blocking), where the device stretches the clock until the end > of the measurement > * No Hold mode (non-blocking), where the device replies NACK for every I2C > call during the measurement > Here the No Hold mode is implemented, selectable with the blocking_io > variable within si7020_platform_data. The default mode is Hold, unless the > adapter does not support clock stretching, in which case the No Hold mode > is used. > > Signed-off-by: Nicola Corna <nic...@corna.info> I'm fine with this. The dependency below should I think show up in the coming merge window, so this lot might as well go via Wolfram. Acked-by: Jonathan Cameron <ji...@kernel.org> > --- > This patch depends on patch "[PATCH v4 1/2] iio: humidity: si7020: replaced > bitmask on humidity values with range check" > drivers/iio/humidity/si7020.c| 75 > > include/linux/platform_data/si7020.h | 21 ++ > 2 files changed, 89 insertions(+), 7 deletions(-) > create mode 100644 include/linux/platform_data/si7020.h > > diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c > index 12128d1..674a61a 100644 > --- a/drivers/iio/humidity/si7020.c > +++ b/drivers/iio/humidity/si7020.c > @@ -2,6 +2,7 @@ > * si7020.c - Silicon Labs Si7013/20/21 Relative Humidity and Temp Sensors > * Copyright (c) 2013,2014 Uplogix, Inc. > * David Barksdale <dbarksd...@uplogix.com> > + * Copyright (c) 2015 Nicola Corna <nic...@corna.info> > * > * This program is free software; you can redistribute it and/or modify it > * under the terms and conditions of the GNU General Public License, > @@ -30,33 +31,78 @@ > #include > #include > #include > +#include > > #include > #include > +#include > > /* Measure Relative Humidity, Hold Master Mode */ > #define SI7020CMD_RH_HOLD0xE5 > +/* Measure Relative Humidity, No Hold Master Mode */ > +#define SI7020CMD_RH_NO_HOLD 0xF5 > /* Measure Temperature, Hold Master Mode */ > #define SI7020CMD_TEMP_HOLD 0xE3 > +/* Measure Temperature, No Hold Master Mode */ > +#define SI7020CMD_TEMP_NO_HOLD 0xF3 > /* Software Reset */ > #define SI7020CMD_RESET 0xFE > +/* Relative humidity measurement timeout (us) */ > +#define SI7020_RH_TIMEOUT22800 > +/* Temperature measurement timeout (us) */ > +#define SI7020_TEMP_TIMEOUT 10800 > +/* Minimum delay between retries (No Hold Mode) in us */ > +#define SI7020_NOHOLD_SLEEP_MIN 2000 > +/* Maximum delay between retries (No Hold Mode) in us */ > +#define SI7020_NOHOLD_SLEEP_MAX 6000 > > static int si7020_read_raw(struct iio_dev *indio_dev, > struct iio_chan_spec const *chan, int *val, > int *val2, long mask) > { > struct i2c_client **client = iio_priv(indio_dev); > + struct si7020_platform_data *pdata; > int ret; > + bool holdmode; > + unsigned char buf[2]; > + unsigned long start; > > switch (mask) { > case IIO_CHAN_INFO_RAW: > - ret = i2c_smbus_read_word_data(*client, > -chan->type == IIO_TEMP ? > -SI7020CMD_TEMP_HOLD : > -SI7020CMD_RH_HOLD); > - if (ret < 0) > - return ret; > - *val = ret >> 2; > + pdata = dev_get_platdata(&(*client)->dev); > + if (pdata) > + holdmode = pdata->blocking_io; > + else > + holdmode = !i2c_check_quirks((*client)->adapter, > +I2C_AQ_NO_CLK_STRETCH); > + if (holdmode) { > + ret = i2c_smbus_read_word_data(*client, > +chan->type == IIO_TEMP ? > +SI7020CMD_TEMP_HOLD : > +SI7020CMD_RH_HOLD); > + if (ret < 0) > + return ret; > + *val = ret >> 2; > + } else { > + ret = i2c_smbus_write_byte(*client, > +chan->type == IIO_TEMP ? > +SI7020CMD_TEMP_NO_HOLD : > +SI7020CMD_RH_NO_HOLD); > + if (ret
Re: [PATCH 4/5] i2c: add i2c_check_quirks helper function
On 29/10/15 11:34, Nicola Corna wrote: > This patch adds a i2c_check_quirks helper function to check the quirk flags > of an i2c adapter, in a similar way to i2c_check_functionality. > > Signed-off-by: Nicola CornaI don't know about everyone else, but I'm finding this particular style of email thread very difficult to follow. Perhaps either: * Start a new thread for each new series version. * label the whole series with a rolling version number rather than doing it on a per patch basis. Would just make it easier to keep track when one reads the thread a while after it started! Jonathan > --- > include/linux/i2c.h | 14 ++ > 1 file changed, 14 insertions(+) > > diff --git a/include/linux/i2c.h b/include/linux/i2c.h > index 9697002..51028f3 100644 > --- a/include/linux/i2c.h > +++ b/include/linux/i2c.h > @@ -617,6 +617,20 @@ static inline int i2c_check_functionality(struct > i2c_adapter *adap, u32 func) > return (func & i2c_get_functionality(adap)) == func; > } > > +/** > + * i2c_check_quirks() - Function for checking the quirk flags in an i2c > adapter > + * @adap: i2c adapter > + * @quirks: quirk flags > + * > + * Return: true if the adapter has all the specified quirk flags, false if > not > + */ > +static inline bool i2c_check_quirks(struct i2c_adapter *adap, u64 quirks) > +{ > + if (!adap->quirks) > + return false; > + return (adap->quirks->flags & quirks) == quirks; > +} > + > /* Return the adapter number for a specific adapter */ > static inline int i2c_adapter_id(struct i2c_adapter *adap) > { > -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] iio: humidity: si7020: added No Hold read mode
On 16/09/15 14:35, Nicola Corna wrote: > The Si7013/20/21 modules support 2 read modes: > * Hold mode (blocking), where the device stretches the clock until the end > of the measurement > * No Hold mode (non-blocking), where the device replies NACK for every I2C > call during the measurement > Here the No Hold mode is implemented, selectable with the blocking_io > variable within si7020_platform_data. The default mode is Hold, unless the > adapter does not support clock stretching, in which case the No Hold mode > is used. > > Signed-off-by: Nicola Corna <nic...@corna.info> Acked-by: Jonathan Cameron <ji...@kernel.org> Wolfram, I'm guessing you will pick these up via the i2c tree when he is happy with them. If you want me to take the series through IIO let me know. Thanks, Jonathan > --- > This patch depends on patch "[PATCH v4 1/2] iio: humidity: si7020: replaced > bitmask on humidity values with range check" > drivers/iio/humidity/si7020.c| 76 > > include/linux/platform_data/si7020.h | 21 ++ > 2 files changed, 90 insertions(+), 7 deletions(-) > create mode 100644 include/linux/platform_data/si7020.h > > diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c > index 12128d1..9cf9527 100644 > --- a/drivers/iio/humidity/si7020.c > +++ b/drivers/iio/humidity/si7020.c > @@ -2,6 +2,7 @@ > * si7020.c - Silicon Labs Si7013/20/21 Relative Humidity and Temp Sensors > * Copyright (c) 2013,2014 Uplogix, Inc. > * David Barksdale <dbarksd...@uplogix.com> > + * Copyright (c) 2015 Nicola Corna <nic...@corna.info> > * > * This program is free software; you can redistribute it and/or modify it > * under the terms and conditions of the GNU General Public License, > @@ -30,33 +31,78 @@ > #include > #include > #include > +#include > > #include > #include > +#include > > /* Measure Relative Humidity, Hold Master Mode */ > #define SI7020CMD_RH_HOLD0xE5 > +/* Measure Relative Humidity, No Hold Master Mode */ > +#define SI7020CMD_RH_NO_HOLD 0xF5 > /* Measure Temperature, Hold Master Mode */ > #define SI7020CMD_TEMP_HOLD 0xE3 > +/* Measure Temperature, No Hold Master Mode */ > +#define SI7020CMD_TEMP_NO_HOLD 0xF3 > /* Software Reset */ > #define SI7020CMD_RESET 0xFE > +/* Relative humidity measurement timeout (us) */ > +#define SI7020_RH_TIMEOUT22800 > +/* Temperature measurement timeout (us) */ > +#define SI7020_TEMP_TIMEOUT 10800 > +/* Minimum delay between retries (No Hold Mode) in us */ > +#define SI7020_NOHOLD_SLEEP_MIN 2000 > +/* Maximum delay between retries (No Hold Mode) in us */ > +#define SI7020_NOHOLD_SLEEP_MAX 6000 > > static int si7020_read_raw(struct iio_dev *indio_dev, > struct iio_chan_spec const *chan, int *val, > int *val2, long mask) > { > struct i2c_client **client = iio_priv(indio_dev); > + struct si7020_platform_data *pdata; > int ret; > + bool holdmode; > + unsigned char buf[2]; > + unsigned long start; > > switch (mask) { > case IIO_CHAN_INFO_RAW: > - ret = i2c_smbus_read_word_data(*client, > -chan->type == IIO_TEMP ? > -SI7020CMD_TEMP_HOLD : > -SI7020CMD_RH_HOLD); > - if (ret < 0) > - return ret; > - *val = ret >> 2; > + pdata = dev_get_platdata(&(*client)->dev); > + if (pdata) > + holdmode = pdata->blocking_io; > + else > + holdmode = !i2c_check_functionality((*client)->adapter, > + I2C_FUNC_NO_CLK_STRETCH); > + if (holdmode) { > + ret = i2c_smbus_read_word_data(*client, > +chan->type == IIO_TEMP ? > +SI7020CMD_TEMP_HOLD : > +SI7020CMD_RH_HOLD); > + if (ret < 0) > + return ret; > + *val = ret >> 2; > + } else { > + ret = i2c_smbus_write_byte(*client, > +chan->type == IIO_TEMP ? > +SI7020CMD_TEMP_NO_HOLD : > +SI7020CMD_RH_NO_HOLD); > +
Re: [PATCH v5 6/8] iio: gyro: bmg160: optimize i2c transfers in trigger handler
On 22/08/15 05:02, Wolfram Sang wrote: The series[1] I am working on implements a i2c smbus block data regmap bus driver. Regmap should then automatically do a block read in regmap_bulk_read. Hmm, so doesn't your series make Irina's series obsolete? It addresses the same problem only at a different layer (i2c core vs. regmap), or? It would mean that i2c client drivers which want to support byte, word, or block transfers should be converted to regmap. I assume most of the potential candidates are register based devices anyhow. Then, regmap would be the proper abstraction layer. Have I overlooked something? This is the only driver converted to use regmap, because of SPI mode support. The other drivers will still use Irina's changes. The question is if they should. Or rather be converted to regmap. It is an open question and I am seeking for further input. There are a fairly large number of legacy drivers where this might apply. Do we have any real idea of how many? I'm assuming Irina only made use of it in ones that were of personal interest. A quick grep suggests 10's of drivers use the block call. I'm guessing quite a few would use it if needed for a particular board. Do we want to insist on a much larger change (conversion to regmap) when if this in place, a simple single functional call change will do the job? Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 6/8] iio: gyro: bmg160: optimize i2c transfers in trigger handler
On 12/08/15 15:31, Irina Tirdea wrote: Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the bmg160 driver does one i2c transfer for each axis. This has an impact on the frequency of the gyroscope at high sample rates due to additional delays introduced by the i2c bus at each transfer. Reading all axis values in one i2c transfer reduces the delays introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated that will fallback to reading each axis as a separate word in case i2c block read is not supported. Signed-off-by: Irina Tirdea irina.tir...@intel.com Acked-by: Jonathan Cameron ji...@kernel.org Acked-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com Note, that in the meantime the bmg160 driver just went all regmap on us (as part of adding SPI support - though that step hasn't happened yet). Hence we'll need a means of telling regmap about this possibility. --- drivers/iio/gyro/bmg160.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/iio/gyro/bmg160.c b/drivers/iio/gyro/bmg160.c index b2a6ccb..1ff306d 100644 --- a/drivers/iio/gyro/bmg160.c +++ b/drivers/iio/gyro/bmg160.c @@ -772,6 +772,7 @@ static const struct iio_event_spec bmg160_event = { .sign = 's',\ .realbits = 16, \ .storagebits = 16, \ + .endianness = IIO_LE, \ }, \ .event_spec = bmg160_event,\ .num_event_specs = 1\ @@ -809,19 +810,16 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf-indio_dev; struct bmg160_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; + int ret = 0; mutex_lock(data-mutex); - for (bit = 0; bit AXIS_MAX; bit++) { - ret = i2c_smbus_read_word_data(data-client, -BMG160_AXIS_TO_REG(bit)); - if (ret 0) { - mutex_unlock(data-mutex); - goto err; - } - data-buffer[i++] = ret; - } + ret = i2c_smbus_read_i2c_block_data_or_emulated(data-client, + BMG160_REG_XOUT_L, + AXIS_MAX * 2, + (u8 *)data-buffer); mutex_unlock(data-mutex); + if (ret 0) + goto err; iio_push_to_buffers_with_timestamp(indio_dev, data-buffer, pf-timestamp); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/8] eeprom: at24: use i2c_smbus_read_i2c_block_data_or_emulated
On 14/08/15 19:24, Wolfram Sang wrote: On Wed, Aug 12, 2015 at 05:31:34PM +0300, Irina Tirdea wrote: For i2c busses that support only SMBUS extensions, the eeprom at24 driver reads data from the device using the SMBus block, word or byte read protocols depending on availability. Replace the block read emulation from the driver with the i2c_smbus_read_i2c_block_data_or_emulated call from i2c core. Signed-off-by: Irina Tirdea irina.tir...@intel.com Applied to for-next, thanks! Cool. These will presumably make it in during the coming merge window. I'll pick up the IIO ones next cycle (IIO merge is probably now closed anyway as Linus is talking about merge window opening next week I think). Good work Irina, Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-iio in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/8] i2c: core: Add support for best effort block read emulation
On 04/08/15 15:04, Irina Tirdea wrote: There are devices that need to handle block transactions regardless of the capabilities exported by the adapter. For performance reasons, they need to use i2c read blocks if available, otherwise emulate the block transaction with word or byte transactions. Add support for a helper function that would read a data block using the best transfer available: I2C_FUNC_SMBUS_READ_I2C_BLOCK, I2C_FUNC_SMBUS_READ_WORD_DATA or I2C_FUNC_SMBUS_READ_BYTE_DATA. Signed-off-by: Irina Tirdea irina.tir...@intel.com I like this a lot. Reviewed-by: Jonathan Cameron ji...@kernel.org --- drivers/i2c/i2c-core.c | 65 ++ include/linux/i2c.h| 3 +++ 2 files changed, 68 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index c83e4d1..79ba6a8 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -2942,6 +2942,71 @@ trace: } EXPORT_SYMBOL(i2c_smbus_xfer); +/** + * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @length: Size of data block; SMBus allows at most 32 bytes + * @values: Byte array into which data will be read; big enough to hold + * the data returned by the slave. SMBus allows at most 32 bytes. + * + * This executes the SMBus block read protocol if supported by the adapter. + * If block read is not supported, it emulates it using either word or byte + * read protocols depending on availability. + * + * The addresses of the I2C slave device that are accessed with this function + * must be mapped to a linear region, so that a block read will have the same + * effect as a byte read. Before using this function you must double-check + * if the I2C slave does support exchanging a block transfer with a byte + * transfer. + */ +s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, + u8 command, u8 length, u8 *values) +{ + u8 i; + int status; + + if (length I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; + + if (i2c_check_functionality(client-adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) + return i2c_smbus_read_i2c_block_data(client, command, length, values); + + if (i2c_check_functionality(client-adapter, I2C_FUNC_SMBUS_READ_WORD_DATA | + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + for (i = 0; (i + 2) = length; i += 2) { + status = i2c_smbus_read_word_data(client, command + i); + if (status 0) + return status; + values[i] = status 0xff; + values[i + 1] = status 8; I was about to suggest we knew we were word aligned for both elements and hence could use an endian conversion, but I guess we don't know that as values might not be word aligned. Hence what you have is the best we can do! + } + if (i length) { + status = i2c_smbus_read_byte_data(client, command + i); + if (status 0) + return status; + values[i] = status; + i++; + } + return i; + } + + if (i2c_check_functionality(client-adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + for (i = 0; i length; i++) { + status = i2c_smbus_read_byte_data(client, command + i); + if (status 0) + return status; + values[i] = status; + } + return i; + } + + dev_err(client-adapter-dev, Unsupported transactions\n); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated); + #if IS_ENABLED(CONFIG_I2C_SLAVE) int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) { diff --git a/include/linux/i2c.h b/include/linux/i2c.h index e83a738..faf518d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -121,6 +121,9 @@ extern s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values); +extern s32 +i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, + u8 command, u8 length, u8 *values); #endif /* I2C */ /** -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation
On 10/07/15 18:14, Tirdea, Irina wrote: -Original Message- From: Jonathan Cameron [mailto:ji...@kernel.org] Sent: 05 July, 2015 14:59 To: Tirdea, Irina; Wolfram Sang; linux-...@vger.kernel.org; linux-i2c@vger.kernel.org Cc: linux-ker...@vger.kernel.org; Pandruvada, Srinivas; Peter Meerwald Subject: Re: [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation On 03/07/15 10:33, Irina Tirdea wrote: There are devices that need to handle block transactions regardless of the capabilities exported by the adapter. For performance reasons, they need to use i2c read blocks if available, otherwise emulate the block transaction with word or byte transactions. Add support for a helper function that would read a data block using the best transfer available: I2C_FUNC_SMBUS_READ_I2C_BLOCK, I2C_FUNC_SMBUS_READ_WORD_DATA or I2C_FUNC_SMBUS_READ_BYTE_DATA. Signed-off-by: Irina Tirdea irina.tir...@intel.com Looks good to me - I vaguely wondered if it would make sense to use an endian conversion in the word case, but as we have possible odd numbers of bytes that gets fiddly. Thanks for the review, Jonathan! I wonder what devices do if you do a word read beyond their end address? Perhaps in odd cases we should always fall back to byte reads? In my tests I can read beyond the end address, but I cannot be sure if this is OK for all devices. This was actually a suggestion from Wolfram for v1, but maybe I'm missing something. Wolfram, is it safe to read one byte beyond the end address or should I better use only byte reads for odd lengths? --- drivers/i2c/i2c-core.c | 60 ++ include/linux/i2c.h| 3 +++ 2 files changed, 63 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 96771ea..55a3455 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -2914,6 +2914,66 @@ trace: } EXPORT_SYMBOL(i2c_smbus_xfer); +/** + * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @length: Size of data block; SMBus allows at most 32 bytes + * @values: Byte array into which data will be read; big enough to hold + * the data returned by the slave. SMBus allows at most 32 bytes. + * + * This executes the SMBus block read protocol if supported by the adapter. + * If block read is not supported, it emulates it using either word or byte + * read protocols depending on availability. + * + * Before using this function you must double-check if the I2C slave does + * support exchanging a block transfer with a byte transfer. Add something here about addressing assumptions. You get odd devices which will give bulk reads of addresses not mapped to a nice linear region when you do byte reads. OK, I'll add this to the comment above: The addresses of the I2C slave device that are accessed with this function must be mapped to a linear region, so that a block read will have the same effect as a byte read. Works for me. Thanks, Irina + */ +s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, + u8 command, u8 length, u8 *values) +{ + u8 i; + int status; + + if (length I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; + + if (i2c_check_functionality(client-adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + return i2c_smbus_read_i2c_block_data(client, command, +length, values); + } else if (i2c_check_functionality(client-adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + for (i = 0; i length; i += 2) { + status = i2c_smbus_read_word_data(client, command + i); + if (status 0) + return status; + values[i] = status 0xff; + if ((i + 1) length) + values[i + 1] = status 8; + } + if (i length) + return length; + return i; + } else if (i2c_check_functionality(client-adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + for (i = 0; i length; i++) { + status = i2c_smbus_read_byte_data(client, command + i); + if (status 0) + return status; + values[i] = status; + } + return i; + } + + dev_err(client-adapter-dev, Unsupported transactions: %d,%d,%d\n, + I2C_SMBUS_I2C_BLOCK_DATA, I2C_SMBUS_WORD_DATA, + I2C_SMBUS_BYTE_DATA); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated); + #if IS_ENABLED(CONFIG_I2C_SLAVE) int
Re: [PATCH v3 6/8] iio: gyro: bmg160: optimize i2c transfers in trigger handler
On 03/07/15 10:33, Irina Tirdea wrote: Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the bmg160 driver does one i2c transfer for each axis. This has an impact on the frequency of the gyroscope at high sample rates due to additional delays introduced by the i2c bus at each transfer. Reading all axis values in one i2c transfer reduces the delays introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated that will fallback to reading each axis as a separate word in case i2c block read is not supported. Signed-off-by: Irina Tirdea irina.tir...@intel.com Acked-by: Jonathan Cameron ji...@kernel.org Obviously you'll ideally pick up Ack's from the driver authors /maintainers as well. Jonathan --- drivers/iio/gyro/bmg160.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/iio/gyro/bmg160.c b/drivers/iio/gyro/bmg160.c index 4b423f2..04e15e9 100644 --- a/drivers/iio/gyro/bmg160.c +++ b/drivers/iio/gyro/bmg160.c @@ -784,6 +784,7 @@ static const struct iio_event_spec bmg160_event = { .sign = 's',\ .realbits = 16, \ .storagebits = 16, \ + .endianness = IIO_LE, \ }, \ .event_spec = bmg160_event,\ .num_event_specs = 1\ @@ -822,19 +823,16 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf-indio_dev; struct bmg160_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; + int ret = 0; mutex_lock(data-mutex); - for (bit = 0; bit AXIS_MAX; bit++) { - ret = i2c_smbus_read_word_data(data-client, -BMG160_AXIS_TO_REG(bit)); - if (ret 0) { - mutex_unlock(data-mutex); - goto err; - } - data-buffer[i++] = ret; - } + ret = i2c_smbus_read_i2c_block_data_or_emulated(data-client, + BMG160_REG_XOUT_L, + AXIS_MAX * 2, + (u8 *)data-buffer); mutex_unlock(data-mutex); + if (ret 0) + goto err; iio_push_to_buffers_with_timestamp(indio_dev, data-buffer, data-timestamp); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 3/8] iio: accel: bmc150: use available_scan_masks
On 03/07/15 10:33, Irina Tirdea wrote: Use available_scan_masks to allow the iio core to select the data to send to userspace depending on which axes are enabled, instead of doing this in the driver's interrupt handler. Signed-off-by: Irina Tirdea irina.tir...@intel.com I guess people almost always want all 3 axes of an accelerometer so a burst read like this probably makes sense for the majority. Acked-by: Jonathan Cameron ji...@kernel.org --- drivers/iio/accel/bmc150-accel.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 73e8773..c6c8416 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c @@ -136,6 +136,7 @@ enum bmc150_accel_axis { AXIS_X, AXIS_Y, AXIS_Z, + AXIS_MAX, }; enum bmc150_power_modes { @@ -1201,6 +1202,8 @@ static const struct iio_info bmc150_accel_info_fifo = { .driver_module = THIS_MODULE, }; +static const unsigned long bmc150_accel_scan_masks[] = {0x7, 0}; + static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -1209,8 +1212,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) int bit, ret, i = 0; mutex_lock(data-mutex); - for_each_set_bit(bit, indio_dev-active_scan_mask, - indio_dev-masklength) { + for (bit = 0; bit AXIS_MAX; bit++) { ret = i2c_smbus_read_word_data(data-client, BMC150_ACCEL_AXIS_TO_REG(bit)); if (ret 0) { @@ -1632,6 +1634,7 @@ static int bmc150_accel_probe(struct i2c_client *client, indio_dev-dev.parent = client-dev; indio_dev-channels = data-chip_info-channels; indio_dev-num_channels = data-chip_info-num_channels; + indio_dev-available_scan_masks = bmc150_accel_scan_masks; indio_dev-name = name; indio_dev-modes = INDIO_DIRECT_MODE; indio_dev-info = bmc150_accel_info; -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation
On 03/07/15 10:33, Irina Tirdea wrote: There are devices that need to handle block transactions regardless of the capabilities exported by the adapter. For performance reasons, they need to use i2c read blocks if available, otherwise emulate the block transaction with word or byte transactions. Add support for a helper function that would read a data block using the best transfer available: I2C_FUNC_SMBUS_READ_I2C_BLOCK, I2C_FUNC_SMBUS_READ_WORD_DATA or I2C_FUNC_SMBUS_READ_BYTE_DATA. Signed-off-by: Irina Tirdea irina.tir...@intel.com Looks good to me - I vaguely wondered if it would make sense to use an endian conversion in the word case, but as we have possible odd numbers of bytes that gets fiddly. I wonder what devices do if you do a word read beyond their end address? Perhaps in odd cases we should always fall back to byte reads? --- drivers/i2c/i2c-core.c | 60 ++ include/linux/i2c.h| 3 +++ 2 files changed, 63 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 96771ea..55a3455 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -2914,6 +2914,66 @@ trace: } EXPORT_SYMBOL(i2c_smbus_xfer); +/** + * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @length: Size of data block; SMBus allows at most 32 bytes + * @values: Byte array into which data will be read; big enough to hold + * the data returned by the slave. SMBus allows at most 32 bytes. + * + * This executes the SMBus block read protocol if supported by the adapter. + * If block read is not supported, it emulates it using either word or byte + * read protocols depending on availability. + * + * Before using this function you must double-check if the I2C slave does + * support exchanging a block transfer with a byte transfer. Add something here about addressing assumptions. You get odd devices which will give bulk reads of addresses not mapped to a nice linear region when you do byte reads. + */ +s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, + u8 command, u8 length, u8 *values) +{ + u8 i; + int status; + + if (length I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; + + if (i2c_check_functionality(client-adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + return i2c_smbus_read_i2c_block_data(client, command, + length, values); + } else if (i2c_check_functionality(client-adapter, +I2C_FUNC_SMBUS_READ_WORD_DATA)) { + for (i = 0; i length; i += 2) { + status = i2c_smbus_read_word_data(client, command + i); + if (status 0) + return status; + values[i] = status 0xff; + if ((i + 1) length) + values[i + 1] = status 8; + } + if (i length) + return length; + return i; + } else if (i2c_check_functionality(client-adapter, +I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + for (i = 0; i length; i++) { + status = i2c_smbus_read_byte_data(client, command + i); + if (status 0) + return status; + values[i] = status; + } + return i; + } + + dev_err(client-adapter-dev, Unsupported transactions: %d,%d,%d\n, + I2C_SMBUS_I2C_BLOCK_DATA, I2C_SMBUS_WORD_DATA, + I2C_SMBUS_BYTE_DATA); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated); + #if IS_ENABLED(CONFIG_I2C_SLAVE) int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) { diff --git a/include/linux/i2c.h b/include/linux/i2c.h index e83a738..faf518d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -121,6 +121,9 @@ extern s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values); +extern s32 +i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, + u8 command, u8 length, u8 *values); #endif /* I2C */ /** -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/8] iio: accel: bmc150: optimize i2c transfers in trigger handler
On 03/07/15 10:33, Irina Tirdea wrote: Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the bmc150 accel driver does one i2c transfer for each axis. This has an impact on the frequency of the accelerometer at high sample rates due to additional delays introduced by the i2c bus at each transfer. Reading all axis values in one i2c transfer reduces the delays introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated that will fallback to reading each axis as a separate word in case i2c block read is not supported. Signed-off-by: Irina Tirdea irina.tir...@intel.com Very nice. There is an effective userspace ABI change, but if people are using the ABI wrong, then it's kind of their own fault! I'll assume Wolfram will pick these up if / when he is happy with the new function. Acked-by: Jonathan Cameron ji...@kernel.org --- drivers/iio/accel/bmc150-accel.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index c6c8416..e686add 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c @@ -1082,6 +1082,7 @@ static const struct iio_event_spec bmc150_accel_event = { .realbits = (bits), \ .storagebits = 16, \ .shift = 16 - (bits), \ + .endianness = IIO_LE, \ Hmm. ABI change of a sort. Should be fine if userspace is doing things right, but never a whole lot of certainty about that. Lets see if anyone screams... }, \ .event_spec = bmc150_accel_event, \ .num_event_specs = 1\ @@ -1209,19 +1210,16 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf-indio_dev; struct bmc150_accel_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; + int ret; mutex_lock(data-mutex); - for (bit = 0; bit AXIS_MAX; bit++) { - ret = i2c_smbus_read_word_data(data-client, -BMC150_ACCEL_AXIS_TO_REG(bit)); - if (ret 0) { - mutex_unlock(data-mutex); - goto err_read; - } - data-buffer[i++] = ret; - } + ret = i2c_smbus_read_i2c_block_data_or_emulated(data-client, + BMC150_ACCEL_REG_XOUT_L, + AXIS_MAX * 2, + (u8 *)data-buffer); mutex_unlock(data-mutex); + if (ret 0) + goto err_read; iio_push_to_buffers_with_timestamp(indio_dev, data-buffer, data-timestamp); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 8/8] iio: accel: kxcjk-1013: optimize i2c transfers in trigger handler
On 03/07/15 10:33, Irina Tirdea wrote: From: Adriana Reus adriana.r...@intel.com Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to enable/disable the bus at each i2c transfer and must wait for the enable/disable to happen before sending the data. When reading data in the trigger handler, the kxcjk-1013 accel driver does one i2c transfer for each axis. This has an impact on the frequency of the accelerometer at high sample rates due to additional delays introduced by the i2c bus at each transfer. Reading all axis values in one i2c transfer reduces the delays introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated that will fallback to reading each axis as a separate word in case i2c block read is not supported. Signed-off-by: Adriana Reus adriana.r...@intel.com Signed-off-by: Irina Tirdea irina.tir...@intel.com Same comments as previously. Acked-by: Jonathan Cameron ji...@kernel.org --- drivers/iio/accel/kxcjk-1013.c | 19 --- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 4960397..8f401c2 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -923,7 +923,7 @@ static const struct iio_event_spec kxcjk1013_event = { .realbits = 12, \ .storagebits = 16, \ .shift = 4, \ - .endianness = IIO_CPU, \ + .endianness = IIO_LE, \ }, \ .event_spec = kxcjk1013_event, \ .num_event_specs = 1\ @@ -955,19 +955,16 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf-indio_dev; struct kxcjk1013_data *data = iio_priv(indio_dev); - int bit, ret, i = 0; + int ret; mutex_lock(data-mutex); - - for (bit = 0; bit AXIS_MAX; bit++) { - ret = kxcjk1013_get_acc_reg(data, bit); - if (ret 0) { - mutex_unlock(data-mutex); - goto err; - } - data-buffer[i++] = ret; - } + ret = i2c_smbus_read_i2c_block_data_or_emulated(data-client, + KXCJK1013_REG_XOUT_L, + AXIS_MAX * 2, + (u8 *)data-buffer); mutex_unlock(data-mutex); + if (ret 0) + goto err; iio_push_to_buffers_with_timestamp(indio_dev, data-buffer, data-timestamp); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/7] iio: mlx90614: Add power management
On 09/03/15 16:43, Wolfram Sang wrote: On Mon, Mar 09, 2015 at 03:39:35PM +, Jonathan Cameron wrote: On 25/02/15 15:55, Vianney le Clément de Saint-Marcq wrote: Add support for system sleep and runtime power management. To wake up the device, the SDA line should be held low for at least 33ms while SCL is high. As this is not possible using the i2c API (and not supported by all i2c adapters), a GPIO connected to the SDA line is needed. The GPIO is named wakeup and can be specified in a device tree with the wakeup-gpios binding. Needs some i2c specialist input on this! As you mentioned it is liable to be controversial. Wolfram, is this a one off special or do any other devices do this sort of magic? s/magic/insanity/ :) I have never heard of something like this. Unsuprisingly, I can not recommend doing it this way. But we all know hardware... And while we could think about reusing the bus_recovery_infrastructure, I don't think it is worth the hazzle. So, doing this GPIO fallback may well be the best we can do now. Fair enough. Lets go with this approach then and hope this is the only bit of hardware ever to do this (yeah right ;) -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/7] iio: mlx90614: Add power management
On 09/03/15 15:39, Jonathan Cameron wrote: On 25/02/15 15:55, Vianney le Clément de Saint-Marcq wrote: Add support for system sleep and runtime power management. To wake up the device, the SDA line should be held low for at least 33ms while SCL is high. As this is not possible using the i2c API (and not supported by all i2c adapters), a GPIO connected to the SDA line is needed. The GPIO is named wakeup and can be specified in a device tree with the wakeup-gpios binding. Needs some i2c specialist input on this! As you mentioned it is liable to be controversial. Wolfram, is this a one off special or do any other devices do this sort of magic? If the wake-up GPIO is not given, disable power management for the device. Entering sleep requires an SMBus byte access, hence power management is also disabled if byte access is not supported by the adapter. Signed-off-by: Vianney le Clément de Saint-Marcq vianney.leclem...@essensium.com Cc: Arnout Vandecappelle (Essensium/Mind) arn...@mind.be Again, with a current address for Wolfram. --- The default autosleep delay (5s) is chosen arbitrarily, trying to take into account the long startup time (250ms). Feel free to change it to another value if you think it is saner. --- .../bindings/iio/temperature/mlx90614.txt | 24 ++ .../devicetree/bindings/vendor-prefixes.txt| 1 + drivers/iio/temperature/mlx90614.c | 244 - 3 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/temperature/mlx90614.txt diff --git a/Documentation/devicetree/bindings/iio/temperature/mlx90614.txt b/Documentation/devicetree/bindings/iio/temperature/mlx90614.txt new file mode 100644 index 000..9be57b0 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/temperature/mlx90614.txt @@ -0,0 +1,24 @@ +* Melexis MLX90614 contactless IR temperature sensor + +http://melexis.com/Infrared-Thermometer-Sensors/Infrared-Thermometer-Sensors/MLX90614-615.aspx + +Required properties: + + - compatible: should be melexis,mlx90614 + - reg: the I2C address of the sensor + +Optional properties: + + - wakeup-gpios: device tree identifier of the GPIO connected to the SDA line + to hold low in order to wake up the device. In normal operation, the + GPIO is set as input and will not interfere in I2C communication. There + is no need for a GPIO driving the SCL line. If no GPIO is given, power + management is disabled. + +Example: + +mlx90614@5a { +compatible = melexis,mlx90614; +reg = 0x5a; +wakeup-gpios = gpio0 2 GPIO_ACTIVE_HIGH; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 389ca13..ceacc40 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -108,6 +108,7 @@ lltc Linear Technology Corporation marvell Marvell Technology Group Ltd. maxim Maxim Integrated Products mediatekMediaTek Inc. +melexis Melexis N.V. merrii Merrii Technology Co., Ltd. micrel Micrel Inc. microchip Microchip Technology Inc. diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index ab98fb6..49c517a 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -12,13 +12,22 @@ * * (7-bit I2C slave address 0x5a, 100KHz bus speed only!) * - * TODO: sleep mode + * To wake up from sleep mode, the SDA line must be held low while SCL is high + * for at least 33ms. This is achieved with an extra GPIO that can be connected + * directly to the SDA line. In normal operation, the GPIO is set as input and + * will not interfere in I2C communication. While the GPIO is driven low, the + * i2c adapter is locked since it cannot be used by other clients. The SCL line + * always has a pull-up so we do not need an extra GPIO to drive it high. If + * the wakeup GPIO is not given, power management will be disabled. */ #include linux/err.h #include linux/i2c.h #include linux/module.h #include linux/delay.h +#include linux/jiffies.h +#include linux/gpio/consumer.h +#include linux/pm_runtime.h #include linux/iio/iio.h #include linux/iio/sysfs.h @@ -53,9 +62,13 @@ #define MLX90614_TIMING_WAKEUP 34 /* time to hold SDA low for wake-up */ #define MLX90614_TIMING_STARTUP 250 /* time before first data after wake-up */ +#define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */ + struct mlx90614_data { struct i2c_client *client; struct mutex lock; /* for EEPROM access only */ +struct gpio_desc *wakeup_gpio; /* NULL to disable sleep/wake-up */ +unsigned long ready_timestamp; /* in jiffies */ }; /* @@ -96,6 +109,52 @@ static s32 mlx90614_write_word(const struct
Re: [PATCH 6/7] iio: mlx90614: Add power management
On 25/02/15 15:55, Vianney le Clément de Saint-Marcq wrote: Add support for system sleep and runtime power management. To wake up the device, the SDA line should be held low for at least 33ms while SCL is high. As this is not possible using the i2c API (and not supported by all i2c adapters), a GPIO connected to the SDA line is needed. The GPIO is named wakeup and can be specified in a device tree with the wakeup-gpios binding. Needs some i2c specialist input on this! As you mentioned it is liable to be controversial. Wolfram, is this a one off special or do any other devices do this sort of magic? If the wake-up GPIO is not given, disable power management for the device. Entering sleep requires an SMBus byte access, hence power management is also disabled if byte access is not supported by the adapter. Signed-off-by: Vianney le Clément de Saint-Marcq vianney.leclem...@essensium.com Cc: Arnout Vandecappelle (Essensium/Mind) arn...@mind.be --- The default autosleep delay (5s) is chosen arbitrarily, trying to take into account the long startup time (250ms). Feel free to change it to another value if you think it is saner. --- .../bindings/iio/temperature/mlx90614.txt | 24 ++ .../devicetree/bindings/vendor-prefixes.txt| 1 + drivers/iio/temperature/mlx90614.c | 244 - 3 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/temperature/mlx90614.txt diff --git a/Documentation/devicetree/bindings/iio/temperature/mlx90614.txt b/Documentation/devicetree/bindings/iio/temperature/mlx90614.txt new file mode 100644 index 000..9be57b0 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/temperature/mlx90614.txt @@ -0,0 +1,24 @@ +* Melexis MLX90614 contactless IR temperature sensor + +http://melexis.com/Infrared-Thermometer-Sensors/Infrared-Thermometer-Sensors/MLX90614-615.aspx + +Required properties: + + - compatible: should be melexis,mlx90614 + - reg: the I2C address of the sensor + +Optional properties: + + - wakeup-gpios: device tree identifier of the GPIO connected to the SDA line + to hold low in order to wake up the device. In normal operation, the + GPIO is set as input and will not interfere in I2C communication. There + is no need for a GPIO driving the SCL line. If no GPIO is given, power + management is disabled. + +Example: + +mlx90614@5a { + compatible = melexis,mlx90614; + reg = 0x5a; + wakeup-gpios = gpio0 2 GPIO_ACTIVE_HIGH; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 389ca13..ceacc40 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -108,6 +108,7 @@ lltc Linear Technology Corporation marvell Marvell Technology Group Ltd. maximMaxim Integrated Products mediatek MediaTek Inc. +melexis Melexis N.V. merrii Merrii Technology Co., Ltd. micrel Micrel Inc. microchipMicrochip Technology Inc. diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index ab98fb6..49c517a 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -12,13 +12,22 @@ * * (7-bit I2C slave address 0x5a, 100KHz bus speed only!) * - * TODO: sleep mode + * To wake up from sleep mode, the SDA line must be held low while SCL is high + * for at least 33ms. This is achieved with an extra GPIO that can be connected + * directly to the SDA line. In normal operation, the GPIO is set as input and + * will not interfere in I2C communication. While the GPIO is driven low, the + * i2c adapter is locked since it cannot be used by other clients. The SCL line + * always has a pull-up so we do not need an extra GPIO to drive it high. If + * the wakeup GPIO is not given, power management will be disabled. */ #include linux/err.h #include linux/i2c.h #include linux/module.h #include linux/delay.h +#include linux/jiffies.h +#include linux/gpio/consumer.h +#include linux/pm_runtime.h #include linux/iio/iio.h #include linux/iio/sysfs.h @@ -53,9 +62,13 @@ #define MLX90614_TIMING_WAKEUP 34 /* time to hold SDA low for wake-up */ #define MLX90614_TIMING_STARTUP 250 /* time before first data after wake-up */ +#define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */ + struct mlx90614_data { struct i2c_client *client; struct mutex lock; /* for EEPROM access only */ + struct gpio_desc *wakeup_gpio; /* NULL to disable sleep/wake-up */ + unsigned long ready_timestamp; /* in jiffies */ }; /* @@ -96,6 +109,52 @@ static s32 mlx90614_write_word(const struct i2c_client *client, u8 command, return ret; } +#ifdef
Re: [PATCH v2] iio: imu: inv_mpu6050: Create mux clients for ACPI
On 22/01/15 22:31, Srinivas Pandruvada wrote: This is a follow up patches after adding i2c mux adapter for bypass mode. Potentially many different types of sensor can be attached to INVMPU6XXX device, which can be connected to main cpu i2c bus in bypass mode. Why do we need this? The system ACPI table entry will consist of only one device for INV6XXX, assuming that this driver will handle all connected sensors. That is not true for the Linux driver. There are bunch of IIO drivers for each sensors, hence we created a mux on this device. So to load these additional drivers, we need to create i2c devices for them in this driver using this mux adapter. There are multiple options: 1. Use the auto detect feature, this needs a new i2c class for the adapter as the existing HWMON class is not acceptable. Also the autodetect has overhead of executing detect method for each matching class of adapters. This is a simple implementation. This option was previously submitted with not a happy feedback. 2. Option is use ACPI magic and parse the configuration data. What we need to create a i2c device at a minimum is address and a name. Address can be obtained for secondary device in more or less in a standard way from using _CRS element. But there is no name. To get name we need to process proprietary vendor data. Not having name is not fun, as you have to create device using the device name of INVN6, respecting driver duplicate name space restriction. Also each client driver needs to have this name in the id table. Since multiple driver can be loaded, the driver should be able to detect its presence and gracefully exit for the other client driver to take it over. So we use two step process: - Use DMI to id platform and parse propritery data. This is not uncommon for many x86 platform specific driver. We will get both name and address. The change created necessary infrastructure to add more properitery vendor data parsing. - If DMI match fails, then create device on INV6XXX-client (we can't create with same name as INV6XXX as it will cause duplicate name and driver model will reject.) With this each client sensor driver which needs to get attached via INV6, need this name in the id table and detect the physical presence of sensor in probe and exit if not found. Signed-off-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com This all looks fine to me, though ideally I'd like some input from others, more familiar with the dmi stuff etc and from Wolfram / others wrt to the approach. Jonathan --- drivers/iio/imu/inv_mpu6050/Makefile | 2 +- drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 196 + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 11 ++ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 3 + 4 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile index 3a677c7..f566f6a 100644 --- a/drivers/iio/imu/inv_mpu6050/Makefile +++ b/drivers/iio/imu/inv_mpu6050/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o -inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o +inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o inv_mpu_acpi.o diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c new file mode 100644 index 000..2d98c1a --- /dev/null +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c @@ -0,0 +1,196 @@ +/* + * inv_mpu_acpi: ACPI processing for creating client devices + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include linux/kernel.h +#include linux/i2c.h +#include linux/dmi.h +#include linux/acpi.h +#include inv_mpu_iio.h + +enum inv_mpu_product_name { + INV_MPU_NOT_MATCHED, + INV_MPU_ASUS_T100TA, +}; + +static enum inv_mpu_product_name matched_product_name; + +static int __init asus_t100_matched(const struct dmi_system_id *d) +{ + matched_product_name = INV_MPU_ASUS_T100TA; + + return 0; +} + +static const struct dmi_system_id inv_mpu_dev_list[] = { + { + .callback = asus_t100_matched, + .ident = Asus Transformer Book T100, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, ASUSTeK COMPUTER INC), + DMI_MATCH(DMI_PRODUCT_NAME, T100TA), +
Re: [PATCH V3 1/1] iio: Added Capella cm3232 ambient light sensor driver.
On 16/01/15 01:41, Kevin Tsai wrote: CM3232 is an advanced ambient light sensor with I2C protocol interface. The I2C slave address is internally hardwired as 0x10 (7-bit). Writing to configure register is byte mode, but reading ALS register requests to use word mode for 16-bit resolution. Signed-off-by: Kevin Tsai kt...@capellamicro.com Couple of little bits inline that I've cleared up in applying the patch... (utterly trivial so lets not waste any time!) I'ts been here a while since Daniel suggested he'd like to see comments from Peter and Hartmut. I'm going to take the view that it looks fine to me, and those guys are either happy, or too busy to look! Anyhow, Applied with small changes as outlined below to the togreg branch of iio.git Initially pushed out as testing for the autobuilders to play. Thanks, Jonathan --- v3: Added hw_id to als_info structure. Removed unused include files. Modified cm3232_write_als_it() to handle register update fail. Thanks comments from Daniel Baluta. v2: Removed unused CM3232_CMD_ALS_HS. Modified cm3232_als_info structure. Removed id field. Modified cm3232_chip structure. Merged CM3232_als_it_bits and CM3232_als_it_values to cm3232_it_scale. Removed mutex lock. Renamed als_raw to regs_als. Moved it to cm3232_chip structure. Modified cm3232_read_als_it() and cm3232_write_als_it() to support val2. Thanks comments from Jeremiah Mahler, Peter Meerwald, Daniel Baluta, and Joe Perches. v1: Added cm3232.c to support Capella Microsystems CM3232 Ambient Light Sensor. .../devicetree/bindings/i2c/trivial-devices.txt| 1 + MAINTAINERS| 6 + drivers/iio/light/Kconfig | 11 + drivers/iio/light/Makefile | 1 + drivers/iio/light/cm3232.c | 409 + 5 files changed, 428 insertions(+) create mode 100644 drivers/iio/light/cm3232.c diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 9f4e382..572a7c4 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -34,6 +34,7 @@ atmel,24c512i2c serial eeprom (24cxx) atmel,24c1024i2c serial eeprom (24cxx) atmel,at97sc3204ti2c trusted platform module (TPM) capella,cm32181 CM32181: Ambient Light Sensor +capella,cm3232 CM3232: Ambient Light Sensor catalyst,24c32 i2c serial eeprom cirrus,cs42l51 Cirrus Logic CS42L51 audio codec dallas,ds130764 x 8, Serial, I2C Real-Time Clock diff --git a/MAINTAINERS b/MAINTAINERS index ddb9ac8..06a613a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2378,6 +2378,12 @@ F: security/capability.c F: security/commoncap.c F: kernel/capability.c +CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER +M: Kevin Tsai kt...@capellamicro.com +S: Maintained +F: drivers/iio/light/cm* +F: Documentation/devicetree/bindings/i2c/trivial-devices.txt + CC2520 IEEE-802.15.4 RADIO DRIVER M: Varka Bhadram varkabhad...@gmail.com L: linux-w...@vger.kernel.org diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 5bea821..cd5028e 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -48,6 +48,17 @@ config CM32181 To compile this driver as a module, choose M here: the module will be called cm32181. +config CM3232 + depends on I2C + tristate CM3232 ambient light sensor + help + Say Y here if you use cm3232. + This option enables ambient light sensor using + Capella Microsystems cm3232 device driver. + + To compile this driver as a module, choose M here: + the module will be called cm3232. + config CM36651 depends on I2C tristate CM36651 driver diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 47877a3..f2c8d55 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_ADJD_S311) += adjd_s311.o obj-$(CONFIG_AL3320A)+= al3320a.o obj-$(CONFIG_APDS9300) += apds9300.o obj-$(CONFIG_CM32181)+= cm32181.o +obj-$(CONFIG_CM3232) += cm3232.o obj-$(CONFIG_CM36651)+= cm36651.o obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c new file mode 100644 index 000..8573f98 --- /dev/null +++ b/drivers/iio/light/cm3232.c @@ -0,0 +1,409 @@ +/* + * CM3232 Ambient Light Sensor + * + * Copyright (C) 2014-2015 Capella Microsystems Inc. + * Author: Kevin Tsai kt...@capellamicro.com + * + * This program is free software; you can redistribute it
Re: [PATCH V1 1/1] iio: Added Capella cm3232 ambient light sensor driver.
On 05/01/15 17:56, Joe Perches wrote: On Mon, 2015-01-05 at 19:50 +0200, Daniel Baluta wrote: On Mon, Jan 5, 2015 at 6:42 PM, Joe Perches j...@perches.com wrote: On Mon, 2015-01-05 at 16:20 +0200, Daniel Baluta wrote: On Mon, Jan 5, 2015 at 3:09 PM, Joe Perches j...@perches.com wrote: On Mon, 2015-01-05 at 12:51 +0200, Daniel Baluta wrote: On Thu, Jan 1, 2015 at 2:10 AM, Kevin Tsai kt...@capellamicro.com wrote: CM3232 is an advanced ambient light sensor with I2C protocol interface. The I2C slave address is internally hardwired as 0x10 (7-bit). Writing to configure register is byte mode, but reading ALS register requests to use word mode for 16-bit resolution. [] You could directly return i2c_smbus_write_byte_data(..). Sometimes it's better to return a specific value for the error instead of depending on correctness of all the indirect functions in the call chain. In this case, all the smbus_xfer functions must return 0 on success. Do they? Yes. http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L2845 This doesn't show that adapter-algo-smbus_xfer() returns 0, you have to look at the code for that indirectly called function. I based my answer on the comment at the top of the function: 2845 * This executes an SMBus protocol operation, and returns a negative 2846 * errno code else zero on success. Sure, but comments and code often differ and the implementation of any of those smbus_xfer functions could return a positive value like the byte value or the number of bytes written instead of 0. For correctness, you'd have to inspect them all. If some new future smbus_xfer function was written incorrectly, the return value from this function could now be positive. That would however, clearly be a bug and likely to cause all sorts of issues elsewhere given the documentation requires that it does return 0 on success and people will have been relying on it. Jonathan cheers, Joe -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] iio: ak8975: Added autodetect feature for ACPI
On 18/12/14 18:00, Srinivas Pandruvada wrote: On Thu, 2014-12-18 at 18:54 +0100, Lars-Peter Clausen wrote: On 12/18/2014 06:30 PM, Srinivas Pandruvada wrote: On Thu, 2014-12-18 at 18:05 +0100, Lars-Peter Clausen wrote: On 12/18/2014 05:52 PM, Srinivas Pandruvada wrote: On Thu, 2014-12-18 at 17:28 +0100, Lars-Peter Clausen wrote: Added I2C to Cc. On 12/15/2014 10:19 PM, Srinivas Pandruvada wrote: Using i2c auto detect feature and auto device creation feature, enumerate ak8975 device, by checking their presence. This is needed because when this device sits behind an i2c mux, there is no way to define i2c mux in ACPI. This will enable ak8975 on windows based tablets/laptops running Linux when connected via a mux. Since DT model already can define an i2c mux and devices connected to it, this feature is only enabled for ACPI. This is quite a bit of a hack. Why? Auto detect is standard feature of i2c devices. This is using standard auto detect feature provided by the framework. Auto detect is ugly, slow and unreliable, it's kind of like the last straw if nothing else works. That is true here. You can't enumerate this device by ACPI. As discussed before we created i2c mux in inv6050 so that we can use AK8975 in bypass mode. I added some API to create i2c device on this mux, which Wolfram didn't like. He wanted to enumerate using existing mechanisms. If there is only a single ACPI ID that says this is a INV6050 with a AK8975 attached then the way to handle this is to have a driver that binds to that id and creates both devices. Which address you will create device also adapter here is i2c mux created by inv6050? You don't know i2c address of AK8975. To know AK8975 i2c address, even ugly hack to parse propriety vendor ACPI data, which will change between to manufacturer. This is odd enough, that I'd like a wider range of views on it. Wolfram - was this the approach you had in mind? - Lars -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] iio: imu: inv_mpu6050: Add i2c mux for by pass
On 05/12/14 22:52, Srinivas Pandruvada wrote: This chip allows some limited number of sensors connected to it as slaves, which can be directly accessed by register interface of this driver.But the current upstream driver doesn't support such mode. To attach such slaves to main processor i2c bus, chip has to be set up in bypass mode. This change adds i2c mux, which will enable/disable this mode for transaction to/from such slave devices. This was discussed for a while in mailing list, this was the outcome: Reference: http://www.spinics.net/lists/linux-iio/msg12126.html http://comments.gmane.org/gmane.linux.kernel.iio/11470 Signed-off-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com Reviewed-by: Wolfram Sang w...@the-dreams.de Applied to the togreg branch of IIO.git Thanks, --- drivers/iio/imu/inv_mpu6050/Kconfig| 1 + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 115 +++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 6 ++ 3 files changed, 116 insertions(+), 6 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig index 2d0608b..48fbc0b 100644 --- a/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/drivers/iio/imu/inv_mpu6050/Kconfig @@ -7,6 +7,7 @@ config INV_MPU6050_IIO depends on I2C SYSFS select IIO_BUFFER select IIO_TRIGGERED_BUFFER + select I2C_MUX help This driver supports the Invensense MPU6050 devices. This driver can also support MPU6500 in MPU6050 compatibility mode diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index b75519d..6d2c115 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -23,6 +23,7 @@ #include linux/kfifo.h #include linux/spinlock.h #include linux/iio/iio.h +#include linux/i2c-mux.h #include inv_mpu_iio.h /* @@ -52,6 +53,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .int_enable = INV_MPU6050_REG_INT_ENABLE, .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, + .int_pin_cfg= INV_MPU6050_REG_INT_PIN_CFG, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -77,6 +79,83 @@ int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d) return i2c_smbus_write_i2c_block_data(st-client, reg, 1, d); } +/* + * The i2c read/write needs to happen in unlocked mode. As the parent + * adapter is common. If we use locked versions, it will fail as + * the mux adapter will lock the parent i2c adapter, while calling + * select/deselect functions. + */ +static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st, + u8 reg, u8 d) +{ + int ret; + u8 buf[2]; + struct i2c_msg msg[1] = { + { + .addr = st-client-addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = reg; + buf[1] = d; + ret = __i2c_transfer(st-client-adapter, msg, 1); + if (ret != 1) + return ret; + + return 0; +} + +static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv, + u32 chan_id) +{ + struct iio_dev *indio_dev = mux_priv; + struct inv_mpu6050_state *st = iio_priv(indio_dev); + int ret = 0; + + /* Use the same mutex which was used everywhere to protect power-op */ + mutex_lock(indio_dev-mlock); + if (!st-powerup_count) { + ret = inv_mpu6050_write_reg_unlocked(st, st-reg-pwr_mgmt_1, + 0); + if (ret) + goto write_error; + + msleep(INV_MPU6050_REG_UP_TIME); + } + if (!ret) { + st-powerup_count++; + ret = inv_mpu6050_write_reg_unlocked(st, st-reg-int_pin_cfg, + st-client-irq | + INV_MPU6050_BIT_BYPASS_EN); + } +write_error: + mutex_unlock(indio_dev-mlock); + + return ret; +} + +static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, +void *mux_priv, u32 chan_id) +{ + struct iio_dev *indio_dev = mux_priv; + struct inv_mpu6050_state *st = iio_priv(indio_dev); + + mutex_lock(indio_dev-mlock); + /* It doesn't really mattter, if any of the calls fails */ + inv_mpu6050_write_reg_unlocked(st, st-reg-int_pin_cfg, +st-client-irq); + st-powerup_count--; + if (!st-powerup_count) + inv_mpu6050_write_reg_unlocked(st, st-reg-pwr_mgmt_1, +
Re: [PATCH v1 1/2] iio: imu: inv_mpu6050: Add i2c mux for by pass
On 18/11/14 17:53, Srinivas Pandruvada wrote: This chip has a mode in which this chipset can be i2c master. But the current upstream driver doesn't support such mode as there is some limited support of clients, which can be connected. To attach such clients to main i2c bus chip has to be set up in bypass mode. Creates an i2c mux, which will enable/disable this mode. This was discussed for a while in mailing list, this was the decision. This change also provides an API, which allows clients to be created for this mux adapter. Signed-off-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com Still wants to go to Wolfram and linux-i2c, given we are adding an i2c mux deep in an IIO driver. Whilst Wolfram was happy (iirc) with the approach he might want to take a look at the implementation (and I'd rather have his ack before taking this). Jonathan --- drivers/iio/imu/inv_mpu6050/Kconfig| 1 + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 168 +++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 9 ++ 3 files changed, 172 insertions(+), 6 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig index 2d0608b..48fbc0b 100644 --- a/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/drivers/iio/imu/inv_mpu6050/Kconfig @@ -7,6 +7,7 @@ config INV_MPU6050_IIO depends on I2C SYSFS select IIO_BUFFER select IIO_TRIGGERED_BUFFER + select I2C_MUX help This driver supports the Invensense MPU6050 devices. This driver can also support MPU6500 in MPU6050 compatibility mode diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index b75519d..4fce0d1 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -23,6 +23,7 @@ #include linux/kfifo.h #include linux/spinlock.h #include linux/iio/iio.h +#include linux/i2c-mux.h #include inv_mpu_iio.h /* @@ -52,6 +53,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .int_enable = INV_MPU6050_REG_INT_ENABLE, .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, + .int_pin_cfg= INV_MPU6050_REG_INT_PIN_CFG, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -72,11 +74,150 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = { }, }; +static struct i2c_adapter *inv_mux_adapter; + int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d) { return i2c_smbus_write_i2c_block_data(st-client, reg, 1, d); } +/* + * The i2c read/write needs to happen in unlocked mode. As the parent + * adapter is common. If we use locked versions, it will fail as + * the mux adapter will lock the parent i2c adapter, while calling + * select/deselect functions. + */ +static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st, + u8 reg, u8 d) +{ + int ret; + u8 buf[2]; + struct i2c_msg msg[1] = { + { + .addr = st-client-addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = reg; + buf[1] = d; + ret = __i2c_transfer(st-client-adapter, msg, 1); + if (ret != 1) + return ret; + + return 0; +} + +static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv, + u32 chan_id) +{ + struct iio_dev *indio_dev = mux_priv; + struct inv_mpu6050_state *st = iio_priv(indio_dev); + int ret = 0; + + /* Use the same mutex which was used everywhere to protect power-op */ + mutex_lock(indio_dev-mlock); + if (!st-powerup_count) { + ret = inv_mpu6050_write_reg_unlocked(st, st-reg-pwr_mgmt_1, + 0); + if (ret) + goto write_error; + + msleep(INV_MPU6050_REG_UP_TIME); + } + if (!ret) { + st-powerup_count++; + ret = inv_mpu6050_write_reg_unlocked(st, st-reg-int_pin_cfg, + st-client-irq | + INV_MPU6050_BIT_BYPASS_EN); + } +write_error: + mutex_unlock(indio_dev-mlock); + + return ret; +} + +static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, +void *mux_priv, u32 chan_id) +{ + struct iio_dev *indio_dev = mux_priv; + struct inv_mpu6050_state *st = iio_priv(indio_dev); + + mutex_lock(indio_dev-mlock); + /* It doesn't really mattter, if any of the calls fails */ + inv_mpu6050_write_reg_unlocked(st,
Re: [PATCH 1/2] iio: imu: inv_mpu6050: Add i2c mux for by pass
On 17/10/14 18:11, Srinivas Pandruvada wrote: This chip has a mode in which this chipset can be i2c master. But the current upstream driver doesn't support such mode as there is some limited support of clients, which can be connected. To attach such clients to main i2c bus chip has to be set up in bypass mode. Creates an i2c mux, which will enable/disable this mode. This was discussed for a while in mailing list, this was the decision. This change also provides an API, which allows clients to be created for this mux adapter. Signed-off-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com Cc'd Wolfram and linux-i2c given this is basically bolting an i2c_mux into an IIO driver. There isn't enough here to make it worth and mfd (to my mind) if Wolfram is happy. I'm happy with the approach. A few bits and bobs inline. Jonathan --- drivers/iio/imu/inv_mpu6050/Kconfig| 1 + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 163 +++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 9 ++ 3 files changed, 167 insertions(+), 6 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig index 2d0608b..48fbc0b 100644 --- a/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/drivers/iio/imu/inv_mpu6050/Kconfig @@ -7,6 +7,7 @@ config INV_MPU6050_IIO depends on I2C SYSFS select IIO_BUFFER select IIO_TRIGGERED_BUFFER + select I2C_MUX help This driver supports the Invensense MPU6050 devices. This driver can also support MPU6500 in MPU6050 compatibility mode diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index b75519d..9864362 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -23,6 +23,7 @@ #include linux/kfifo.h #include linux/spinlock.h #include linux/iio/iio.h +#include linux/i2c-mux.h #include inv_mpu_iio.h /* @@ -52,6 +53,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .int_enable = INV_MPU6050_REG_INT_ENABLE, .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, + .int_pin_cfg= INV_MPU6050_REG_INT_PIN_CFG, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -72,11 +74,147 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = { }, }; +static struct i2c_adapter *inv_mux_adapter; + Not embedding this surely prevents more than one mpu6050. Can we not put it an instance specific structure? int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d) { return i2c_smbus_write_i2c_block_data(st-client, reg, 1, d); } +/* + * The i2c read/write needs to happen in unlocked mode. As the parent + * adapter is common. If we use locked versions, it will fail as + * the mux adapter will lock the parent i2c adapter, while calling + * select/deselect functions. + */ +static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st, + int reg, u8 d) +{ + int ret; + u8 buf[2]; u8 buf[2] = {reg, d}; perhaps. + struct i2c_msg msg[1] = { Drop the array bit and just use msg below for cleaner code? + { + .addr = st-client-addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = reg; + buf[1] = d; + ret = __i2c_transfer(st-client-adapter, msg, 1); + if (ret != 1) + return ret; + + return 0; +} + +static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv, + u32 chan_id) +{ + struct iio_dev *indio_dev = mux_priv; + struct inv_mpu6050_state *st = iio_priv(indio_dev); + int ret = 0; + + /* Use the same mutex which was used everywhere to protect power-op */ + mutex_lock(indio_dev-mlock); + if (!st-powerup_count) { + ret = inv_mpu6050_write_reg_unlocked(st, st-reg-pwr_mgmt_1, + 0); + if (!ret) + msleep(INV_MPU6050_REG_UP_TIME); + } + if (!ret) { + st-powerup_count++; + ret = inv_mpu6050_write_reg_unlocked(st, st-reg-int_pin_cfg, + st-client-irq | + INV_MPU6050_BIT_BYPASS_EN); + } + mutex_unlock(indio_dev-mlock); + + return ret; +} + +static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, +void *mux_priv, u32 chan_id) +{ + struct iio_dev *indio_dev = mux_priv; + struct inv_mpu6050_state *st = iio_priv(indio_dev); + + mutex_lock(indio_dev-mlock); + /* It
Re: [RFC Patch v0 1/3] i2c-smbus: Add poll interface for smbus alert
On 27/03/14 21:50, Srinivas Pandruvada wrote: On 03/27/2014 10:34 AM, Jonathan Cameron wrote: On March 27, 2014 7:44:56 AM GMT+00:00, Jean Delvarejdelv...@suse.de wrote: On Wed, 26 Mar 2014 17:42:10 -0700, Srinivas Pandruvada wrote: The current i2c smbus alert module depends on smbus alert mechanism supported by underlying bus drivers. By specifications, these alerts can be polled if there is no hardware support. Currently multiple drivers who needs smbus alerts are creating a new i2c dummy device with address 0x0C (ARA register), by luck they don't co-exist. Otherwise i2c device creation will fail. Added a poll interface, so that all these driver can call a common interface to poll. Even if they polli, all drivers bound to an adapater will be notified by their alert callback if ARA register read is successful. Signed-off-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com --- drivers/i2c/i2c-smbus.c | 23 +++ include/linux/i2c-smbus.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index fc99f0d..e274f20 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -72,6 +72,29 @@ static int smbus_do_alert(struct device *dev, void *addrp) return -EBUSY; } +int i2c_smbus_ara_poll(const struct i2c_client *client) +{ + union i2c_smbus_data data; + int status; + struct alert_data alert_data; + + status = i2c_smbus_xfer(client-adapter, 0x0C, 0, + I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE, data); + if (status 0) + return status; + + alert_data.flag = data.byte 1; + alert_data.addr = data.byte 1; + + /* Notify driver for the device which issued the alert */ + device_for_each_child(client-adapter-dev, alert_data, + smbus_do_alert); + + return data.byte; +} This is essentially duplicating code from smbus_alert(), but in a hackish way, as the ARA is never properly reserved. Your bus driver should really register the ARA with i2c_setup_smbus_alert(). I see that the code may not properly deal with the polled case everywhere but it should be pretty trivial to deal with. For example, check for alert-irq 0 before re-enabling the irq in smbus_alert(). I don't immediately see any other change needed. If SMBus alert polling is done from the i2c device driver, we'll have to find a standard way for i2c device drivers to retrieve the ara client associated with an i2c_adapter. However I still need to be convinced that this makes any sense at all. Ultimately the alert will call the i2c device drivers's alert() callback. If the i2c device driver needs to do that, there's no need to go through ARA, it might as well just call the callback by itself. So can you please explain what problem exactly you are trying to solve? As I understand it the issue is that some parts will not clear their internal interrupt status unless an at a read occurs and presumably the read has to get the correct address? To my mind we should have polling inside the core and it should ensure all devices that want to have replied. Have I miss understood how Ara is supposed to work but should we not know which device to call the callback on? Ah, I was barking up the wrong tree with this one and had missed the check that was conducted to ensure that only the right device is notified. Sorry about that. This is summary: May be Jean can suggest some better solution: - We have some sensor devices on i2C bus, which need to read ARA register to ack smbus alert signal. Without acking this, they will not allow further reads. They currently are calling i2c_new_dummy() for reserving ARA (0x0C) register. But the problem is if there are two devices on this bus both have to read ARA, they can't call i2c_new_dummy() as one of them will fail (__i2c_check_addr_busy() will return -EBUSY). - In above case, If they use hacked way to use i2_transfer function, but it will not address the real issue. Because one driver is reading ARA basically can acknowledge ALERT from wrong device. So their needs to be a core level poll so that devices can be notified, if there is an alert for their device only. Agreed. Right now at a quick glance, all devices are notified which seems odd... From physical interface level many i2controllers (including x86s) don't have separate signal for SMBALERT#. So somewhere it needs polling. For some devices SMBALERT is wired through a GPIO for GPIO interrupt. But they still need to read ARA to ACK. If it is wired through a gpio interrupt (and that interrupt is shared by various smbalert equipped devices - or there is only one present on the i2c bus) then it should be handled using the existing infrastructure. (perhaps modified slightly) Also we can't blindly reserve 0x0c for every i2c-bus as 0x0C is a valid i2C address. There are already occupied (e.g. AK8963
Re: [RFC Patch v0 1/3] i2c-smbus: Add poll interface for smbus alert
On March 27, 2014 7:44:56 AM GMT+00:00, Jean Delvare jdelv...@suse.de wrote: On Wed, 26 Mar 2014 17:42:10 -0700, Srinivas Pandruvada wrote: The current i2c smbus alert module depends on smbus alert mechanism supported by underlying bus drivers. By specifications, these alerts can be polled if there is no hardware support. Currently multiple drivers who needs smbus alerts are creating a new i2c dummy device with address 0x0C (ARA register), by luck they don't co-exist. Otherwise i2c device creation will fail. Added a poll interface, so that all these driver can call a common interface to poll. Even if they polli, all drivers bound to an adapater will be notified by their alert callback if ARA register read is successful. Signed-off-by: Srinivas Pandruvada srinivas.pandruv...@linux.intel.com --- drivers/i2c/i2c-smbus.c | 23 +++ include/linux/i2c-smbus.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index fc99f0d..e274f20 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -72,6 +72,29 @@ static int smbus_do_alert(struct device *dev, void *addrp) return -EBUSY; } +int i2c_smbus_ara_poll(const struct i2c_client *client) +{ +union i2c_smbus_data data; +int status; +struct alert_data alert_data; + +status = i2c_smbus_xfer(client-adapter, 0x0C, 0, +I2C_SMBUS_READ, 0, +I2C_SMBUS_BYTE, data); +if (status 0) +return status; + +alert_data.flag = data.byte 1; +alert_data.addr = data.byte 1; + +/* Notify driver for the device which issued the alert */ +device_for_each_child(client-adapter-dev, alert_data, +smbus_do_alert); + +return data.byte; +} This is essentially duplicating code from smbus_alert(), but in a hackish way, as the ARA is never properly reserved. Your bus driver should really register the ARA with i2c_setup_smbus_alert(). I see that the code may not properly deal with the polled case everywhere but it should be pretty trivial to deal with. For example, check for alert-irq 0 before re-enabling the irq in smbus_alert(). I don't immediately see any other change needed. If SMBus alert polling is done from the i2c device driver, we'll have to find a standard way for i2c device drivers to retrieve the ara client associated with an i2c_adapter. However I still need to be convinced that this makes any sense at all. Ultimately the alert will call the i2c device drivers's alert() callback. If the i2c device driver needs to do that, there's no need to go through ARA, it might as well just call the callback by itself. So can you please explain what problem exactly you are trying to solve? As I understand it the issue is that some parts will not clear their internal interrupt status unless an at a read occurs and presumably the read has to get the correct address? To my mind we should have polling inside the core and it should ensure all devices that want to have replied. Have I miss understood how Ara is supposed to work but should we not know which device to call the callback on? +EXPORT_SYMBOL_GPL(i2c_smbus_ara_poll); + /* * The alert IRQ handler needs to hand work off to a task which can issue * SMBus calls, because those sleeping calls can't be made in IRQ context. diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h index 8f1b086..f70755d 100644 --- a/include/linux/i2c-smbus.h +++ b/include/linux/i2c-smbus.h @@ -48,4 +48,7 @@ struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter, struct i2c_smbus_alert_setup *setup); int i2c_handle_smbus_alert(struct i2c_client *ara); +/* Interface to poll smbus alert */ +int i2c_smbus_ara_poll(const struct i2c_client *client); + #endif /* _LINUX_I2C_SMBUS_H */ -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V1 1/1] iio: add Capella cm3218x ambient light sensor driver.
On March 20, 2014 11:19:49 PM GMT+00:00, Srinivas Pandruvada srinivas.pandruv...@linux.intel.com wrote: On 03/19/2014 11:54 PM, Jonathan Cameron wrote: On March 20, 2014 12:58:02 AM GMT+00:00, Kevin Tsai kt...@capellamicro.com wrote: Hi Peter, Thanks for your advise. I'll update my code. ACPI is optional. Most PC manufactory may store the lens factor to ACPI table. But, phone customers like to modify the parameters inside code. CM3218 have two versions. The old version need to read SMBus ARA register to clean interrupt. That's why I need to change I2C chip address. Please guid me if you have a better way to access two addresses. Would the smbus alert infrastructure in drivers/i2ç/i2c-smbus.c help? The smbus alert notification are based on the underlying i2c controller. Not every controller supports. I can see only one controller driver in the upstream Linux added this support. To my mind adding wider support for the alert functionality will be the way forward. Wolfram, any idea why so few bus drivers implement the smbus alert stuff? I would guess you won't be against wider support of this using existing infrastructure? Thanks, Srinivas Thanks. Kevin Tsai 03/19/14 - Original Message - From: Peter Meerwald pme...@pmeerw.net To: Kevin Tsai kt...@capellamicro.com Cc: Jonathan Cameron ji...@kernel.org; linux-...@vger.kernel.org Sent: Wednesday, March 19, 2014 11:07 Subject: Re: [PATCH V1 1/1] iio: add Capella cm3218x ambient light sensor driver. Add Capella Microsystem CM3218x family Ambient Light Sensor IIO driver. This driver will convert raw data to lux value. Default parameters are for reference only. It will detect ACPI table to load per-system manufacturing parameters. nitpicking below --- .../devicetree/bindings/i2c/trivial-devices.txt| 1 + drivers/iio/light/Kconfig | 11 + drivers/iio/light/Makefile | 1 + drivers/iio/light/cm3218x.c| 769 + 4 files changed, 782 insertions(+) create mode 100644 drivers/iio/light/cm3218x.c diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 1a1ac2e..29e7eae 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -17,6 +17,7 @@ at,24c08 i2c serial eeprom (24cxx) atmel,24c02 i2c serial eeprom (24cxx) atmel,at97sc3204t i2c trusted platform module (TPM) capella,cm32181 CM32181: Ambient Light Sensor +capella,cm3218x CM3218x: Ambient Light Sensor catalyst,24c32 i2c serial eeprom dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock dallas,ds1338 I2C RTC with 56-Byte NV RAM diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index d12b2a0..45a22a6 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -38,6 +38,17 @@ config CM32181 To compile this driver as a module, choose M here: the module will be called cm32181. +config CM3218X + depends on I2C is there an ACPI dependency? + tristate CM3218x driver + help + Say Y here if you use cm3218x. + This option enables ambient light sensor using + Capella cm3218x device driver. + + To compile this driver as a module, choose M here: + the module will be called cm3218x. + config CM36651 depends on I2C tristate CM36651 driver diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 60e35ac..a506c23 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ADJD_S311) += adjd_s311.o obj-$(CONFIG_APDS9300) += apds9300.o obj-$(CONFIG_CM32181) += cm32181.o +obj-$(CONFIG_CM3218X) += cm3218x.o obj-$(CONFIG_CM36651) += cm36651.o obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o diff --git a/drivers/iio/light/cm3218x.c b/drivers/iio/light/cm3218x.c new file mode 100644 index 000..e422f68 --- /dev/null +++ b/drivers/iio/light/cm3218x.c @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2014 Capella Microsystems Inc. + * Author: Kevin Tsai kt...@capellamicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2, as published + * by the Free Software Foundation. + * + * Special thanks Srinivas Pandruvada srinivas.pandruv...@linux.intel.com + * help to add ACPI support. + * + */ + +#include linux/delay.h +#include linux/err.h +#include linux/i2c.h +#include linux/mutex.h +#include linux/module.h +#include linux/interrupt.h +#include linux/regulator/consumer.h +#include linux/iio/iio.h +#include linux/iio/sysfs.h +#include linux/iio/events.h +#include linux/init.h +#include linux/acpi.h + +/* Registers Address */ +#define CM3218x_REG_ADDR_CMD 0x00 +#define
Re: [PATCH 2/5] I2C: Add helper macro for i2c_driver boilerplate
On 11/16/2011 05:12 PM, Grant Likely wrote: On Wed, Nov 16, 2011 at 2:13 AM, Lars-Peter Clausen l...@metafoo.de wrote: This patch introduces the module_i2c_driver macro which is a convenience macro for I2C driver modules similar to module_platform_driver. It is intended to be used by drivers which init/exit section does nothing but register/unregister the I2C driver. By using this macro it is possible to eliminate a few lines of boilerplate code per I2C driver. Signed-off-by: Lars-Peter Clausen l...@metafoo.de Acked-by: Grant Likely grant.lik...@secretlab.ca Acked-by: Jonathan Cameron ji...@cam.ac.uk --- include/linux/i2c.h | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a81bf6d..7e92854 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -485,6 +485,19 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) { return adap-nr; } + +/** + * module_i2c_driver() - Helper macro for registering a I2C driver + * @__i2c_driver: i2c_driver struct + * + * Helper macro for I2C drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_i2c_driver(__i2c_driver) \ + module_driver(__i2c_driver, i2c_add_driver, \ + i2c_del_driver) + #endif /* I2C */ #endif /* __KERNEL__ */ -- 1.7.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/5] drivercore: Generalize module_platform_driver
On 11/16/2011 05:11 PM, Grant Likely wrote: On Wed, Nov 16, 2011 at 2:13 AM, Lars-Peter Clausen l...@metafoo.de wrote: This patch generalizes the module_platform_driver macro and introduces a new module_driver macro. The module_driver macro takes a driver name, a register and a unregister function for this driver type. Using these it construct the module init and exit sections which register and unregister the driver. Since such init/exit sections are commonly found in drivers this macro can be used to eliminate a lot of boilerplate code. The macro is not intended to be used by driver modules directly, instead it should be used to generate bus specific macros for registering drivers like the module_platform_driver macro. Signed-off-by: Lars-Peter Clausen l...@metafoo.de Acked-by: Grant Likely grant.lik...@secretlab.ca Acked-by: Jonathan Cameron ji...@kernel.org --- include/linux/init.h| 21 + include/linux/platform_device.h | 12 ++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/include/linux/init.h b/include/linux/init.h index 9146f39..3e2d238 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -346,4 +346,25 @@ void __init parse_early_options(char *cmdline); #define __exit_p(x) NULL #endif +/** + * module_driver() - Helper macro for drivers that don't do anything + * special in module init/exit. This eliminates a lot of boilerplate. + * Each module may only use this macro once, and calling it replaces + * module_init() and module_exit(). + * Use this macro to construct bus specific macros for registering + * drivers. + */ +#define module_driver(__driver, __register, __unregister) \ +static int __init __driver##_init(void) \ +{ \ + return __register((__driver)); \ +} \ +module_init(__driver##_init); \ +static void __exit __driver##_exit(void) \ +{ \ + __unregister((__driver)); \ +} \ +module_exit(__driver##_exit); + #endif /* _LINUX_INIT_H */ + diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 2a23f7d..165a8d1 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -196,16 +196,8 @@ static inline void platform_set_drvdata(struct platform_device *pdev, void *data * calling it replaces module_init() and module_exit() */ #define module_platform_driver(__platform_driver) \ -static int __init __platform_driver##_init(void) \ -{ \ - return platform_driver_register((__platform_driver)); \ -} \ -module_init(__platform_driver##_init); \ -static void __exit __platform_driver##_exit(void) \ -{ \ - platform_driver_unregister((__platform_driver)); \ -} \ -module_exit(__platform_driver##_exit); + module_driver(__platform_driver, platform_driver_register, \ + platform_driver_unregister) extern struct platform_device *platform_create_bundle(struct platform_driver *driver, int (*probe)(struct platform_device *), -- 1.7.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] rtc-isl1208: Use SMBus functions if I2C isn't available
On 10/26/11 03:30, Ben Gardner wrote: The rtc-isl1208 driver currently depends on raw I2C functionality. This patch adds a fall-back to SMBus functions so that the driver can be used on a SMBus-only platforms, such as i2c-isch. Perhaps a summary of how bad things would be if smbus were all that is used? Afterall it is emulated on i2c buses if they don't support it directly. Signed-off-by: Ben Gardner gardner.ben-re5jqeeqqe8avxtiumw...@public.gmane.org --- drivers/rtc/rtc-isl1208.c | 68 +++- 1 files changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index ea10736..c553c7b 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -66,20 +66,35 @@ static int isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len) { - u8 reg_addr[1] = { reg }; - struct i2c_msg msgs[2] = { - {client-addr, 0, sizeof(reg_addr), reg_addr} - , - {client-addr, I2C_M_RD, len, buf} - }; int ret; BUG_ON(reg ISL1208_REG_USR2); BUG_ON(reg + len ISL1208_REG_USR2 + 1); - ret = i2c_transfer(client-adapter, msgs, 2); - if (ret 0) - ret = 0; It's a bit early in the morning, but at least at first glance I think this is an i2c_smbus_i2c_read_block_data reimplementation? + if (i2c_check_functionality(client-adapter, I2C_FUNC_I2C)) { + u8 reg_addr[1] = { reg }; + struct i2c_msg msgs[2] = { + {client-addr, 0, sizeof(reg_addr), reg_addr} + , Odd spacing. + {client-addr, I2C_M_RD, len, buf} + }; + + ret = i2c_transfer(client-adapter, msgs, 2); + if (ret 0) + ret = 0; + } else { + int idx; + ret = i2c_smbus_read_byte_data(client, reg); + if (ret 0) + return ret; + buf[0] = ret; + for (idx = 1; idx len; idx++) { + ret = i2c_smbus_read_byte(client); + if (ret 0) + return ret; + buf[idx] = ret; + } + } return ret; } @@ -88,21 +103,32 @@ static int isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned len) { - u8 i2c_buf[ISL1208_REG_USR2 + 2]; - struct i2c_msg msgs[1] = { - {client-addr, 0, len + 1, i2c_buf} - }; - int ret; + int ret = 0; BUG_ON(reg ISL1208_REG_USR2); BUG_ON(reg + len ISL1208_REG_USR2 + 1); - i2c_buf[0] = reg; - memcpy(i2c_buf[1], buf[0], len); + if (i2c_check_functionality(client-adapter, I2C_FUNC_I2C)) { + u8 i2c_buf[ISL1208_REG_USR2 + 2]; + struct i2c_msg msgs[1] = { + {client-addr, 0, len + 1, i2c_buf} + }; + + i2c_buf[0] = reg; + memcpy(i2c_buf[1], buf[0], len); - ret = i2c_transfer(client-adapter, msgs, 1); - if (ret 0) - ret = 0; + ret = i2c_transfer(client-adapter, msgs, 1); + if (ret 0) + ret = 0; + } else { + int idx; + for (idx = 0; idx len; idx++) { + ret = i2c_smbus_write_byte_data(client, reg + idx, + buf[idx]); + if (ret 0) + return ret; + } + } return ret; } @@ -622,7 +648,9 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) int rc = 0; struct rtc_device *rtc; - if (!i2c_check_functionality(client-adapter, I2C_FUNC_I2C)) + if (!i2c_check_functionality(client-adapter, I2C_FUNC_I2C) + !i2c_check_functionality(client-adapter, I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; if (isl1208_i2c_validate_client(client) 0) -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] i2c: boilerplate function for byte swapped smbus_write/read_word_data
On 10/11/11 16:21, Jonathan Cameron wrote: On 10/11/11 12:49, Jean Delvare wrote: On Mon, 10 Oct 2011 13:50:14 +0200, Jean Delvare wrote: On Mon, 10 Oct 2011 10:07:43 +0100, Jonathan Cameron wrote: Reimplemented at least 17 times discounting error mangling cases where it could be used. Signed-off-by: Jonathan Cameron jic23-KWPb1pKIrIJaa/9udqf...@public.gmane.org --- Documentation/i2c/smbus-protocol |8 include/linux/i2c.h | 17 + 2 files changed, 25 insertions(+), 0 deletions(-) Applied, thanks. BTW... I have a patch ready converting all concerned hwmon drivers to use the new functions. I would appreciate if you could take care of all other drivers. Thanks, Will do. Have IIO patch queued locally. Will get the others covered shortly. Jean, Sorry forgot to cc you on the first few patches I sent out using this. So for reference (and anyone else who cares). IIO I'll deal with when it merges (patch has been posted for a couple of weeks). v4l sent out (5 drivers) input sent out patch (only one user) power sent out patch (only one user) All pretty trivial cases. Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] input:ad7879-i2c use swapped varient of i2c_smbus_read_word_data
On 10/21/11 17:09, Dmitry Torokhov wrote: On Fri, Oct 21, 2011 at 12:57:16PM +0100, Jonathan Cameron wrote: This varient was introduced in i2c: boilerplate function for byte swapped smbus_write/read_word_data This also has the side effect of ensuring any errors from the i2c read and no longer mangled. Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- V2: include the write function as pointed out by Michael Hennerich. The patch introducing this swapped function is working its way through the i2c tree. drivers/input/touchscreen/ad7879-i2c.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c index 4e4e58c..cc51392 100644 --- a/drivers/input/touchscreen/ad7879-i2c.c +++ b/drivers/input/touchscreen/ad7879-i2c.c @@ -47,7 +47,7 @@ static int ad7879_i2c_read(struct device *dev, u8 reg) { struct i2c_client *client = to_i2c_client(dev); -return swab16(i2c_smbus_read_word_data(client, reg)); +return i2c_smbus_read_word_swapped(client, reg); This is still not endian-safe. I wonder if introducing i2c_smbus_read_word_swapped() just makes the metter worse by hiding this... I'd prefer if we had i2c_smbus_read_be16() instead. smbus spec says that all transfers must be little endian. Hence it is type safe because the smbus controllers are guaranteed to have made that assumption and converted to cpu endianess. If not they are buggy. Hence, this is endian safe. Unfortunately numerous devices do the exact opposite (for successive approximation ADCs it would be silly to do otherwise.) Hence they use the smbus protocol, but then have to flip the bytes. -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] i2c: boilerplate function for byte swapped smbus_write/read_word_data
On 10/11/11 12:49, Jean Delvare wrote: On Mon, 10 Oct 2011 13:50:14 +0200, Jean Delvare wrote: On Mon, 10 Oct 2011 10:07:43 +0100, Jonathan Cameron wrote: Reimplemented at least 17 times discounting error mangling cases where it could be used. Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- Documentation/i2c/smbus-protocol |8 include/linux/i2c.h | 17 + 2 files changed, 25 insertions(+), 0 deletions(-) Applied, thanks. BTW... I have a patch ready converting all concerned hwmon drivers to use the new functions. I would appreciate if you could take care of all other drivers. Thanks, Will do. Have IIO patch queued locally. Will get the others covered shortly. -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2] i2c: boilerplate function for byte swapped smbus_write/read_word_data
V2: Jean's suggestions: 1) Documentation as comments on the smbus_write_word_data and smbus_read_word_data entries in Documetation/i2c/smbus-protocol 2) /* for swab 16 comment */ 3) shorter names for the two functions (drop the _data part as it doesn't tell us anything anyway). V1: Hi All, Quite a number of devices rather unhelpfully handle smbus read/write word commands but return the result byte swapped. Hence drivers swap it back again. Examples based on quick grep or read users that byte swap(write is completely trivial) drivers/hwmon/ad7418.c - no error handling so trivial drivers/hwmon/ads1015.c - correct drivers/hwmon/asb100.c - no error handling so trivial drivers/hwmon/ds1621.c - correct drivers/hwmon/ds620.c - no error handling so trivial drivers/hwmon/gl518sm.c - no error handling so trivial drivers/hwmon/gl520sm.c - no error handling so trivial drivers/hwmon/jc42.c - correct drivers/hwmon/lm73.c - no error handling drivers/hwmon/lm75.c - correct drivers/hwmon/lm92.c - some are byte swapped. Implementation doesn't handle errors drivers/hwmon/tmp102.c - correct drivers/hwmon/w83781.c - no error handling. drivers/input/touchscreen/ad7879-i2c.c - no error handling drivers/media/video/mt9m001.c - correct drivers/media/video/mt9m111.c - no error handling drivers/media/video/mt9t031.c - correct drivers/media/video/mt9v022.c - correct drivers/media/video/mt9v032.c - correct drivers/media/video/vpx3220.c - correct drivers/staging/iio/adc/ad7150.c - correct drivers/staging/iio/adc/ad7152.c - correct drivers/staging/iio/adc/ad7291.c - correct drivers/staging/iio/adc/ad7746.c - correct drivers/staging/iio/adc/ad799x_core.c - correct drivers/staging/iio/adc/adt7410.c - correct drivers/staging/iio/adc/adt75.c - correct 'correct' are those that need handle or at least pass on the error code without mangling it. The others typically just shove an error into some local cache without taking any notice. Just for the curious this is based on greping for i2c_smbus_write_word_data and looking to see if the read does the swab16 as well. Anyhow, so to the proposal. Introduce a couple of inline static functions into i2c.h. My only use examples done so far are on top of unpublished iio changes, so I'll leave the reader to take a look and decided whether or not this is interesting enough to do. Even if the driver uses equivalent functions we are saving about 6 lines per user. I'm happy to do a series converting the easy ones from the above if people don't mind the patch. Jonathan Cameron (1): i2c: boilerplate function for byte swapped smbus_write/read_word_data Documentation/i2c/smbus-protocol |8 include/linux/i2c.h | 17 + 2 files changed, 25 insertions(+), 0 deletions(-) -- 1.7.3.4 -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] i2c: boilerplate function for byte swapped smbus_write/read_word_data
Reimplemented at least 17 times discounting error mangling cases where it could be used. Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- Documentation/i2c/smbus-protocol |8 include/linux/i2c.h | 17 + 2 files changed, 25 insertions(+), 0 deletions(-) diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol index 7c19d1a..5003539 100644 --- a/Documentation/i2c/smbus-protocol +++ b/Documentation/i2c/smbus-protocol @@ -88,6 +88,10 @@ byte. But this time, the data is a complete word (16 bits). S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P +Note the convenience function i2c_smbus_read_word_swapped is +available for reads where the two data bytes are the other way +around. (not smbus compliant) + SMBus Write Byte: i2c_smbus_write_byte_data() == @@ -108,6 +112,10 @@ specified through the Comm byte. S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P +Note the convenience function i2c_smbus_write_word_swapped is +available for writes where the two data bytes are the other way +around. (not smbus compliant) + SMBus Process Call: i2c_smbus_process_call() = diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a6c652e..38a21c3 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -34,6 +34,7 @@ #include linux/sched.h /* for completion */ #include linux/mutex.h #include linux/of.h /* for struct device_node */ +#include linux/swab.h/* for swab16 */ extern struct bus_type i2c_bus_type; extern struct device_type i2c_adapter_type; @@ -88,6 +89,22 @@ extern s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command); extern s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value); + +static inline s32 +i2c_smbus_read_word_swapped(const struct i2c_client *client, u8 command) +{ + s32 value = i2c_smbus_read_word_data(client, command); + + return (value 0) ? value : swab16(value); +} + +static inline s32 +i2c_smbus_write_word_swapped(const struct i2c_client *client, +u8 command, u16 value) +{ + return i2c_smbus_write_word_data(client, command, swab16(value)); +} + /* Returns the number of read bytes */ extern s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values); -- 1.7.3.4 -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] i2c: boilerplate function for byte swapped smbus_write/read_word_data
On 09/22/11 14:48, Jonathan Cameron wrote: Reimplemented at least 17 times discounting error mangling cases where it could be used. Anyone care to comment? Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- Hi All, Quite a number of devices rather unhelpfully handle smbus read/write word commands but return the result byte swapped. Hence drivers swap it back again. Examples based on quick grep or read users that byte swap(write is completely trivial) drivers/hwmon/ad7418.c - no error handling so trivial drivers/hwmon/ads1015.c - correct drivers/hwmon/asb100.c - no error handling so trivial drivers/hwmon/ds1621.c - correct drivers/hwmon/ds620.c - no error handling so trivial drivers/hwmon/gl518sm.c - no error handling so trivial drivers/hwmon/gl520sm.c - no error handling so trivial drivers/hwmon/jc42.c - correct drivers/hwmon/lm73.c - no error handling drivers/hwmon/lm75.c - correct drivers/hwmon/lm92.c - some are byte swapped. Implementation doesn't handle errors drivers/hwmon/tmp102.c - correct drivers/hwmon/w83781.c - no error handling. drivers/input/touchscreen/ad7879-i2c.c - no error handling drivers/media/video/mt9m001.c - correct drivers/media/video/mt9m111.c - no error handling drivers/media/video/mt9t031.c - correct drivers/media/video/mt9v022.c - correct drivers/media/video/mt9v032.c - correct drivers/media/video/vpx3220.c - correct drivers/staging/iio/adc/ad7150.c - correct drivers/staging/iio/adc/ad7152.c - correct drivers/staging/iio/adc/ad7291.c - correct drivers/staging/iio/adc/ad7746.c - correct drivers/staging/iio/adc/ad799x_core.c - correct drivers/staging/iio/adc/adt7410.c - correct drivers/staging/iio/adc/adt75.c - correct 'correct' are those that need handle or at least pass on the error code without mangling it. The others typically just shove an error into some local cache without taking any notice. Just for the curious this is based on greping for i2c_smbus_write_word_data and looking to see if the read does the swab16 as well. Anyhow, so to the proposal. Introduce a couple of inline static functions into i2c.h. My only use examples done so far are on top of unpublished iio changes, so I'll leave the reader to take a look and decided whether or not this is interesting enough to do. Even if the driver uses equivalent functions we are saving about 6 lines per user. I'm happy to do a series converting the easy ones from the above if people don't mind the patch. include/linux/i2c.h | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a6c652e..59ae02b 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -34,6 +34,7 @@ #include linux/sched.h /* for completion */ #include linux/mutex.h #include linux/of.h/* for struct device_node */ +#include linux/swab.h extern struct bus_type i2c_bus_type; extern struct device_type i2c_adapter_type; @@ -88,6 +89,23 @@ extern s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command); extern s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value); + +static inline s32 +i2c_smbus_read_word_data_swapped(const struct i2c_client *client, + u8 command) +{ + s32 value = i2c_smbus_read_word_data(client, command); + + return (value 0) ? value : swab16(value); +} + +static inline s32 +i2c_smbus_write_word_data_swapped(const struct i2c_client *client, + u8 command, u16 value) +{ + return i2c_smbus_write_word_data(client, command, swab16(value)); +} + /* Returns the number of read bytes */ extern s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] i2c: boilerplate function for byte swapped smbus_write/read_word_data
Reimplemented at least 17 times discounting error mangling cases where it could be used. Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- Hi All, Quite a number of devices rather unhelpfully handle smbus read/write word commands but return the result byte swapped. Hence drivers swap it back again. Examples based on quick grep or read users that byte swap(write is completely trivial) drivers/hwmon/ad7418.c - no error handling so trivial drivers/hwmon/ads1015.c - correct drivers/hwmon/asb100.c - no error handling so trivial drivers/hwmon/ds1621.c - correct drivers/hwmon/ds620.c - no error handling so trivial drivers/hwmon/gl518sm.c - no error handling so trivial drivers/hwmon/gl520sm.c - no error handling so trivial drivers/hwmon/jc42.c - correct drivers/hwmon/lm73.c - no error handling drivers/hwmon/lm75.c - correct drivers/hwmon/lm92.c - some are byte swapped. Implementation doesn't handle errors drivers/hwmon/tmp102.c - correct drivers/hwmon/w83781.c - no error handling. drivers/input/touchscreen/ad7879-i2c.c - no error handling drivers/media/video/mt9m001.c - correct drivers/media/video/mt9m111.c - no error handling drivers/media/video/mt9t031.c - correct drivers/media/video/mt9v022.c - correct drivers/media/video/mt9v032.c - correct drivers/media/video/vpx3220.c - correct drivers/staging/iio/adc/ad7150.c - correct drivers/staging/iio/adc/ad7152.c - correct drivers/staging/iio/adc/ad7291.c - correct drivers/staging/iio/adc/ad7746.c - correct drivers/staging/iio/adc/ad799x_core.c - correct drivers/staging/iio/adc/adt7410.c - correct drivers/staging/iio/adc/adt75.c - correct 'correct' are those that need handle or at least pass on the error code without mangling it. The others typically just shove an error into some local cache without taking any notice. Just for the curious this is based on greping for i2c_smbus_write_word_data and looking to see if the read does the swab16 as well. Anyhow, so to the proposal. Introduce a couple of inline static functions into i2c.h. My only use examples done so far are on top of unpublished iio changes, so I'll leave the reader to take a look and decided whether or not this is interesting enough to do. Even if the driver uses equivalent functions we are saving about 6 lines per user. I'm happy to do a series converting the easy ones from the above if people don't mind the patch. include/linux/i2c.h | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a6c652e..59ae02b 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -34,6 +34,7 @@ #include linux/sched.h /* for completion */ #include linux/mutex.h #include linux/of.h /* for struct device_node */ +#include linux/swab.h extern struct bus_type i2c_bus_type; extern struct device_type i2c_adapter_type; @@ -88,6 +89,23 @@ extern s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command); extern s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value); + +static inline s32 +i2c_smbus_read_word_data_swapped(const struct i2c_client *client, +u8 command) +{ + s32 value = i2c_smbus_read_word_data(client, command); + + return (value 0) ? value : swab16(value); +} + +static inline s32 +i2c_smbus_write_word_data_swapped(const struct i2c_client *client, + u8 command, u16 value) +{ + return i2c_smbus_write_word_data(client, command, swab16(value)); +} + /* Returns the number of read bytes */ extern s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values); -- 1.7.3.4 -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V3 1/5] i2c: Add irq_gpio field to struct i2c_client, i2c_board_info.
On 09/20/11 05:16, Grant Likely wrote: On Fri, Sep 02, 2011 at 08:56:20AM +0200, Jean Delvare wrote: Stephen, Can you please fix your e-mail client / system / whatever so that your patch series are no longer sent duplicated? On Thu, 1 Sep 2011 16:04:27 -0600, Stephen Warren wrote: Some devices use a single pin as both an IRQ and a GPIO. In that case, irq_gpio is the GPIO ID for that pin. Not all drivers use this feature. Where they do, and the use of this feature is optional, and the system wishes to disable this feature, this field must be explicitly set to a defined invalid GPIO ID, such as -1. Signed-off-by: Stephen Warren swar...@nvidia.com --- v3: Also add the field to i2c_board_info, and copy the field from i2c_board_info to i2c_client upon instantiation I don't get the idea. The i2c core doesn't make any use of the field, and that field will only be used by a few drivers amongst the 420+ i2c drivers in the tree. This looks like a waste of memory. What's wrong with including the new field in the private platform or arch data structure for drivers which need it? I have to second the concern; but for a different reason. This shouldn't even remotely be necessary. If the pin is used as an interrupt, then interrupt controller driver (which I would assume is also the gpio controller driver) should be responsible for setting up the pin so that it can be used correctly as a irq line. Why does the gpio number need to be explicitly passed? The particular driver covered here is somewhat of a false positive. It really ought to be rewritten to do everything 'properly' with interrupts. Right now no one with the inclination has the hardware to fix it up. The nasty case we are trying to cover is peripherals that use level interrupts talking to gpio chips that only do edge triggered ones. We use the pin as an irq but have to query it as a gpio to discover if the sneaky chip raised it again without it actually going low. There are sometimes work arounds involving polling registers on the device to check if the interrupt is active, but give the bus is slow, pinging the gpio to find out it's state is often much faster. So it's a dirty hack for dirty hardware. Having said that I agree that it's a niche case and certainly shouldn't be part of any core code, unless it is done right at the core in the generic interrupt code and previous discussions suggest that is tricky to say the least! -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 1/4] i2c: Add irq_gpio field to struct i2c_client.
On 09/01/11 17:52, Stephen Warren wrote: Some devices use a single pin as both an IRQ and a GPIO. In that case, irq_gpio is the GPIO ID for that pin. Not all drivers use this feature. Where they do, and the use of this feature is optional, and the system wishes to disable this feature, this field must be explicitly set to a defined invalid GPIO ID, such as -1. Why make it specifically an irq related gpio? Might as well just call it gpio then it can be used for cases where it never corresponds to an irq such as capture trigger pins. Otherwise I'd be happy to see this go in. Signed-off-by: Stephen Warren swar...@nvidia.com --- v2: This patch is new. This updated series based on Arnd's comments that this solution was a good idea. Note that I leave on vacation for 2 weeks starting Friday afternoon. I may have some email capabilities during this time, but will certainly be slow to respond. include/linux/i2c.h |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 3fad485..b368097 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -192,6 +192,12 @@ struct i2c_driver { * @driver: device's driver, hence pointer to access routines * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) + * @irq_gpio: some devices use a single pin as both an IRQ and a GPIO. In + * that case, irq_gpio is the GPIO ID for that pin. Not all drivers + * use this feature. Where they do, and the use of this feature is + * optional, and the system wishes to disable this feature, this + * field must be explicitly set to a defined invalid GPIO ID, such + * as -1. * @detected: member of an i2c_driver.clients list or i2c-core's * userspace_devices list * @@ -209,6 +215,7 @@ struct i2c_client { struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq;/* irq issued by device */ + int irq_gpio; /* gpio corresponding to irq*/ struct list_head detected; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 1/4] i2c: Add irq_gpio field to struct i2c_client.
On 09/02/11 09:48, Jonathan Cameron wrote: On 09/01/11 17:52, Stephen Warren wrote: Some devices use a single pin as both an IRQ and a GPIO. In that case, irq_gpio is the GPIO ID for that pin. Not all drivers use this feature. Where they do, and the use of this feature is optional, and the system wishes to disable this feature, this field must be explicitly set to a defined invalid GPIO ID, such as -1. Why make it specifically an irq related gpio? Might as well just call it gpio then it can be used for cases where it never corresponds to an irq such as capture trigger pins. Otherwise I'd be happy to see this go in. oops, should have taken a closer look. For i2c devices specified by i2c_board_info structs there is no way of actually specifying this value. Signed-off-by: Stephen Warren swar...@nvidia.com --- v2: This patch is new. This updated series based on Arnd's comments that this solution was a good idea. Note that I leave on vacation for 2 weeks starting Friday afternoon. I may have some email capabilities during this time, but will certainly be slow to respond. include/linux/i2c.h |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 3fad485..b368097 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -192,6 +192,12 @@ struct i2c_driver { * @driver: device's driver, hence pointer to access routines * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) + * @irq_gpio: some devices use a single pin as both an IRQ and a GPIO. In + * that case, irq_gpio is the GPIO ID for that pin. Not all drivers + * use this feature. Where they do, and the use of this feature is + * optional, and the system wishes to disable this feature, this + * field must be explicitly set to a defined invalid GPIO ID, such + * as -1. * @detected: member of an i2c_driver.clients list or i2c-core's * userspace_devices list * @@ -209,6 +215,7 @@ struct i2c_client { struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq;/* irq issued by device */ +int irq_gpio; /* gpio corresponding to irq*/ struct list_head detected; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 3/4] staging:iio:magnetometer:ak8975: Don't assume 0 is an invalid GPIO
On 09/01/11 17:52, Stephen Warren wrote: gpio_is_valid() is the defined mechanism to determine whether a GPIO is valid. Use this instead of assuming that 0 is an invalid GPIO. This one is unchanged so you should probably have carried acks from v1. Anyhow, Signed-off-by: Stephen Warren swar...@nvidia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/staging/iio/magnetometer/ak8975.c | 11 +-- 1 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 14076da..0dfdf50 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -373,7 +373,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val) } /* Wait for the conversion to complete. */ - if (data-eoc_gpio) + if (gpio_is_valid(data-eoc_gpio)) ret = wait_conversion_complete_gpio(data); else ret = wait_conversion_complete_polled(data); @@ -481,7 +481,7 @@ static int ak8975_probe(struct i2c_client *client, /* We may not have a GPIO based IRQ to scan, that is fine, we will poll if so */ - if (eoc_gpio 0) { + if (gpio_is_valid(eoc_gpio)) { err = gpio_request(eoc_gpio, ak_8975); if (err 0) { dev_err(client-dev, @@ -497,8 +497,7 @@ static int ak8975_probe(struct i2c_client *client, eoc_gpio, err); goto exit_gpio; } - } else - eoc_gpio = 0; /* No GPIO available */ + } /* Register with IIO */ indio_dev = iio_allocate_device(sizeof(*data)); @@ -534,7 +533,7 @@ static int ak8975_probe(struct i2c_client *client, exit_free_iio: iio_free_device(indio_dev); exit_gpio: - if (eoc_gpio) + if (gpio_is_valid(eoc_gpio)) gpio_free(eoc_gpio); exit: return err; @@ -549,7 +548,7 @@ static int ak8975_remove(struct i2c_client *client) iio_device_unregister(indio_dev); iio_free_device(indio_dev); - if (eoc_gpio) + if (gpio_is_valid(eoc_gpio)) gpio_free(eoc_gpio); return 0; -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 4/4] staging:iio:magnetometer:ak8975: Fix probe() error-handling
On 09/01/11 17:52, Stephen Warren wrote: Fix ak8975_probe() to jump to the appropriate exit labels when an error occurs. With the previous code, some cleanup actions were being skipped for some error conditions. Signed-off-by: Stephen Warren swar...@nvidia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/staging/iio/magnetometer/ak8975.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 0dfdf50..cc20e8d 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -510,7 +510,7 @@ static int ak8975_probe(struct i2c_client *client, err = ak8975_setup(client); if (err 0) { dev_err(client-dev, AK8975 initialization fails\n); - goto exit_gpio; + goto exit_free_iio; } i2c_set_clientdata(client, indio_dev); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V3 1/5] i2c: Add irq_gpio field to struct i2c_client, i2c_board_info.
On 09/02/11 07:56, Jean Delvare wrote: Stephen, Can you please fix your e-mail client / system / whatever so that your patch series are no longer sent duplicated? On Thu, 1 Sep 2011 16:04:27 -0600, Stephen Warren wrote: Some devices use a single pin as both an IRQ and a GPIO. In that case, irq_gpio is the GPIO ID for that pin. Not all drivers use this feature. Where they do, and the use of this feature is optional, and the system wishes to disable this feature, this field must be explicitly set to a defined invalid GPIO ID, such as -1. Signed-off-by: Stephen Warren swar...@nvidia.com --- v3: Also add the field to i2c_board_info, and copy the field from i2c_board_info to i2c_client upon instantiation I don't get the idea. The i2c core doesn't make any use of the field, and that field will only be used by a few drivers amongst the 420+ i2c drivers in the tree. This looks like a waste of memory. What's wrong with including the new field in the private platform or arch data structure for drivers which need it? Why not make it platform data for now and 'if' it becomes way more common (probably won't) we can always propose adding as a general field at a later date. -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging iio: Replace kmalloc with local variable
On 06/09/11 09:34, anish singh wrote: On Thu, Jun 9, 2011 at 1:59 PM, Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org wrote: On Thu, 9 Jun 2011 13:53:09 +0530, anish singh wrote: On Wed, Jun 8, 2011 at 10:41 AM, anish singh anish198519851...@gmail.com mailto:anish198519851...@gmail.comwrote: On Tue, Jun 7, 2011 at 7:32 PM, Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org wrote: To be clearer, it is down to the i2c BUS (adapter) driver, NOT the i2c device driver. So the patch is correct. I think i can take Jean ack on this?If yes then Joanthan kindly apply this patch and i think you didn't lead me in wrong way as whatever said by you is corroborated by jean also i.e. it is I2C bus driver responsiblity to care about DMA. Sorry to ping you again.Can i take your ack on this? Yes of course. Acked-by: Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org Thanks a ton.Jonathan kindly apply it now :) Greg, I'll send this one on to you with the set I currently have out for review. Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging iio: Replace kmalloc with local variable
On 06/09/11 09:48, Jonathan Cameron wrote: On 06/09/11 09:34, anish singh wrote: On Thu, Jun 9, 2011 at 1:59 PM, Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org wrote: On Thu, 9 Jun 2011 13:53:09 +0530, anish singh wrote: On Wed, Jun 8, 2011 at 10:41 AM, anish singh anish198519851...@gmail.com mailto:anish198519851...@gmail.comwrote: On Tue, Jun 7, 2011 at 7:32 PM, Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org wrote: To be clearer, it is down to the i2c BUS (adapter) driver, NOT the i2c device driver. So the patch is correct. I think i can take Jean ack on this?If yes then Joanthan kindly apply this patch and i think you didn't lead me in wrong way as whatever said by you is corroborated by jean also i.e. it is I2C bus driver responsiblity to care about DMA. Sorry to ping you again.Can i take your ack on this? Yes of course. Acked-by: Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org Thanks a ton.Jonathan kindly apply it now :) Greg, I'll send this one on to you with the set I currently have out for review. Doh, after all this, I just tried to apply this to find the code in question has already gone. Anish, what tree are you working against? Looks like I did an equivalent clean up (with a load of others) back in May then forgot about it. Sorry all. I should have actually have checked it was still relevant rather than reviewing purely on basis of content of patch... Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging iio: Replace kmalloc with local variable
On 06/09/11 15:29, anish singh wrote: On Thu, Jun 9, 2011 at 7:46 PM, Jonathan Cameron ji...@cam.ac.uk mailto:ji...@cam.ac.uk wrote: On 06/09/11 09:48, Jonathan Cameron wrote: On 06/09/11 09:34, anish singh wrote: On Thu, Jun 9, 2011 at 1:59 PM, Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org mailto:kh...@linux-fr.org mailto:kh...@linux-fr.org wrote: On Thu, 9 Jun 2011 13:53:09 +0530, anish singh wrote: On Wed, Jun 8, 2011 at 10:41 AM, anish singh anish198519851...@gmail.com mailto:anish198519851...@gmail.com mailto:anish198519851...@gmail.com mailto:anish198519851...@gmail.comwrote: On Tue, Jun 7, 2011 at 7:32 PM, Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org mailto:kh...@linux-fr.org mailto:kh...@linux-fr.org wrote: To be clearer, it is down to the i2c BUS (adapter) driver, NOT the i2c device driver. So the patch is correct. I think i can take Jean ack on this?If yes then Joanthan kindly apply this patch and i think you didn't lead me in wrong way as whatever said by you is corroborated by jean also i.e. it is I2C bus driver responsiblity to care about DMA. Sorry to ping you again.Can i take your ack on this? Yes of course. Acked-by: Jean Delvare kh...@linux-fr.org mailto:kh...@linux-fr.org mailto:kh...@linux-fr.org mailto:kh...@linux-fr.org Thanks a ton.Jonathan kindly apply it now :) Greg, I'll send this one on to you with the set I currently have out for review. Doh, after all this, I just tried to apply this to find the code in question has already gone. Anish, what tree are you working against? I am using linux-next.Is it not the right tree for staging? Something curious is going on then because this code is no longer in linux-next either. Looks like I did an equivalent clean up (with a load of others) back in May then forgot about it. Sorry all. I should have actually have checked it was still relevant rather than reviewing purely on basis of content of patch... Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging iio: Replace kmalloc with local variable
On 06/07/11 13:39, anish wrote: From: anish kumar anish198519851...@gmail.com replaced kmalloc with local variable as I2C(in this case) doesn't require kmalloc memory it can do with stack memory. I've cc'd linux-i2c just to check I'm right about the whole i2c doesn't need dma safe buffers bit... Signed-off-by: anish kumar anish198519851...@gmail.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/staging/iio/adc/max1363_core.c |5 + 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 1037087..9462230 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -207,15 +207,12 @@ static int max1363_write_basic_config(struct i2c_client *client, unsigned char d2) { int ret; - u8 *tx_buf = kmalloc(2, GFP_KERNEL); + u8 tx_buf[2]; - if (!tx_buf) - return -ENOMEM; tx_buf[0] = d1; tx_buf[1] = d2; ret = i2c_master_send(client, tx_buf, 2); - kfree(tx_buf); return (ret 0) ? 0 : ret; } -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging iio: Replace kmalloc with local variable
On 06/07/11 14:41, Ben Dooks wrote: On Tue, Jun 07, 2011 at 02:00:23PM +0100, Jonathan Cameron wrote: On 06/07/11 13:39, anish wrote: From: anish kumar anish198519851...@gmail.com replaced kmalloc with local variable as I2C(in this case) doesn't require kmalloc memory it can do with stack memory. I've cc'd linux-i2c just to check I'm right about the whole i2c doesn't need dma safe buffers bit... No, it is down to the i2c driver, and from recollection dma from stack is not recommended, due to things like cache line alignment. Please do not do this. Then lets drop this. Sorry Anish, seems I led you down the garden path. I'll check all my i2c drivers don't do this... Signed-off-by: anish kumar anish198519851...@gmail.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/staging/iio/adc/max1363_core.c |5 + 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 1037087..9462230 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -207,15 +207,12 @@ static int max1363_write_basic_config(struct i2c_client *client, unsigned char d2) { int ret; - u8 *tx_buf = kmalloc(2, GFP_KERNEL); + u8 tx_buf[2]; - if (!tx_buf) - return -ENOMEM; tx_buf[0] = d1; tx_buf[1] = d2; ret = i2c_master_send(client, tx_buf, 2); - kfree(tx_buf); return (ret 0) ? 0 : ret; } -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] misc: Driver for Silicon Labs Si570 and compatibles
On 04/19/11 22:36, Guenter Roeck wrote: This driver adds support for Si570, Si571, Si598, and Si599 programmable XO/VCXO. cc'd Michael Hennerich, as I would imagine this has some similarities to the DDS chips we have in IIO (be it a very simple one). Guenter, what is your use case for this part? Signed-off-by: Guenter Roeck guenter.ro...@ericsson.com --- v2: - Fixed checkpatch errors and warnings - Moved si570.h platform data include file to include/linux/platform_data - Documented reset sysfs attribute - Added Documentation/ABI/testing/sysfs-bus-i2c-si570 Documentation/ABI/testing/sysfs-bus-i2c-si570 | 21 ++ Documentation/misc-devices/si570 | 62 MAINTAINERS |7 + drivers/misc/Kconfig | 10 + drivers/misc/Makefile |1 + drivers/misc/si570.c | 398 + include/linux/platform_data/si570.h | 23 ++ 7 files changed, 522 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-si570 create mode 100644 Documentation/misc-devices/si570 create mode 100644 drivers/misc/si570.c create mode 100644 include/linux/platform_data/si570.h diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-si570 b/Documentation/ABI/testing/sysfs-bus-i2c-si570 new file mode 100644 index 000..78c43f7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-i2c-si570 @@ -0,0 +1,21 @@ +What:/sys/bus/i2c/devices/busnum-devaddr/frequency +Date:April 2011 +Kernel version: 2.6.40 ? +Contact: Guenter Roeck guenter.ro...@ericsson.com +Description: + Read or write XO/VCXO frequency of the device in Hz. + + Accepted values: 10 MHz to 1400 MHz for Si570 and Si571, + 10 MHz to 525 MHz for Si598 and Si599. +Users: + Userspace applications interested in knowing or changing the + device frequency. + +What:/sys/bus/i2c/devices/busnum-devaddr/reset +Date:April 2011 +Kernel Version: 2.6.40 ? +Contact: Guenter Roeck guenter.ro...@ericsson.com +Description: Writing a value other than 0 resets the device. + Reading always returns 0 and has no effect. +Users: + Userspace applications interested in resetting the device. diff --git a/Documentation/misc-devices/si570 b/Documentation/misc-devices/si570 new file mode 100644 index 000..54e32f7 --- /dev/null +++ b/Documentation/misc-devices/si570 @@ -0,0 +1,62 @@ +Kernel driver si570 += + +Supported chips: + * Silicon Labs Si570/Si571 +Prefix: 'si570' +Addresses scanned: None (see below) +Datasheets: +http://www.silabs.com/Support%20Documents/TechnicalDocs/si570.pdf + * Silicon Labs Si598/Si599 +Prefix: 'si598' +Addresses scanned: None (see below) +Datasheets: + http://www.silabs.com/Support%20Documents/TechnicalDocs/si598-99.pdf + +Author: Guenter Roeck guenter.ro...@ericsson.com + + +Description +--- + +The Si570/Si598 XO and Si571/Si599 VCXO provide a low-jitter clock at any +frequency. + +The Si570/Si571 are user-programmable to any output frequency from 10 to 945 MHz +and select frequencies to 1400 MHz with 1 ppb resolution. + +The Si598/Si599 are user programmable to any output frequency from 10 to 525 MHz +with 28 parts per trillion (ppt) resolution. + +See the datasheets for more information. + + +Sysfs entries +- + +frequency- Selected frequency +reset- Writing a value other than 0 resets the device + + +General Remarks +--- + +The chips support all valid 7-bit I2C addresses. I2C addresses are assigned +during the ordering process. + +This driver does not auto-detect devices. You will have to instantiate the +devices explicitly. Please see Documentation/i2c/instantiating-devices for +details. + + +Platform data +- + +The devices can be provided with platform data to select the factory default +output frequency. If platform data is not specified, the driver will assume a +default factory output frequency of 125 MHz for Si570/Si571 and 10 MHz for +Si598/Si599. + +struct si570_platform_data { + unsigned long fout; /* Factory default output frequency */ +}; diff --git a/MAINTAINERS b/MAINTAINERS index ec36003..4c339ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5406,6 +5406,13 @@ L: linux-ser...@vger.kernel.org S: Maintained F: drivers/tty/serial +SI570 DRIVER +M: Guenter Roeck guenter.ro...@ericsson.com +L: linux-ker...@vger.kernel.org +S: Maintained +F: drivers/misc/si570.c +F: include/linux/platform_data/si570.h + TIMEKEEPING, NTP M: John Stultz johns...@us.ibm.com M: Thomas Gleixner t...@linutronix.de diff --git
Re: [Device-drivers-devel] [PATCH] i2c: add irq_flags to board info
On 10/25/10 01:45, Ben Dooks wrote: On Mon, Oct 18, 2010 at 03:51:49PM -0400, Mike Frysinger wrote: On Mon, Oct 18, 2010 at 10:33, Jean Delvare wrote: Why do we have set_irq_type() if we're not supposed to call it? I am not claiming to be an expert in the area, but it seems totally reasonable to me that the same piece of code instantiating an I2C device is also responsible for setting its IRQ type. but we're back to the same issue mentioned earlier -- you cant have a single kernel build with modules supporting multiple drivers simultaneously. we like to ship development boards with a single kernel build on it with many modules. then people can pick the addon boards they wish to prototype with at runtime by plugging in the card and loading the module. I also dislike set_irq_type() as it doesn't check whether there is anyone registered with the interrupt, which means that you could set the irq type of someone else's irq. I wonder if we should pass a struct resource instead, in case there are multiple interrupt sources, as well as having it registered with the right resource systems. Either works as far as I am concerned. Having seen a large set of drivers using the flags option (posted to linux-iio yesterday) I'm definitely convinced some means of allowing devices to match what the board config asks for is useful. I personally prefer the struct resource option as I have multiple drivers in IIO which have two interrupts and this is the only reason some of them use platform data. Thanks, Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/12] hwmon: lis3: regulator control
On 10/22/10 12:57, Samu Onkalo wrote: Based on pm_runtime control, turn lis3 regulators on and off. Perform context save and restore on transitions. Feature is optional and must be enabled in platform data. Answers all my queries on the previous version Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/hwmon/lis3lv02d.c | 52 ++ drivers/hwmon/lis3lv02d.h | 12 + drivers/hwmon/lis3lv02d_i2c.c | 55 - include/linux/lis3lv02d.h |2 + 4 files changed, 120 insertions(+), 1 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 412ddc3..ade6f3a 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -31,6 +31,7 @@ #include linux/delay.h #include linux/wait.h #include linux/poll.h +#include linux/slab.h #include linux/freezer.h #include linux/uaccess.h #include linux/miscdevice.h @@ -223,10 +224,46 @@ fail: return ret; } +/* + * Order of registers in the list affects to order of the restore process. + * Perhaps it is a good idea to set interrupt enable register as a last one + * after all other configurations + */ +static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1, +FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2, +CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ, +CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW, +CTRL_REG1, CTRL_REG2, CTRL_REG3}; + +static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H, +FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H, +DD_THSE_L, DD_THSE_H, +CTRL_REG1, CTRL_REG3, CTRL_REG2}; + +static inline void lis3_context_save(struct lis3lv02d *lis3) +{ + int i; + for (i = 0; i lis3-regs_size; i++) + lis3-read(lis3, lis3-regs[i], lis3-reg_cache[i]); + lis3-regs_stored = true; +} + +static inline void lis3_context_restore(struct lis3lv02d *lis3) +{ + int i; + if (lis3-regs_stored) + for (i = 0; i lis3-regs_size; i++) + lis3-write(lis3, lis3-regs[i], lis3-reg_cache[i]); +} + void lis3lv02d_poweroff(struct lis3lv02d *lis3) { + if (lis3-reg_ctrl) + lis3_context_save(lis3); /* disable X,Y,Z axis and power down */ lis3-write(lis3, CTRL_REG1, 0x00); + if (lis3-reg_ctrl) + lis3-reg_ctrl(lis3, LIS3_REG_OFF); } EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); @@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) reg |= CTRL2_BDU; lis3-write(lis3, CTRL_REG2, reg); } + if (lis3-reg_ctrl) + lis3_context_restore(lis3); } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); @@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) pm_runtime_disable(lis3-pm_dev); pm_runtime_set_suspended(lis3-pm_dev); } + kfree(lis3-reg_cache); return 0; } EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); @@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) dev-odrs = lis3_12_rates; dev-odr_mask = CTRL1_DF0 | CTRL1_DF1; dev-scale = LIS3_SENSITIVITY_12B; + dev-regs = lis3_wai12_regs; + dev-regs_size = ARRAY_SIZE(lis3_wai12_regs); break; case WAI_8B: printk(KERN_INFO DRIVER_NAME : 8 bits sensor found\n); @@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) dev-odrs = lis3_8_rates; dev-odr_mask = CTRL1_DR; dev-scale = LIS3_SENSITIVITY_8B; + dev-regs = lis3_wai8_regs; + dev-regs_size = ARRAY_SIZE(lis3_wai8_regs); break; default: printk(KERN_ERR DRIVER_NAME @@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) return -EINVAL; } + dev-reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), + sizeof(lis3_wai12_regs)), GFP_KERNEL); + + if (dev-reg_cache == NULL) { + printk(KERN_ERR DRIVER_NAME out of memory\n); + return -ENOMEM; + } + mutex_init(dev-mutex); lis3lv02d_add_fs(dev); diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 3e8a208..7661e59 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -20,6 +20,7 @@ */ #include linux/platform_device.h #include linux/input-polldev.h +#include linux/regulator/consumer.h /* * This driver tries to support the digital accelerometer chips from @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b { CLICK_IA= 0x40
Re: [PATCH 01/12] hwmon: lis3: pm_runtime support
On 10/22/10 12:57, Samu Onkalo wrote: Add pm_runtime support to lis3 core driver. Add pm_runtime support to lis3 i2c driver. spi and hp_accel drivers are not yet supported. Old always on functionality remains for those. For sysfs there is 5 second delay before turning off the chip to avoid long ramp up delay. I acked this last time around (after Samu answered some queries I had) and I don't think it has changed. Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/hwmon/lis3lv02d.c | 60 + drivers/hwmon/lis3lv02d.h |1 + drivers/hwmon/lis3lv02d_i2c.c | 54 - 3 files changed, 102 insertions(+), 13 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index fc591ae..412ddc3 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -34,6 +34,7 @@ #include linux/freezer.h #include linux/uaccess.h #include linux/miscdevice.h +#include linux/pm_runtime.h #include asm/atomic.h #include lis3lv02d.h @@ -43,6 +44,9 @@ #define MDPS_POLL_INTERVAL 50 #define MDPS_POLL_MIN 0 #define MDPS_POLL_MAX 2000 + +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */ + /* * The sensor can also generate interrupts (DRDY) but it's pretty pointless * because they are generated even if the data do not change. So it's better @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) mutex_unlock(lis3_dev.mutex); } +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) +{ + if (lis3_dev.pm_dev) + pm_runtime_get_sync(lis3_dev.pm_dev); +} + +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) +{ + if (lis3_dev.pm_dev) + pm_runtime_put(lis3_dev.pm_dev); +} + static irqreturn_t lis302dl_interrupt(int irq, void *dummy) { if (!test_bit(0, lis3_dev.misc_opened)) @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) if (test_and_set_bit(0, lis3_dev.misc_opened)) return -EBUSY; /* already open */ + if (lis3_dev.pm_dev) + pm_runtime_get_sync(lis3_dev.pm_dev); + atomic_set(lis3_dev.count, 0); return 0; } @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { fasync_helper(-1, file, 0, lis3_dev.async_queue); clear_bit(0, lis3_dev.misc_opened); /* release the device */ + if (lis3_dev.pm_dev) + pm_runtime_put(lis3_dev.pm_dev); return 0; } @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void) return -ENOMEM; lis3_dev.idev-poll = lis3lv02d_joystick_poll; + lis3_dev.idev-open = lis3lv02d_joystick_open; + lis3_dev.idev-close = lis3lv02d_joystick_close; lis3_dev.idev-poll_interval = MDPS_POLL_INTERVAL; lis3_dev.idev-poll_interval_min = MDPS_POLL_MIN; lis3_dev.idev-poll_interval_max = MDPS_POLL_MAX; @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void) EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); /* Sysfs stuff */ +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3) +{ + /* + * SYSFS functions are fast visitors so put-call + * immediately after the get-call. However, keep + * chip running for a while and schedule delayed + * suspend. This way periodic sysfs calls doesn't + * suffer from relatively long power up time. + */ + + if (lis3-pm_dev) { + pm_runtime_get_sync(lis3-pm_dev); + pm_runtime_put_noidle(lis3-pm_dev); + pm_schedule_suspend(lis3-pm_dev, LIS3_SYSFS_POWERDOWN_DELAY); + } +} + static ssize_t lis3lv02d_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { int result; s16 values[3]; + lis3lv02d_sysfs_poweron(lis3_dev); result = lis3lv02d_selftest(lis3_dev, values); return sprintf(buf, %s %d %d %d\n, result == 0 ? OK : FAIL, values[0], values[1], values[2]); @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev, { int x, y, z; + lis3lv02d_sysfs_poweron(lis3_dev); mutex_lock(lis3_dev.mutex); lis3lv02d_get_xyz(lis3_dev, x, y, z); mutex_unlock(lis3_dev.mutex); @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev, static ssize_t lis3lv02d_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { + lis3lv02d_sysfs_poweron(lis3_dev); return sprintf(buf, %d\n, lis3lv02d_get_odr()); } @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev, if (strict_strtoul(buf, 0, rate)) return -EINVAL
Re: [PATCH 07/12] hwmon: lis3: New parameters to platform data
On 10/22/10 12:57, Samu Onkalo wrote: Added default output data rate setting to platform data. If default rate is 0, reset default value is used. Added control for duration via platform data. Added possibility to configure interrupts to trig on both rising and falling edge. The lis3 WU unit can be configured quite many ways and with some configurations it is quite handy to get coordinate refresh when some event trigs and when it reason goes away. Per patch description of what changed would have made reviewing easier (for lazy people like me ;) Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/hwmon/lis3lv02d.c | 21 ++--- include/linux/lis3lv02d.h |6 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index b44d4c5..d66cbe1 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, if (p-wakeup_flags) { dev-write(dev, FF_WU_CFG_1, p-wakeup_flags); dev-write(dev, FF_WU_THS_1, p-wakeup_thresh 0x7f); - /* default to 2.5ms for now */ - dev-write(dev, FF_WU_DURATION_1, 1); + /* pdata value + 1 to keep this backward compatible*/ + dev-write(dev, FF_WU_DURATION_1, p-duration1 + 1); ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ } if (p-wakeup_flags2) { dev-write(dev, FF_WU_CFG_2, p-wakeup_flags2); dev-write(dev, FF_WU_THS_2, p-wakeup_thresh2 0x7f); - /* default to 2.5ms for now */ - dev-write(dev, FF_WU_DURATION_2, 1); + /* pdata value + 1 to keep this backward compatible*/ + dev-write(dev, FF_WU_DURATION_2, p-duration2 + 1); ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ } /* Configure hipass filters */ @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, err = request_threaded_irq(p-irq2, NULL, lis302dl_interrupt_thread2_8b, - IRQF_TRIGGER_RISING | - IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_ONESHOT | + (p-irq_flags2 IRQF_TRIGGER_MASK), DRIVER_NAME, lis3_dev); if (err 0) printk(KERN_ERR DRIVER_NAME @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) { int err; irq_handler_t thread_fn; + int irq_flags = 0; dev-whoami = lis3lv02d_read_8(dev, WHO_AM_I); @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) if (dev-whoami == WAI_8B) lis3lv02d_8b_configure(dev, p); + irq_flags = p-irq_flags1 IRQF_TRIGGER_MASK; + dev-irq_cfg = p-irq_cfg; if (p-irq_cfg) dev-write(dev, CTRL_REG3, p-irq_cfg); + + if (p-default_rate) + lis3lv02d_set_odr(p-default_rate); } /* bail if we did not get an IRQ from the bus layer */ @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) err = request_threaded_irq(dev-irq, lis302dl_interrupt, thread_fn, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_ONESHOT | + irq_flags, DRIVER_NAME, lis3_dev); if (err 0) { diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index c4a4a52..18d578f 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data { #define LIS3_IRQ_OPEN_DRAIN (1 6) #define LIS3_IRQ_ACTIVE_LOW (1 7) unsigned char irq_cfg; - + unsigned char irq_flags1; /* Additional irq edge / level flags */ + unsigned char irq_flags2; /* Additional irq edge / level flags */ + unsigned char duration1; + unsigned char duration2; #define LIS3_WAKEUP_X_LO (1 0) #define LIS3_WAKEUP_X_HI (1 1) #define LIS3_WAKEUP_Y_LO (1 2) @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data { s8 axis_z; #define LIS3_USE_REGULATOR_CTRL 0x01 u16 driver_features; + int default_rate; int (*setup_resources)(void); int (*release_resources)(void); /* Limits for selftest are specified in chip data sheet */ -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http
Re: [PATCH 09/12] hwmon: lis3: use block read to access data registers
On 10/22/10 12:57, Samu Onkalo wrote: Add optional blockread function to interface driver. If available the chip driver uses it for data register access. For 12 bit device it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out 5 bytes since every second byte is dummy. This optimizes bus usage and reduces number of operations and interrupts needed for one data update. All good now. Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/hwmon/lis3lv02d.c | 21 ++--- drivers/hwmon/lis3lv02d.h |1 + drivers/hwmon/lis3lv02d_i2c.c | 13 + include/linux/lis3lv02d.h |1 + 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 7555091..9fd946c 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) int position[3]; int i; - position[0] = lis3-read_data(lis3, OUTX); - position[1] = lis3-read_data(lis3, OUTY); - position[2] = lis3-read_data(lis3, OUTZ); + if (lis3-blkread) { + if (lis3_dev.whoami == WAI_12B) { + u16 data[3]; + lis3-blkread(lis3, OUTX_L, 6, (u8 *)data); + for (i = 0; i 3; i++) + position[i] = (s16)le16_to_cpu(data[i]); + } else { + u8 data[5]; + /* Data: x, dummy, y, dummy, z */ + lis3-blkread(lis3, OUTX, 5, data); + for (i = 0; i 3; i++) + position[i] = (s8)data[i * 2]; + } + } else { + position[0] = lis3-read_data(lis3, OUTX); + position[1] = lis3-read_data(lis3, OUTY); + position[2] = lis3-read_data(lis3, OUTZ); + } for (i = 0; i 3; i++) position[i] = (position[i] * lis3-scale) / LIS3_ACCURACY; diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 2ac27b9..d3cb662 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -225,6 +225,7 @@ struct lis3lv02d { int (*init) (struct lis3lv02d *lis3); int (*write) (struct lis3lv02d *lis3, int reg, u8 val); int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); + int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret); int (*reg_ctrl) (struct lis3lv02d *lis3, bool state); int *odrs; /* Supported output data rates */ diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index 36171bf..61c109b 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c @@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v) return 0; } +static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len, + u8 *v) +{ + struct i2c_client *c = lis3-bus_priv; + reg |= (1 7); /* 7th bit enables address auto incrementation */ + return i2c_smbus_read_i2c_block_data(c, reg, len, v); +} + static int lis3_i2c_init(struct lis3lv02d *lis3) { u8 reg; @@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, if (pdata-driver_features LIS3_USE_REGULATOR_CTRL) lis3_dev.reg_ctrl = lis3_reg_ctrl; + if ((pdata-driver_features LIS3_USE_BLOCK_READ) + (i2c_check_functionality(client-adapter, + I2C_FUNC_SMBUS_I2C_BLOCK))) + lis3_dev.blkread = lis3_i2c_blockread; + if (pdata-axis_x) lis3lv02d_axis_map.x = pdata-axis_x; diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index 18d578f..c949612 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -68,6 +68,7 @@ struct lis3lv02d_platform_data { s8 axis_y; s8 axis_z; #define LIS3_USE_REGULATOR_CTRL 0x01 +#define LIS3_USE_BLOCK_READ 0x02 u16 driver_features; int default_rate; int (*setup_resources)(void); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields
On 10/22/10 12:57, Samu Onkalo wrote: Short documentation at kernel doc format. Please check the use of tabs etc in the alignment of the documentation. It might work out right, but looks a bit random currently. Couple of typos. Otherwise looks fine to me, but I'll only give a reviewed by on this as I really don't know the devices well enough! Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- include/linux/lis3lv02d.h | 41 + 1 files changed, 41 insertions(+), 0 deletions(-) diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index c949612..da294cd 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -1,6 +1,47 @@ #ifndef __LIS3LV02D_H_ #define __LIS3LV02D_H_ +/** + * struct lis3lv02d_platform_data - lis3 chip family platform data + * @click_flags: Click detection unit configuration + * @click_thresh_x:Click detection unit x axis treshold threshold + * @click_thresh_y:Click detection unit y axis treshold + * @click_thresh_z:Click detection unit z axis treshold + * @click_time_limit: Click detection unit time parameter + * @click_latency: Click detection unit latency parameter + * @click_window: Click detection unit window parameter + * @irq_cfg:On chip irq configuration (click / data available / wu) wu isn't a terribly helpful acronym, please put it in long hand. iirc kernel doc lets you use multiple lines for parameter descriptions... + * @irq_flags1: Additional irq triggering flags for irq channel 0 + * @irq_flags2: Additional irq triggering flags for irq channel 1 + * @duration1: Wake up unit 1 duration parameter + * @duration2: Wake up unit 2 duration parameter + * @wakeup_flags: Wakeup unit 1 flags + * @wakeup_thresh: Wakeup unit 1 threshold value + * @wakeup_flags2: Wakeup unit 2 flags + * @wakeup_thresh2:Wakeup unit 2 threshold value + * @hipass_ctrl: Hi-pass filter control High-pass + * @axis_x: Remap parameter for x-axis + * @axis_y: Remap parameter for y-axis + * @axis_z: Remap parameter for z-axis + * @driver_features: Enable bits for different features. Disabled by default + * @default_rate: Default sampling rate. 0 means reset default + * @setup_resources: Interrupt line setup call back function + * @release_resources: Interrupt line release call back function + * @st_min_limits[3]: Selftest acceptance minimum values + * @st_max_limits[3]: Selftest accepratnce maximum values acceptance + * @irq2: Irq line 2 number + * + * Platform data is used to setup the sensor chip. Meaning of the different + * chip features can be found from the data sheet. Currently the data is used + * only for the 8 bit device. The 8 bit device has two wake up / free fall + * detection units and click detection unit. There are plenty of ways to + * configure the chip which makes is quite impossible to explain meaning of the + * fields here. Behaviour of the detection blocks varies heavily depending + * on the configuration. Irq_flags can be used to enable interrupt detection + * on the both edges. With proper chip configuration this produces interrupt + * when some trigger starts and when it goes away. + */ + struct lis3lv02d_platform_data { /* please note: the 'click' feature is only supported for * LIS[32]02DL variants of the chip and will be ignored for -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V3] staging: iio: light: tmd27711: Add tmd27711 proximity and ambient light sensor driver
On 10/11/10 05:56, Donggeun Kim wrote: This driver supports TAOS TMD27711 and TMD27713 proximity and ambient light sensor. When threshold condition for proximity or ambient light sensor is satisfied, an event is generated. The proximity raw value is exported through the 'proximity_raw' attribute. This driver uses 'illuminance0_input' attribute to export lux value by calculating ch0 and ch1 ADC values. Just tested the merge This driver will merge into staging-next so it needs to apply and build against Greg's current tree. Another light sensor merged at the end of last week so you will need to rebase your patches to take into account the changes in Makefiles and Kconfig. Also, the way event codes are built changed with a patch set that merged at the end of last week. This means that a few changes will be needed there as well before merge. Sorry, IIO is pretty fast moving and so this happens from time to time with new drivers. Take a look at the work Analog have been doing to bring their driver set up to date to see how this bites us all from time to time! The necessary changes should be pretty trivial. I've put the event code bits inline. The merge issues should just be a cut and paste job. I've put a couple of other utterly trivial comments inline that I notticed as I was reading. Don't worry about those as the don't materially effect anything! Subject to fixing merge issues and updating the event codes, please add Acked-by: Jonathan Cameron ji...@cam.ac.uk Changes from V2 to V3: - The source file name is changed from tmd2771x to tmd27711. - The macros for generating set and get functions are removed. - Checking the device ID is fixed. - Address a race condition. Changes from V1 to V2: - I2C read and write wrapping functions are removed. - The error handling routines are inserted. - The similar functions are created by macro invocation. - Some attribute names are changed. - Some event attribute names are changed. - The comments are added to the code to explain the non standard attributes and fields of the platform data. Signed-off-by: Donggeun Kim dg77@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/staging/iio/light/Kconfig| 10 + drivers/staging/iio/light/Makefile |1 + drivers/staging/iio/light/tmd27711.c | 720 ++ drivers/staging/iio/light/tmd27711.h | 172 drivers/staging/iio/sysfs.h |3 + 5 files changed, 906 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/light/tmd27711.c create mode 100644 drivers/staging/iio/light/tmd27711.h diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index 3ddc478..f08ea5a 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -12,3 +12,13 @@ config SENSORS_TSL2563 This driver can also be built as a module. If so, the module will be called tsl2563. + +config SENSORS_TMD27711 + tristate TAOS TMD27711/TMD27713 proximity and ambient light sensor + depends on I2C + help + If you say yes here you get support for TAOS TMD27711, + TMD27713 proximity and ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called tmd27711. diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 30f3300..b6a0cdc 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_SENSORS_TSL2563)+= tsl2563.o +obj-$(CONFIG_SENSORS_TMD27711) += tmd27711.o diff --git a/drivers/staging/iio/light/tmd27711.c b/drivers/staging/iio/light/tmd27711.c new file mode 100644 index 000..0f5016c --- /dev/null +++ b/drivers/staging/iio/light/tmd27711.c @@ -0,0 +1,720 @@ +/* + * tmd27711.c - Texas Advanced Optoelectronic Solutions Inc. + *Proximity/Ambient light sensor + * + * Copyright (C) 2010 Samsung Electronics + * Donggeun Kim dg77@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/module.h +#include linux/init.h +#include linux/interrupt.h +#include linux/platform_device.h +#include linux/workqueue.h +#include linux/mutex.h +#include linux/err.h +#include linux/i2c.h +#include linux/delay.h +#include linux/slab.h +#include ../iio.h This has gone away (as it became empty!) +#include light.h +#include tmd27711.h + +struct tmd27711_chip { + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct work_thresh; + s64 last_timestamp; + struct mutex
Re: [PATCHv2 1/5] misc: Driver for bh1770glc / sfh7770 ALS and proximity sensor
On 10/11/10 07:16, Onkalo Samu wrote: I have a question about one of your comment On Fri, 2010-10-08 at 16:35 +0200, ext Jonathan Cameron wrote: On 10/08/10 14:42, Samu Onkalo wrote: This is a driver for ROHM BH1770GLC and OSRAM SFH7770 combined ALS and proximity sensor. Interface is sysfs based. The driver uses interrupts to provide new data. The driver supports pm_runtime and regulator frameworks. See Documentation/misc-devices/bhsfh.txt for details Couple of nitpicks / formatting suggestions inline. +/* chip-mutex is kept when this is called */ +static int bhsfh_lux_update_thresholds(struct bhsfh_chip *chip, + u16 threshold_hi, u16 threshold_lo) +{ + u8 data[4]; u8 data[4] = { threshold_hi, threshold_hi 8, threshold_lo, threshold_low 8}; and loose the below will give same result. What do you mean by that? Threshold_lo / threshold_hi parameters can be modified before they are stored to HW. + int ret; + + /* sysfs may call this when the chip is powered off */ + if (pm_runtime_suspended(chip-client-dev)) + return 0; + + /* + * Compensate threshold values with the correction factors if not + * set to minimum or maximum. + * Min max values disables interrupts. + */ + if (threshold_hi != BHSFH_LUX_RANGE threshold_hi != 0) + threshold_hi = bhsfh_lux_adjusted_to_raw(chip, threshold_hi); + + if (threshold_lo != BHSFH_LUX_RANGE threshold_lo != 0) + threshold_lo = bhsfh_lux_adjusted_to_raw(chip, threshold_lo); Code above can modify values. ah. Sorry, I was clearly half asleep when I reviewed this! + + if (chip-lux_thres_hi_onchip == threshold_hi + chip-lux_thres_lo_onchip == threshold_lo) + return 0; + + chip-lux_thres_hi_onchip = threshold_hi; + chip-lux_thres_lo_onchip = threshold_lo; + + data[0] = threshold_hi; + data[1] = threshold_hi 8; + data[2] = threshold_lo; + data[3] = threshold_lo 8; + + ret = i2c_smbus_write_i2c_block_data(chip-client, + BHSFH_ALS_TH_UP_0, + ARRAY_SIZE(data), + data); + return ret; +} + -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 2/5] misc: update bhsfh driver to Kconfig and Makefile
On 10/11/10 07:17, Onkalo Samu wrote: On Fri, 2010-10-08 at 16:25 +0200, ext Jonathan Cameron wrote: On 10/08/10 14:42, Samu Onkalo wrote: Compilation support for bhsfh driver Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/misc/Kconfig | 10 ++ drivers/misc/Makefile |1 + 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b743312..f2e8065 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -314,6 +314,16 @@ config SENSORS_BH1780 This driver can also be built as a module. If so, the module will be called bh1780gli. +config SENSORS_BHSFH + tristate BH1770GLC / SFH7770 combined ALS / Proximity sensor; + depends on I2C + ---help--- + Say Y here if you want to build a driver for BH1770GLC / SFH7770 + combined ambient light and proximity sensor chip + + To compile this driver as a module, choose M here: the + module will be called bhsfh. If unsure, say N here. + Really not keen on the naming. The above comment made me think this was a single chip integrating both of the parts. Reading the code makes it clear that they just share an interface. So please name it after one of them. Lots of reasons not to invent combined names like this. * non obvious thing to grep for. * 3rd part comes along with a different name. Do you change the driver name? So best bet is always just to pick a supported part and name the driver after that. The device table stuff and clear descriptions in kconfig will make it obvious what the part supports. ok, bhsfh.* bh1770glc.* What do you think, is it ok to still keep BHSFH in definitions and in function names? I'd say it's fine to leave function names alone. If anyone else cares, they can post a patch changing the lot. Jonathan config HMC6352 tristate Honeywell HMC6352 compass depends on I2C diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95..fd5a4b7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1)+= tifm_7xx1.o obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o +obj-$(CONFIG_SENSORS_BHSFH)+= bhsfh.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv3 1/5] misc: Driver for bh1770glc / sfh7770 ALS and proximity sensor
On 10/11/10 12:06, Samu Onkalo wrote: This is a driver for ROHM BH1770GLC and OSRAM SFH7770 combined ALS and proximity sensor. Interface is sysfs based. The driver uses interrupts to provide new data. The driver supports pm_runtime and regulator frameworks. See Documentation/misc-devices/bh1770glc.txt for details Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/misc/bh1770glc.c | 1413 + include/linux/i2c/bh1770glc.h | 53 ++ 2 files changed, 1466 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/bh1770glc.c ... -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv3 3/5] misc: Driver for APDS990X ALS and proximity sensors
On 10/11/10 12:06, Samu Onkalo wrote: This is a driver for Avago APDS990X combined ALS and proximity sensor. Interface is sysfs based. The driver uses interrupts to provide new data. The driver supports pm_runtime and regulator frameworks. See Documentation/misc-devices/apds990x.txt for details Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- drivers/misc/apds990x.c | 1295 ++ include/linux/i2c/apds990x.h | 79 +++ 2 files changed, 1374 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/apds990x.c create mode 100644 include/linux/i2c/apds990x.h -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv3 5/5] Documentation: Short descriptions for bh1770glc and apds990x drivers
On 10/11/10 12:06, Samu Onkalo wrote: Add short documentation for two ALS / proximity chip drivers. Couple of nitpicks. All in category of things to fix if you are respinning the patch for some other reason. Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk --- Documentation/misc-devices/apds990x.txt | 113 Documentation/misc-devices/bh1770glc.txt | 118 ++ 2 files changed, 231 insertions(+), 0 deletions(-) create mode 100644 Documentation/misc-devices/apds990x.txt create mode 100644 Documentation/misc-devices/bh1770glc.txt diff --git a/Documentation/misc-devices/apds990x.txt b/Documentation/misc-devices/apds990x.txt new file mode 100644 index 000..36b9e40 --- /dev/null +++ b/Documentation/misc-devices/apds990x.txt @@ -0,0 +1,113 @@ +Kernel driver apds990x +== + +Supported chips: +Avago APDS990X + +Data sheet: +Not freely available + +Author: +Samu Onkalo samu.p.onk...@nokia.com + +Description +--- + +APDS990x is a combined ambient light and proximity sensor. ALS and proximity +functionality are highly connected. ALS measurement path must be running +while the proximity functionality is enabled. + +ALS produces raw measurement values for two channels: Clear channel +(infrared + visible light) and IR only. However, threshold comparisons happen +using clear channel only. LUX value and the threshold level on the HW +might vary quite much depending the spectrum of the light source. + +Driver makes necessary conversions to both directions so that user handles +only LUX values. LUX value is calculated using information from the both +channels. HW threshold level is calculated from the given LUX value to match +with current type of the lightning. Sometimes inaccuracy of the estimations +lead to false interrupt, but that doesn't harm. + +ALS contains 4 different gain steps. Driver automatically +selects suitable gain step. After each measurement, reliability of the results +is estimated and new measurement is trigged if necessary. + +Platform data can provide tuned values to the conversion formulas if +values are known. Otherwise plain sensor default values are used. + +Proximity side is little bit simpler. There is no need for complex conversions. +It produces directly usable values. + +Driver controls chip operational state using pm_runtime framework. +Voltage regulators are controlled based on chip operational state. + +SYSFS +- + + +chip_id + RO - shows detected chip type and version + +power_state + RW - enable / disable chip. Uses counting logic + 1 enables the chip + 0 disables the chip +lux0_input + RO - measured LUX value + sysfs_notify called when threshold interrupt occurs + +lux0_sensor_range + RO - lux0_input max value. Actually never reaches since sensor tends + to saturate much before that. Real max value varies depending + on the light spectrum etc. + bonus blank line? + +lux0_rate + RW - measurement rate in Hz + +lux0_rate_avail + RO - supported measurement rates + +lux0_calibscale + RW - calibration value. Set to neutral value by default. + Output results are multiplied with calibscale / calibscale_default + value. + +lux0_calibscale_default + RO - neutral calibration value + +lux0_thresh_above_value + RW - HI level threshold value. All results above the value + trigs an interrupt. 65535 (i.e. sensor_range) disables the above + interrupt. + +lux0_thresh_below_value + RW - LO level threshold value. All results below the value + trigs an interrupt. 0 disables the below interrupt. + +prox0_raw + RO - measured proximity value + sysfs_notify called when threshold interrupt occurs + +prox0_sensor_range + RO - prox0_raw max value (1023) + +prox0_raw_en + RW - enable / disable proximity - uses counting logic + 1 enables the proximity + 0 disables the proximity + +prox0_reporting_mode + RW - trigger / periodic. In trigger mode the driver tells two possible + values: 0 or prox0_sensor_range value. 0 means no proximity, + 1023 means proximity. This causes minimal number of interrupts. + In periodic mode the driver reports all values above + prox0_thresh_above. This causes more interrupts, but it can give + _rough_ estimate about the distance. + +prox0_reporting_mode_avail + RO - accepted values to prox0_reporting_mode (trigger, periodic) + +prox0_thresh_above_value + RW - threshold level which trigs proximity events. + diff --git a/Documentation/misc-devices/bh1770glc.txt b/Documentation/misc-devices/bh1770glc.txt new file mode 100644 index 000..e98e756 --- /dev/null +++ b/Documentation/misc
Re: [PATCHv2 2/5] misc: update bhsfh driver to Kconfig and Makefile
On 10/08/10 14:42, Samu Onkalo wrote: Compilation support for bhsfh driver Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/misc/Kconfig | 10 ++ drivers/misc/Makefile |1 + 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b743312..f2e8065 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -314,6 +314,16 @@ config SENSORS_BH1780 This driver can also be built as a module. If so, the module will be called bh1780gli. +config SENSORS_BHSFH + tristate BH1770GLC / SFH7770 combined ALS / Proximity sensor; + depends on I2C + ---help--- + Say Y here if you want to build a driver for BH1770GLC / SFH7770 + combined ambient light and proximity sensor chip + + To compile this driver as a module, choose M here: the + module will be called bhsfh. If unsure, say N here. + Really not keen on the naming. The above comment made me think this was a single chip integrating both of the parts. Reading the code makes it clear that they just share an interface. So please name it after one of them. Lots of reasons not to invent combined names like this. * non obvious thing to grep for. * 3rd part comes along with a different name. Do you change the driver name? So best bet is always just to pick a supported part and name the driver after that. The device table stuff and clear descriptions in kconfig will make it obvious what the part supports. config HMC6352 tristate Honeywell HMC6352 compass depends on I2C diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95..fd5a4b7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_PHANTOM)+= phantom.o obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o +obj-$(CONFIG_SENSORS_BHSFH) += bhsfh.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 1/5] misc: Driver for bh1770glc / sfh7770 ALS and proximity sensor
On 10/08/10 14:42, Samu Onkalo wrote: This is a driver for ROHM BH1770GLC and OSRAM SFH7770 combined ALS and proximity sensor. Interface is sysfs based. The driver uses interrupts to provide new data. The driver supports pm_runtime and regulator frameworks. See Documentation/misc-devices/bhsfh.txt for details Couple of nitpicks / formatting suggestions inline. Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/misc/bhsfh.c | 1443 + include/linux/i2c/bhsfh.h | 42 ++ 2 files changed, 1485 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/bhsfh.c create mode 100644 include/linux/i2c/bhsfh.h diff --git a/drivers/misc/bhsfh.c b/drivers/misc/bhsfh.c new file mode 100644 index 000..e82fadb --- /dev/null +++ b/drivers/misc/bhsfh.c @@ -0,0 +1,1443 @@ +/* + * This file is part of the ROHM BH1770GLC / OSRAM SFH7770 sensor driver. + * Chip is combined proximity and ambient light sensor. + * + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Samu Onkalo samu.p.onk...@nokia.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/i2c.h +#include linux/interrupt.h +#include linux/mutex.h +#include linux/i2c/bhsfh.h +#include linux/regulator/consumer.h +#include linux/pm_runtime.h +#include linux/workqueue.h +#include linux/delay.h +#include linux/wait.h +#include linux/slab.h + +#define BHSFH_ALS_CONTROL0x80 /* ALS operation mode control */ +#define BHSFH_PS_CONTROL 0x81 /* PS operation mode control */ +#define BHSFH_I_LED 0x82 /* active LED and LED1, LED2 current */ +#define BHSFH_I_LED3 0x83 /* LED3 current setting */ +#define BHSFH_ALS_PS_MEAS0x84 /* Forced mode trigger */ +#define BHSFH_PS_MEAS_RATE 0x85 /* PS meas. rate at stand alone mode */ +#define BHSFH_ALS_MEAS_RATE 0x86 /* ALS meas. rate at stand alone mode */ +#define BHSFH_PART_ID0x8a /* Part number and revision ID */ +#define BHSFH_MANUFACT_ID0x8b /* Manufacturerer ID */ +#define BHSFH_ALS_DATA_0 0x8c /* ALS DATA low byte */ +#define BHSFH_ALS_DATA_1 0x8d /* ALS DATA high byte */ +#define BHSFH_ALS_PS_STATUS 0x8e /* Measurement data and int status */ +#define BHSFH_PS_DATA_LED1 0x8f /* PS data from LED1 */ +#define BHSFH_PS_DATA_LED2 0x90 /* PS data from LED2 */ +#define BHSFH_PS_DATA_LED3 0x91 /* PS data from LED3 */ +#define BHSFH_INTERRUPT 0x92 /* Interrupt setting */ +#define BHSFH_PS_TH_LED1 0x93 /* PS interrupt threshold for LED1 */ +#define BHSFH_PS_TH_LED2 0x94 /* PS interrupt threshold for LED2 */ +#define BHSFH_PS_TH_LED3 0x95 /* PS interrupt threshold for LED3 */ +#define BHSFH_ALS_TH_UP_00x96 /* ALS upper threshold low byte */ +#define BHSFH_ALS_TH_UP_10x97 /* ALS upper threshold high byte */ +#define BHSFH_ALS_TH_LOW_0 0x98 /* ALS lower threshold low byte */ +#define BHSFH_ALS_TH_LOW_1 0x99 /* ALS lower threshold high byte */ + +/* MANUFACT_ID */ +#define BHSFH_MANUFACT_ROHM 0x01 +#define BHSFH_MANUFACT_OSRAM 0x03 + +/* PART_ID */ +#define BHSFH_PART 0x90 +#define BHSFH_PART_MASK 0xf0 +#define BHSFH_REV_MASK 0x0f +#define BHSFH_REV_SHIFT 0 +#define BHSFH_REV_0 0x00 +#define BHSFH_REV_1 0x01 + +/* ALS_MEAS_RATE */ +#define BHSFH_ALS_MAX_RATE 9 + +/* PS_MEAS_RATE */ +#define BHSFH_PS_MAX_RATE4 + +/* Operating modes for both */ +#define BHSFH_STANDBY0x00 +#define BHSFH_FORCED 0x02 +#define BHSFH_STANDALONE 0x03 +#define BHSFH_SWRESET(0x01 2) + +#define BHSFH_PS_TRIG_MEAS (1 0) +#define BHSFH_ALS_TRIG_MEAS (1 1) + +/* Interrupt control */ +#define BHSFH_INT_OUTPUT_MODE(1 3) /* 0 = latched */ +#define BHSFH_INT_POLARITY (1 2) /* 1 = active high */ +#define BHSFH_INT_ALS_ENA(1 1) +#define BHSFH_INT_PS_ENA (1 0) + +/* Interrupt status */ +#define BHSFH_INT_LED1_DATA (1 0) +#define BHSFH_INT_LED1_INT (1 1) +#define BHSFH_INT_LED2_DATA (1 2) +#define BHSFH_INT_LED2_INT (1 3) +#define BHSFH_INT_LED3_DATA (1 4) +#define BHSFH_INT_LED3_INT (1 5) +#define BHSFH_INT_LEDS_INT ((1
Re: [PATCHv2 3/5] misc: Driver for APDS990X ALS and proximity sensors
On 10/08/10 14:42, Samu Onkalo wrote: This is a driver for Avago APDS990X combined ALS and proximity sensor. Interface is sysfs based. The driver uses interrupts to provide new data. The driver supports pm_runtime and regulator frameworks. See Documentation/misc-devices/apds990x.txt for details Couple of nitpicks inline based on a quick read. Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/misc/apds990x.c | 1303 ++ include/linux/i2c/apds990x.h | 58 ++ 2 files changed, 1361 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/apds990x.c create mode 100644 include/linux/i2c/apds990x.h diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c new file mode 100644 index 000..658c5c4 --- /dev/null +++ b/drivers/misc/apds990x.c @@ -0,0 +1,1303 @@ +/* + * This file is part of the APDS990x sensor driver. + * Chip is combined proximity and ambient light sensor. + * + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Samu Onkalo samu.p.onk...@nokia.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/i2c.h +#include linux/interrupt.h +#include linux/mutex.h +#include linux/regulator/consumer.h +#include linux/pm_runtime.h +#include linux/delay.h +#include linux/wait.h +#include linux/slab.h +#include linux/i2c/apds990x.h + +/* Register map */ +#define APDS990X_ENABLE 0x00 /* Enable of states and interrupts */ +#define APDS990X_ATIME0x01 /* ALS ADC time */ +#define APDS990X_PTIME0x02 /* Proximity ADC time */ +#define APDS990X_WTIME0x03 /* Wait time */ +#define APDS990X_AILTL0x04 /* ALS interrupt low threshold low byte */ +#define APDS990X_AILTH0x05 /* ALS interrupt low threshold hi byte */ +#define APDS990X_AIHTL0x06 /* ALS interrupt hi threshold low byte */ +#define APDS990X_AIHTH0x07 /* ALS interrupt hi threshold hi byte */ +#define APDS990X_PILTL0x08 /* Proximity interrupt low threshold low byte */ +#define APDS990X_PILTH0x09 /* Proximity interrupt low threshold hi byte */ +#define APDS990X_PIHTL0x0a /* Proximity interrupt hi threshold low byte */ +#define APDS990X_PIHTH0x0b /* Proximity interrupt hi threshold hi byte */ +#define APDS990X_PERS 0x0c /* Interrupt persistence filters */ +#define APDS990X_CONFIG 0x0d /* Configuration */ +#define APDS990X_PPCOUNT 0x0e /* Proximity pulse count */ +#define APDS990X_CONTROL 0x0f /* Gain control register */ +#define APDS990X_REV 0x11 /* Revision Number */ +#define APDS990X_ID 0x12 /* Device ID */ +#define APDS990X_STATUS 0x13 /* Device status */ +#define APDS990X_CDATAL 0x14 /* Clear ADC low data register */ +#define APDS990X_CDATAH 0x15 /* Clear ADC high data register */ +#define APDS990X_IRDATAL 0x16 /* IR ADC low data register */ +#define APDS990X_IRDATAH 0x17 /* IR ADC high data register */ +#define APDS990X_PDATAL 0x18 /* Proximity ADC low data register */ +#define APDS990X_PDATAH 0x19 /* Proximity ADC high data register */ + +/* Control */ +#define APDS990X_MAX_AGAIN 3 + +/* Enable register */ +#define APDS990X_EN_PIEN (0x1 5) +#define APDS990X_EN_AIEN (0x1 4) +#define APDS990X_EN_WEN (0x1 3) +#define APDS990X_EN_PEN (0x1 2) +#define APDS990X_EN_AEN (0x1 1) +#define APDS990X_EN_PON (0x1 0) +#define APDS990X_EN_DISABLE_ALL 0 + +/* Status register */ +#define APDS990X_ST_PINT (0x1 5) +#define APDS990X_ST_AINT (0x1 4) + +/* I2C access types */ +#define APDS990x_CMD_TYPE_MASK (0x03 5) +#define APDS990x_CMD_TYPE_RB (0x00 5) /* Repeated byte */ +#define APDS990x_CMD_TYPE_INC(0x01 5) /* Auto increment */ +#define APDS990x_CMD_TYPE_SPE(0x03 5) /* Special function */ + +#define APDS990x_ADDR_SHIFT 0 +#define APDS990x_CMD 0x80 + +/* Interrupt ack commands */ +#define APDS990X_INT_ACK_ALS 0x6 +#define APDS990X_INT_ACK_PS 0x5 +#define APDS990X_INT_ACK_BOTH0x7 + +/* ptime */ +#define APDS990X_PTIME_DEFAULT 0xff /* Recommended conversion time 2.7ms*/ + +/* wtime */ +#define
Re: [PATCH v4] iio: light: Adding driver for ISL29018 ALS
On 10/06/10 22:25, rkl...@nvidia.com wrote: From: Rhyland Klein rkl...@nvidia.com Adding support for the ISL 29018 ambient light and proximity sensor. Addressed comments from reviews by Jonathan Cameron and Joe Perches * Removed some excess dbg prints that only printed function name * Renamed some properties to make them more descriptive * Added a property to list available adc resolutions * Defined arrays for resolutions/ranges as static const * Change loops initialization to memset for extensibility. * used sizeof() instead of ARRAY_SIZE() to be safer * Added a property to list available adc ranges One typo in the documentation you will want to fix. Otherwise, I'm happy. Signed-off-by: Rhyland Klein rkl...@nvidia.com Acked-by: Jonathan Cameron ji...@cam.ac.uk Please send a copy to Greg KH g...@kroah.com for merging --- .../staging/iio/Documentation/sysfs-bus-iio-light | 64 +++ drivers/staging/iio/light/Kconfig | 11 + drivers/staging/iio/light/Makefile |1 + drivers/staging/iio/light/isl29018.c | 563 4 files changed, 639 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/Documentation/sysfs-bus-iio-light create mode 100755 drivers/staging/iio/light/isl29018.c diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light new file mode 100644 index 000..2f7d9c5 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light @@ -0,0 +1,64 @@ + +What:/sys/bus/iio/devices/device[n]/range +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + Hardware dependent ADC Full Scale Range used for some ambient + light sensors in calculating lux. + +What:/sys/bus/iio/devices/device[n]/range_available +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + Hardware dependent supported vales for ADC Full Scale Range. + +What:/sys/bus/iio/devices/device[n]/adc_resolution +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + Hardware dependent ADC resolution of the ambient light sensor + used in calculating the lux. + +What:/sys/bus/iio/devices/device[n]/adc_resolution_available +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + Hardware dependent list of possible values supported for the + adc_resolution of the given sensor. + +What:/sys/bus/iio/devices/device[n]/illuminance0[_input|_raw] +KernelVersion: 2.6.35 +Contact: linux-...@vger.kernel.org +Description: + This should return the calculated lux from the light sensor. If + it comes back in SI units, it should also inclue _input else it typo inclue - include. + should include _raw to signify it is not in SI units. + +What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_supression +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + Hardware dependent mode for an ALS device to calculate the value + in proximity mode. When this is enabled, then the device should + use a infrared sensor reading to remove infrared noise from the + proximity reading. If this is not enabled, the driver can still + do this calculation manually by reading the infrared sensor + value and doing the negation in sw. + +What:/sys/bus/iio/devices/device[n]/proximity[_input|_raw] +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + This property is supported by proximity sensors and should be + used to return the value of a reading by the sensor. If this + value is returned in SI units, it should also include _input + but if it is not, then it should include _raw. + +What: /sys/bus/iio/devices/device[n]/intensity_infrared[_input|_raw] +KernelVersion: 2.6.37 +Contact: linux-...@vger.kernel.org +Description: + This property is supported by sensors that have an infrared + sensing mode. This value should be the output from a reading + and if expressed in SI units, should include _input. If this + value is not in SI units, then it should include _raw. diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index 80cb6e5..36d8bbe 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -13,3 +13,14 @@ config SENSORS_TSL2563 This driver can also be built as a module. If so, the module will be called tsl2563
Re: [PATCH 5/5] Documentation: Short descriptions for bhsfh and apds990x drivers
On 10/05/10 10:42, Samu Onkalo wrote: Add short documentation for two ALS / proximity chip drivers. Hi Samu, Good to see the documentation as it makes commenting on naming etc far simpler. There are a lot of comments, but that's because you define a lot of new interfaces and as ever I'm interested in working out how to keep them clear and as relevant to as many parts as possible. For reference, a very similar device driver (capability wise) was proposed on linux-iio by Dongguen Kim. I don't personally care about the location of these drivers, but I do care about the interfaces. http://marc.info/?t=12845324101r=1w=2 [PATCH V2] staging: iio: tmd2771x: Add tmd2771x proximity and ambient light sensor driver Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- Documentation/misc-devices/apds990x.txt | 126 +++ Documentation/misc-devices/bhsfh.txt| 125 ++ 2 files changed, 251 insertions(+), 0 deletions(-) create mode 100644 Documentation/misc-devices/apds990x.txt create mode 100644 Documentation/misc-devices/bhsfh.txt diff --git a/Documentation/misc-devices/apds990x.txt b/Documentation/misc-devices/apds990x.txt new file mode 100644 index 000..edffbea --- /dev/null +++ b/Documentation/misc-devices/apds990x.txt @@ -0,0 +1,126 @@ +Kernel driver apds990x +== + +Supported chips: +Avago APDS990X + +Data sheet: +Not freely available + +Author: +Samu Onkalo samu.p.onk...@nokia.com + +Description +--- + +APDS990x is a combined ambient light and proximity sensor. ALS and proximity +functionality are highly connected. ALS measurement path must be running +while the proximity functionality is enabled. + +ALS produces only raw measurement values. Further processing is needed +to get sensible LUX values. Vice versa, HW threshold control has nothing +to do with LUX values. Threshold detection triggs to raw conversion values. +Driver makes necessary conversions to both directions so that user handles +only LUX values. ALS contains 4 different gain steps. Driver automatically +selects suitable gain step. After each measurement, reliability of the results +is estimated and new measurement is trigged if necessary. Nice. + +Platform data can provide tuned values to the conversion formulas if +values are known. Othervise plain sensor default values are used. Typo: Otherwise + +Proximity side is little bit simpler. It produces directly usable values. In what sense? What units are the values in? If they are raw values, I'd denote that in the attribute name (_raw rather than _input). + +Driver controls chip operational state using pm_runtime framework. +Voltage regulators are controlled based on chip operational state. + +SYSFS +- +chip_id + RO - shows detected chip type and version + +power_state + RW - enable / disable chip. Uses counting logic + 1 enables the chip + 0 disables the chip +lux0_input + RO - measured LUX value + range: 0 .. 65535 + sysfs_notify called when threshold interrupt occurs Personally I'm still in favour (for generality) of using illuminance0 rather than lux0 but I think the mass of drivers mean I'm losing that argument. (argument for those who haven't seen it before is that lux is the unit, the thing being measured is illuminance - units don't generalize to other sensor types e.g. acceleration) + +lux0_input10x + RO - Same as lux0_input but values are 10x larger so accuracy + is 0.1 lux + range: 0 .. 655350 Why do we care? Just do a bit of fixed point arithmetic and output it in lux0_input (yes hwmon is fussy about not having decimal places, I think everyone else is more flexible in cases like this). +lux0_rate + RW - measurement period in milliseconds Then it's not a rate is it. Please fix naming or what comes out. Rate = sampling frequency, not sampling period. + +lux0_rate_avail + RO - supported measurement periods + +lux0_calib + RW - calibration value. Set to neutral value by default That tells me nothing about what this parameter is. Please provide some info on this so we can work out a clearer naming convention. + +lux0_calib_format + RO - neutral calibration value + +lux0_threshold_range + RW - lo and hi threshold values like 100 1000 + range: 0 .. 65535 Are these conceptually one value... Maybe. I proposed an RFC with a general naming convention the other day. I'm happy to reopen that debate if you disagree, but do feel it is vital to pick a standard and keep to it. I've move iio to the conventions proposed in that discussion (on linux-iio for review at the moment). Under that convention this would be (I think, given I don't have the data sheet) lux0_input_thresh_rising_value lux0_input_thresh_falling_value For reference the naming convention discussion follows from
Re: [PATCH 5/5] Documentation: Short descriptions for bhsfh and apds990x drivers
On 10/05/10 13:22, Onkalo Samu wrote: Jonathan, thanks. -Samu On Tue, 2010-10-05 at 13:53 +0200, ext Jonathan Cameron wrote: On 10/05/10 10:42, Samu Onkalo wrote: Add short documentation for two ALS / proximity chip drivers. Hi Samu, Good to see the documentation as it makes commenting on naming etc far simpler. There are a lot of comments, but that's because you define a lot of new interfaces and as ever I'm interested in working out how to keep them clear and as relevant to as many parts as possible. For reference, a very similar device driver (capability wise) was proposed on linux-iio by Dongguen Kim. I don't personally care about the location of these drivers, but I do care about the interfaces. http://marc.info/?t=12845324101r=1w=2 [PATCH V2] staging: iio: tmd2771x: Add tmd2771x proximity and ambient light sensor driver Looks quite similar indeed. Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- Documentation/misc-devices/apds990x.txt | 126 +++ Documentation/misc-devices/bhsfh.txt| 125 ++ 2 files changed, 251 insertions(+), 0 deletions(-) create mode 100644 Documentation/misc-devices/apds990x.txt create mode 100644 Documentation/misc-devices/bhsfh.txt diff --git a/Documentation/misc-devices/apds990x.txt b/Documentation/misc-devices/apds990x.txt new file mode 100644 index 000..edffbea --- /dev/null +++ b/Documentation/misc-devices/apds990x.txt @@ -0,0 +1,126 @@ +Kernel driver apds990x +== + +Supported chips: +Avago APDS990X + +Data sheet: +Not freely available + +Author: +Samu Onkalo samu.p.onk...@nokia.com + +Description +--- + +APDS990x is a combined ambient light and proximity sensor. ALS and proximity +functionality are highly connected. ALS measurement path must be running +while the proximity functionality is enabled. + +ALS produces only raw measurement values. Further processing is needed +to get sensible LUX values. Vice versa, HW threshold control has nothing +to do with LUX values. Threshold detection triggs to raw conversion values. +Driver makes necessary conversions to both directions so that user handles +only LUX values. ALS contains 4 different gain steps. Driver automatically +selects suitable gain step. After each measurement, reliability of the results +is estimated and new measurement is trigged if necessary. Nice. + +Platform data can provide tuned values to the conversion formulas if +values are known. Othervise plain sensor default values are used. Typo: Otherwise + +Proximity side is little bit simpler. It produces directly usable values. In what sense? What units are the values in? If they are raw values, I'd denote that in the attribute name (_raw rather than _input). I'll change it to _raw. I just meant here that proximity doesn't need lot of conversions etc. to have usable values. Cool. That is what I thought you meant, just wanted to be sure. + +Driver controls chip operational state using pm_runtime framework. +Voltage regulators are controlled based on chip operational state. + +SYSFS +- +chip_id + RO - shows detected chip type and version + +power_state + RW - enable / disable chip. Uses counting logic + 1 enables the chip + 0 disables the chip +lux0_input + RO - measured LUX value + range: 0 .. 65535 + sysfs_notify called when threshold interrupt occurs Personally I'm still in favour (for generality) of using illuminance0 rather than lux0 but I think the mass of drivers mean I'm losing that argument. (argument for those who haven't seen it before is that lux is the unit, the thing being measured is illuminance - units don't generalize to other sensor types e.g. acceleration) I think Alan just got one driver queued with lux :) Yup, that was largely why I was giving up on the argument. I won it with als but as that never merged, the consensus is beating me this time ;) Its a small point anyway and I can always blame it on Alan if anyone points out it is inconsistent in the future :) + +lux0_input10x + RO - Same as lux0_input but values are 10x larger so accuracy + is 0.1 lux + range: 0 .. 655350 Why do we care? Just do a bit of fixed point arithmetic and output it in lux0_input (yes hwmon is fussy about not having decimal places, I think everyone else is more flexible in cases like this). %d.%d :) Exactly, might be hideous, but it does the job. +lux0_rate + RW - measurement period in milliseconds Then it's not a rate is it. Please fix naming or what comes out. Rate = sampling frequency, not sampling period. rate - period Snag there is that I don't think anyone is using period for this particular parameter... If it's easy I'd stick with rate or sampling frequency and output 1/rate If I'm wrong and for example Alan has used
Re: [lm-sensors] [RFC PATCH 6/9] hwmon: lis3: New parameters to platform data
On 10/01/10 12:46, Samu Onkalo wrote: Added control for duration via platform data. Added possibility to configure interrupts to trig on both rising and falling edge. The lis3 WU unit can be configured quite many ways and with some configurations it is quite handy to get coordinate refresh when some event trigs and when it reason goes away. There are probably cleaner ways of doing this. For example rather than creating your own data types, why not just have platform data eleemnts that are exactly the irq_flags you want? Or perhaps use resource structures instead? Looks like there is some irq type support in ioport.h and a few users in tree... Still, patch is sound except for the random last addition that has nothing to do with this. I'd like to seem some explanatory documentation in the platform data talking about why you would want to do this though... (actual examples please) Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/hwmon/lis3lv02d.c | 21 ++--- include/linux/lis3lv02d.h |7 ++- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 81e2313..0a46a0e 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -681,6 +681,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, { int err; int ctrl2 = p-hipass_ctrl; + int irq_flags = IRQF_TRIGGER_RISING | IRQF_ONESHOT; if (p-click_flags) { dev-write(dev, CLICK_CFG, p-click_flags); @@ -703,27 +704,29 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, if (p-wakeup_flags) { dev-write(dev, FF_WU_CFG_1, p-wakeup_flags); dev-write(dev, FF_WU_THS_1, p-wakeup_thresh 0x7f); - /* default to 2.5ms for now */ - dev-write(dev, FF_WU_DURATION_1, 1); + /* pdata value + 1 to keep this backward compatible*/ + dev-write(dev, FF_WU_DURATION_1, p-duration1 + 1); ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ } if (p-wakeup_flags2) { dev-write(dev, FF_WU_CFG_2, p-wakeup_flags2); dev-write(dev, FF_WU_THS_2, p-wakeup_thresh2 0x7f); - /* default to 2.5ms for now */ - dev-write(dev, FF_WU_DURATION_2, 1); + /* pdata value + 1 to keep this backward compatible*/ + dev-write(dev, FF_WU_DURATION_2, p-duration2 + 1); ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ } /* Configure hipass filters */ dev-write(dev, CTRL_REG2, ctrl2); + if (p-irq_flags LIS3_IRQ2_USE_BOTH_EDGES) + irq_flags |= IRQF_TRIGGER_FALLING; + if (p-irq2) { err = request_threaded_irq(p-irq2, NULL, lis302dl_interrupt_thread2_8b, - IRQF_TRIGGER_RISING | - IRQF_ONESHOT, + irq_flags, DRIVER_NAME, lis3_dev); if (err 0) printk(KERN_ERR DRIVER_NAME @@ -739,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) { int err; irq_handler_t thread_fn; + int irq_flags = IRQF_TRIGGER_RISING | IRQF_ONESHOT; dev-whoami = lis3lv02d_read_8(dev, WHO_AM_I); @@ -799,6 +803,9 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) if (dev-whoami == WAI_8B) lis3lv02d_8b_configure(dev, p); + if (dev-pdata-irq_flags LIS3_IRQ1_USE_BOTH_EDGES) + irq_flags |= IRQF_TRIGGER_FALLING; + dev-irq_cfg = p-irq_cfg; if (p-irq_cfg) dev-write(dev, CTRL_REG3, p-irq_cfg); @@ -829,7 +836,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) err = request_threaded_irq(dev-irq, lis302dl_interrupt, thread_fn, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + irq_flags, DRIVER_NAME, lis3_dev); if (err 0) { diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index 0e8a346..167f947 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -36,13 +36,18 @@ struct lis3lv02d_platform_data { #define LIS3_IRQ_OPEN_DRAIN (1 6) #define LIS3_IRQ_ACTIVE_LOW (1 7) unsigned char irq_cfg; - +#define LIS3_IRQ1_USE_BOTH_EDGES 1 +#define LIS3_IRQ2_USE_BOTH_EDGES 2 + unsigned char irq_flags; + unsigned char duration1; + unsigned char duration2; #define LIS3_WAKEUP_X_LO (1 0) #define LIS3_WAKEUP_X_HI (1 1) #define LIS3_WAKEUP_Y_LO (1 2) #define LIS3_WAKEUP_Y_HI (1 3) #define LIS3_WAKEUP_Z_LO (1 4)
Re: [lm-sensors] [RFC PATCH 8/9] hwmon: lis3: use block read to access data registers
On 10/01/10 12:46, Samu Onkalo wrote: Add optional blockread function to interface driver. If available the chip driver uses it for data register access. For 12 bit device it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out 5 bytes since every second byte is dummy. This optimizes bus usage and reduces number of operations and interrupts needed for one data update. Do we need to query if the i2c bus supports block reading or are they all guaranteed to do so? I'm guessing not seeing as i2c.h has a functionality bit for it... I2C_FUNC_SMBUS_READ_BLOCK_DATA Otherwise looks good. Either justify that all i2c buses will work or add the functionality check and you can add. Acked-by: Jonathan Cameron ji...@cam.ac.uk Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/hwmon/lis3lv02d.c | 21 ++--- drivers/hwmon/lis3lv02d.h |1 + drivers/hwmon/lis3lv02d_i2c.c |9 + 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index b740024..469f251 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -129,9 +129,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) int position[3]; int i; - position[0] = lis3-read_data(lis3, OUTX); - position[1] = lis3-read_data(lis3, OUTY); - position[2] = lis3-read_data(lis3, OUTZ); + if (lis3-blkread) { + if (lis3_dev.whoami == WAI_12B) { + u16 data[3]; + lis3-blkread(lis3, OUTX_L, 6, (u8 *)data); + for (i = 0; i 3; i++) + position[i] = (s16)le16_to_cpu(data[i]); + } else { + u8 data[5]; + /* Data: x, dummy, y, dummy, z */ + lis3-blkread(lis3, OUTX, 5, data); + for (i = 0; i 3; i++) + position[i] = (s8)data[i * 2]; + } + } else { + position[0] = lis3-read_data(lis3, OUTX); + position[1] = lis3-read_data(lis3, OUTY); + position[2] = lis3-read_data(lis3, OUTZ); + } for (i = 0; i 3; i++) position[i] = (position[i] * lis3-scale) / LIS3_ACCURACY; diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 1522855..cfff63c 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -232,6 +232,7 @@ struct lis3lv02d { int (*init) (struct lis3lv02d *lis3); int (*write) (struct lis3lv02d *lis3, int reg, u8 val); int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); + int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret); int (*reg_ctrl) (struct lis3lv02d *lis3, bool state); int *odrs; /* Supported output data rates */ diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index c5a60e4..1e0673b 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c @@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v) return 0; } +static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len, + u8 *v) +{ + struct i2c_client *c = lis3-bus_priv; + reg |= (1 7); /* 7th bit enables address auto incrementation */ + return i2c_smbus_read_i2c_block_data(c, reg, len, v); +} + static int lis3_i2c_init(struct lis3lv02d *lis3) { u8 reg; @@ -125,6 +133,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, lis3_dev.bus_priv = client; lis3_dev.init = lis3_i2c_init; lis3_dev.read = lis3_i2c_read; + lis3_dev.blkread = lis3_i2c_blockread; lis3_dev.write= lis3_i2c_write; lis3_dev.reg_ctrl = lis3_reg_ctrl; lis3_dev.irq = client-irq; -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [lm-sensors] [RFC PATCH 1/9] hwmon: lis3: pm_runtime support
On 10/03/10 06:03, Onkalo Samu wrote: Thanks for comments. On Sat, 2010-10-02 at 19:14 +0200, ext Jonathan Cameron wrote: On 10/01/10 12:46, Samu Onkalo wrote: Add pm_runtime support to lis3 core driver. Add pm_runtime support to lis3 i2c driver. spi and hp_accel drivers are not yet supported. Old always on functionality remains for those. For sysfs there is 5 second delay before turning off the chip to avoid long ramp up delay. I'm not overly familiar with the runtime stuff so looking at this based on a quick read of their documentation. Note I'm also not that familiar with the driver :) One real query about the logic in lis3lv02d_i2c_resume. My reading is that if we are runtime suspended when coming out of a system suspend then we don't want to power up the chip? However I'm not entirely sure how the two types of power management interact so sorry if I have completely misunderstood this! It took some time understand how this system works over the system level suspend. And depending on the use, lis3 chip can be kept active or powered down over the system standby :) The answer below covers my query (and is a handy thing to know about in general so thanks for that!) I'll certainly be copying this code for some of my drivers when I have the time to play with runtime pm. Acked-by: Jonathan Cameron ji...@cam.ac.uk Jonathan Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/hwmon/lis3lv02d.c | 59 + drivers/hwmon/lis3lv02d.h |1 + drivers/hwmon/lis3lv02d_i2c.c | 48 + 3 files changed, 96 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index fc591ae..eaa5bf0 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -34,6 +34,7 @@ #include linux/freezer.h #include linux/uaccess.h #include linux/miscdevice.h +#include linux/pm_runtime.h #include asm/atomic.h #include lis3lv02d.h @@ -43,6 +44,9 @@ #define MDPS_POLL_INTERVAL 50 #define MDPS_POLL_MIN 0 #define MDPS_POLL_MAX 2000 + +#define SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */ Name is rather generic... + /* * The sensor can also generate interrupts (DRDY) but it's pretty pointless * because they are generated even if the data do not change. So it's better @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) mutex_unlock(lis3_dev.mutex); } +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) +{ + if (lis3_dev.pm_dev) + pm_runtime_get_sync(lis3_dev.pm_dev); +} + +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) +{ + if (lis3_dev.pm_dev) + pm_runtime_put(lis3_dev.pm_dev); +} + static irqreturn_t lis302dl_interrupt(int irq, void *dummy) { if (!test_bit(0, lis3_dev.misc_opened)) @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) if (test_and_set_bit(0, lis3_dev.misc_opened)) return -EBUSY; /* already open */ + if (lis3_dev.pm_dev) + pm_runtime_get_sync(lis3_dev.pm_dev); + atomic_set(lis3_dev.count, 0); return 0; } @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { fasync_helper(-1, file, 0, lis3_dev.async_queue); clear_bit(0, lis3_dev.misc_opened); /* release the device */ + if (lis3_dev.pm_dev) + pm_runtime_put(lis3_dev.pm_dev); return 0; } @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void) return -ENOMEM; lis3_dev.idev-poll = lis3lv02d_joystick_poll; + lis3_dev.idev-open = lis3lv02d_joystick_open; + lis3_dev.idev-close = lis3lv02d_joystick_close; lis3_dev.idev-poll_interval = MDPS_POLL_INTERVAL; lis3_dev.idev-poll_interval_min = MDPS_POLL_MIN; lis3_dev.idev-poll_interval_max = MDPS_POLL_MAX; @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void) EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); /* Sysfs stuff */ +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3) +{ + /* +* SYSFS functions are fast visitors so put-call +* immediately after the get-call. However, keep +* chip running for a while and schedule delayed +* suspend. This way periodic sysfs calls doesn't +* suffer from relatively long power up time. +*/ + + if (lis3_dev.pm_dev) { + pm_runtime_get_sync(lis3-pm_dev); + pm_runtime_put_noidle(lis3-pm_dev); + pm_schedule_suspend(lis3-pm_dev, SYSFS_POWERDOWN_DELAY); + } +} + static ssize_t lis3lv02d_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { int result; s16 values[3]; + lis3lv02d_sysfs_poweron(lis3_dev); result = lis3lv02d_selftest(lis3_dev, values
Re: [lm-sensors] [RFC PATCH 2/9] hwmon: lis3: regulator control
... subtle change here... Out of intererst, why did the top level lis3_dev structure ever exist? (you can tell I haven't looked closely at this driver before!) Can remove_fs return an error? Remove fs returns always 0. There are couple of bigger changes which somebody should do to this driver: - Change static lis3_dev structure to a dynamically allocated one//generalize Definitely. - Add proper error handling to the driver. Agreed, hopefully someone will step up and do it (good job for a starting out kernel dev perhaps?) -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [lm-sensors] [RFC PATCH 0/9] lis3 accelerator feature update
On 10/02/10 09:25, Jean Delvare wrote: Hi Guenter, On Fri, 1 Oct 2010 19:53:11 -0700, Guenter Roeck wrote: On Fri, Oct 01, 2010 at 07:46:47AM -0400, Samu Onkalo wrote: This patch set is done to top of 2.6.36-RC5 Changes are tested only with I2C interface using 8bit sensor since I don't have other possibilities. I send this as RFC since changes may affect functionalities or use cases which I can't test or I don't know to exist. Wonder if there is a better mailing list to get good (or even any) feedback for this patchset. Even though the driver resides in the hwmon directory, it isn't really a hardware monitoring driver. Neither i2c nor hwmon fits well. Ideas, anyone ? cc lkml? These are very much device specific so only people who can really review are those who actually have the part or don't mind spending a fair bit of time familiarizing themselves with a fairly complex driver. Perhaps runtime pm ones want to go to the runtime pm guys? That bit isn't really subsystem specific. I'm quite keen to drive that stuff into some of my drivers, but haven't done it yet so am not familiar enough with the infrastructure. In an ideal world, people interested in accelerometers would create a subsystem for it, declare themselves maintainers of it, and all accelerometer drivers which currently leave under drivers/hwmon (hdaps, hp_accel, lis3lv02d and maybe ams) would be moved there. Agreed. The current state is very bad, because these drivers are located in a maintained subsystem but they don't belong there. This is what motivated my request to move these drivers away [1]. But as you can see nobody replied. Dmitry often takes a little while to reply, so I wouldn't give up hope yet. Sadly, despite numerous people wading in from time to time to tell use we are doing it all wrong, those who actually are interested day to day in these sorts of devices are far too thin on the ground. Personally, if no one responds from input, I'd just push this driver into misc asap. Can't seen anyone objecting to that. [1] http://www.spinics.net/lists/linux-input/msg11411.html -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [lm-sensors] [RFC PATCH 1/9] hwmon: lis3: pm_runtime support
On 10/01/10 12:46, Samu Onkalo wrote: Add pm_runtime support to lis3 core driver. Add pm_runtime support to lis3 i2c driver. spi and hp_accel drivers are not yet supported. Old always on functionality remains for those. For sysfs there is 5 second delay before turning off the chip to avoid long ramp up delay. I'm not overly familiar with the runtime stuff so looking at this based on a quick read of their documentation. Note I'm also not that familiar with the driver :) One real query about the logic in lis3lv02d_i2c_resume. My reading is that if we are runtime suspended when coming out of a system suspend then we don't want to power up the chip? However I'm not entirely sure how the two types of power management interact so sorry if I have completely misunderstood this! Jonathan Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com --- drivers/hwmon/lis3lv02d.c | 59 + drivers/hwmon/lis3lv02d.h |1 + drivers/hwmon/lis3lv02d_i2c.c | 48 + 3 files changed, 96 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index fc591ae..eaa5bf0 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -34,6 +34,7 @@ #include linux/freezer.h #include linux/uaccess.h #include linux/miscdevice.h +#include linux/pm_runtime.h #include asm/atomic.h #include lis3lv02d.h @@ -43,6 +44,9 @@ #define MDPS_POLL_INTERVAL 50 #define MDPS_POLL_MIN 0 #define MDPS_POLL_MAX 2000 + +#define SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */ Name is rather generic... + /* * The sensor can also generate interrupts (DRDY) but it's pretty pointless * because they are generated even if the data do not change. So it's better @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) mutex_unlock(lis3_dev.mutex); } +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) +{ + if (lis3_dev.pm_dev) + pm_runtime_get_sync(lis3_dev.pm_dev); +} + +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) +{ + if (lis3_dev.pm_dev) + pm_runtime_put(lis3_dev.pm_dev); +} + static irqreturn_t lis302dl_interrupt(int irq, void *dummy) { if (!test_bit(0, lis3_dev.misc_opened)) @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) if (test_and_set_bit(0, lis3_dev.misc_opened)) return -EBUSY; /* already open */ + if (lis3_dev.pm_dev) + pm_runtime_get_sync(lis3_dev.pm_dev); + atomic_set(lis3_dev.count, 0); return 0; } @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { fasync_helper(-1, file, 0, lis3_dev.async_queue); clear_bit(0, lis3_dev.misc_opened); /* release the device */ + if (lis3_dev.pm_dev) + pm_runtime_put(lis3_dev.pm_dev); return 0; } @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void) return -ENOMEM; lis3_dev.idev-poll = lis3lv02d_joystick_poll; + lis3_dev.idev-open = lis3lv02d_joystick_open; + lis3_dev.idev-close = lis3lv02d_joystick_close; lis3_dev.idev-poll_interval = MDPS_POLL_INTERVAL; lis3_dev.idev-poll_interval_min = MDPS_POLL_MIN; lis3_dev.idev-poll_interval_max = MDPS_POLL_MAX; @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void) EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); /* Sysfs stuff */ +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3) +{ + /* + * SYSFS functions are fast visitors so put-call + * immediately after the get-call. However, keep + * chip running for a while and schedule delayed + * suspend. This way periodic sysfs calls doesn't + * suffer from relatively long power up time. + */ + + if (lis3_dev.pm_dev) { + pm_runtime_get_sync(lis3-pm_dev); + pm_runtime_put_noidle(lis3-pm_dev); + pm_schedule_suspend(lis3-pm_dev, SYSFS_POWERDOWN_DELAY); + } +} + static ssize_t lis3lv02d_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { int result; s16 values[3]; + lis3lv02d_sysfs_poweron(lis3_dev); result = lis3lv02d_selftest(lis3_dev, values); return sprintf(buf, %s %d %d %d\n, result == 0 ? OK : FAIL, values[0], values[1], values[2]); @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev, { int x, y, z; + lis3lv02d_sysfs_poweron(lis3_dev); mutex_lock(lis3_dev.mutex); lis3lv02d_get_xyz(lis3_dev, x, y, z); mutex_unlock(lis3_dev.mutex); @@ -549,6 +591,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev, if (strict_strtoul(buf, 0, rate))
Re: [lm-sensors] [RFC PATCH 5/9] hwmon: lis3: Power on corrections
On 10/01/10 12:46, Samu Onkalo wrote: Sometimes lis3 chip seems to fail to setup factory tuning at boot up. This probably happens if there is some odd power ramp down ramp up sequence for example in device restart. Set boot bit in control2 register to trig boot sequence manually and wait until it is finished. Also restore axis enable bits in init. This really ought to be two separate patches. The issues are completely unconnected. I've noticed you tend to fix other things in individual patches as you go along. This makes the harder to review so please break out each conceptual change. Both look fine to me, so feel free to add Acked-by: Jonathan Cameron ji...@cam.ac.uk To a broken out pair of patches. Signed-off-by: Samu O kalo samu.p.onk...@nokia.com --- drivers/hwmon/lis3lv02d.c | 19 +++ drivers/hwmon/lis3lv02d.h |1 + drivers/hwmon/lis3lv02d_i2c.c |2 +- drivers/hwmon/lis3lv02d_spi.c |2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index dc777d2..81e2313 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -272,19 +272,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) lis3-init(lis3); - /* LIS3 power on delay is quite long */ - msleep(lis3-pwron_delay / lis3lv02d_get_odr()); - /* * Common configuration * BDU: (12 bits sensors only) LSB and MSB values are not updated until * both have been read. So the value read will always be correct. + * Set BOOT bit to refresh factory tuning values. */ - if (lis3-whoami == WAI_12B) { - lis3-read(lis3, CTRL_REG2, reg); - reg |= CTRL2_BDU; - lis3-write(lis3, CTRL_REG2, reg); - } + lis3-read(lis3, CTRL_REG2, reg); + if (lis3-whoami == WAI_12B) + reg |= CTRL2_BDU | CTRL2_BOOT; + else + reg |= CTRL2_BOOT_8B; + lis3-write(lis3, CTRL_REG2, reg); + + /* LIS3 power on delay is quite long */ + msleep(lis3-pwron_delay / lis3lv02d_get_odr()); + if (lis3-reg_ctrl) lis3_context_restore(lis3); } diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 8c19185..1522855 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -142,6 +142,7 @@ enum lis3lv02d_ctrl2 { enum lis302d_ctrl2 { HP_FF_WU2 = 0x08, HP_FF_WU1 = 0x04, + CTRL2_BOOT_8B = 0x40, }; enum lis3lv02d_ctrl3 { diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index 0852bed..c5a60e4 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c @@ -82,7 +82,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3) if (ret 0) return ret; - reg |= CTRL1_PD0; + reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen; return lis3-write(lis3, CTRL_REG1, reg); } diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c index b9be5e3..778885d 100644 --- a/drivers/hwmon/lis3lv02d_spi.c +++ b/drivers/hwmon/lis3lv02d_spi.c @@ -50,7 +50,7 @@ static int lis3_spi_init(struct lis3lv02d *lis3) if (ret 0) return ret; - reg |= CTRL1_PD0; + reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen; return lis3-write(lis3, CTRL_REG1, reg); } -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1] iio: light: Adding driver for ISL29018 ALS
On 10/01/10 01:23, rkl...@nvidia.com wrote: From: Rhyland Klein rkl...@nvidia.com Hi Rhyland, please cc linux-...@vger.kernel.org for IIO drivers (I've added it here). As a heads up to IIO people, this driver introduces a few new attributes that need pinning down. I've also cc'd Dongguen as he proposed a driver for a similar part a few weeks back. (speaking of which, is there any reason that hasn't gone to Greg as yet? The remaining comments were pretty minor.) Nice clean driver. Most of my comments are to do with the userspace interfaces. Sorry if I appear rather picky, but remember I am trying to enforce consistent interfaces across a range of extremely varied sensors. As with nearly every driver at the moment, yours has a few cases we haven't seen before. Now, as IIO is in staging, we are still fairly lax about what needs to be done before a merge. Hence you are welcome to send this on to Greg as is and abi cleanups can occur after that. However, if you are willing there are a few things I would definitely like cleaned up or clarified before merging. These are all pretty trivial. * The proximity_scheme attribute - this is a classic magic number attribute. Please rename it so a user can find out what it is doing without reading the datasheet. The binary input is fine given there are only two options (otherwise I'd insist on informative strings inside the file!) * add _input to all attributes in SI units and if they are in any form of raw unit, _raw. * rename the infrared and proximity attributes as per current drivers. * not all resolutions are supported, so even ignoring the fact that I'd prefer a _type attribute, I definitely want a way of userspace finding out what resolutions are allowed! So if you keep your current naming, a resolution_available attribute is a must. There is also a slight excess of debugging in here for a driver being merged, but that's personal taste! Thanks, Jonathan Adding support for the ISL 29018 ambient light and proximity sensor. Signed-off-by: Rhyland Klein rkl...@nvidia.com --- drivers/staging/iio/light/Kconfig| 11 + drivers/staging/iio/light/Makefile |1 + drivers/staging/iio/light/isl29018.c | 565 ++ 3 files changed, 577 insertions(+), 0 deletions(-) create mode 100755 drivers/staging/iio/light/isl29018.c diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index 80cb6e5..09113e4 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -13,3 +13,14 @@ config SENSORS_TSL2563 This driver can also be built as a module. If so, the module will be called tsl2563. +config SENSORS_ISL29018 +tristate ISL 29018 light and proximity sensor +depends on I2C +default n +help + If you say yes here you get support for ambient light sensing and + proximity ir sensing from Intersil ISL29018. worth ir-infrared here? Would make the help more consistent. + This driver will provide the measurements of ambient light intensity + in lux, proximity infrared sensing and normal infrared sensing. + Data from sensor is accessible via sysfs. + diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 30f3300..9142c0e 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_SENSORS_TSL2563)+= tsl2563.o +obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c new file mode 100755 index 000..453a419 --- /dev/null +++ b/drivers/staging/iio/light/isl29018.c @@ -0,0 +1,565 @@ +/* + * A iio driver for the light sensor ISL 29018. iio - IIO (again for consistency - either option is fine with me!) + * + * IIO driver for monitoring ambient light intensity in luxi, proximity + * sensing and infrared sensing. + * + * Copyright (c) 2010, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include linux/module.h +#include linux/i2c.h +#include linux/err.h +#include linux/mutex.h +#include linux/delay.h
Re: [PATCH 1/2] Add ALS drivers for the apds9802als
Hi Alan, Looks pretty clean to me. Comments inline on attribute formats and name of attributes. I'd like to see the range setting moved over to values in lux as you have done for the read back. The naming issue is just a suggestion that might make things a little clearer. Thanks, Jonathan From: anantha anantha.naraya...@intel.com This adds support for the ADPS9802ALS sensor. Cleanup by Alan Cox - move mutexes to cover more things - report I/O errors back to user space - report range and values in LUX Signed-off-by: Anantha Narayanan anantha.naraya...@intel.com Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/misc/Kconfig | 10 + drivers/misc/Makefile |1 drivers/misc/apds9802als.c | 303 3 files changed, 314 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/apds9802als.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 53b21ff..d6ec9ce 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -293,6 +293,16 @@ config SGI_GRU_DEBUG This option enables addition debugging code for the SGI GRU driver. If you are unsure, say N. +config APDS9802ALS + tristate Medfield Avago APDS9802 ALS Sensor module + depends on I2C + help + If you say yes here you get support for the ALS APDS9802 ambient + light sensor. + + This driver can also be built as a module. If so, the module + will be called apds9802als. + config ISL29003 tristate Intersil ISL29003 ambient light sensor depends on I2C SYSFS diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 4c771a2..0e5f2a5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SGI_XP)+= sgi-xp/ obj-$(CONFIG_SGI_GRU)+= sgi-gru/ obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o obj-$(CONFIG_HP_ILO) += hpilo.o +obj-$(CONFIG_APDS9802ALS)+= apds9802als.o obj-$(CONFIG_ISL29003) += isl29003.o obj-$(CONFIG_SENSORS_TSL2550)+= tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c new file mode 100644 index 000..cfd004a --- /dev/null +++ b/drivers/misc/apds9802als.c @@ -0,0 +1,303 @@ +/* + * apds9802als.c - apds9802 ALS Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~ + * + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/err.h +#include linux/delay.h +#include linux/mutex.h +#include linux/sysfs.h +#include linux/hwmon-sysfs.h + +#define ALS_MIN_RANGE_VAL 1 +#define ALS_MAX_RANGE_VAL 2 +#define POWER_STA_ENABLE 1 +#define POWER_STA_DISABLE 0 +#define APDS9802ALS_I2C_ADDR 0x29 + +#define DRIVER_NAME apds9802als + +struct als_data { + struct device *hwmon_dev; + bool needresume; + struct mutex mutex; +}; + +static ssize_t als_sensing_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + int val; + + val = i2c_smbus_read_byte_data(client, 0x81); + if (val 0) + return val; + if (val 1) + return sprintf(buf, 4000\n); + else + return sprintf(buf, 64000\n); +} + +static ssize_t als_lux_output_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct als_data *data = i2c_get_clientdata(client); + unsigned int ret_val; + int temp; + + /* Protect against parallel reads */ + mutex_lock(data-mutex); + temp = i2c_smbus_read_byte_data(client, 0x8C);/*LSB data*/ + if (temp 0) { + ret_val = temp; + goto failed; + } + ret_val = i2c_smbus_read_byte_data(client, 0x8D);/*MSB data*/ + if (ret_val 0) + goto failed; + mutex_unlock(data-mutex); +
Re: [PATCH] Add ALS drivers for the apds9802als
On 09/28/10 15:18, Alan Cox wrote: From: anantha anantha.naraya...@intel.com This adds support for the ADPS9802ALS sensor. Hi Alan, One last point, hwmon equivalent syntax for the naming would be lux0_input rather than the lux_input0 you have here. I'm still not keen on the lack of association between sensing range and what it is of, but then we don't have a unified naming convention for this as yet. Cleanup by Alan Cox - move mutexes to cover more things - report I/O errors back to user space - report range and values in LUX Signed-off-by: Anantha Narayanan anantha.naraya...@intel.com [The 4K and 64K in the hw spec acutally means 4095 (12bit) and 65535 (16bit).] Signed-off-by: Hong Liu hong@intel.com Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/misc/Kconfig | 10 + drivers/misc/Makefile |1 drivers/misc/apds9802als.c | 308 3 files changed, 319 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/apds9802als.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 53b21ff..d6ec9ce 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -293,6 +293,16 @@ config SGI_GRU_DEBUG This option enables addition debugging code for the SGI GRU driver. If you are unsure, say N. +config APDS9802ALS + tristate Medfield Avago APDS9802 ALS Sensor module + depends on I2C + help + If you say yes here you get support for the ALS APDS9802 ambient + light sensor. + + This driver can also be built as a module. If so, the module + will be called apds9802als. + config ISL29003 tristate Intersil ISL29003 ambient light sensor depends on I2C SYSFS diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 4c771a2..0e5f2a5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SGI_XP)+= sgi-xp/ obj-$(CONFIG_SGI_GRU)+= sgi-gru/ obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o obj-$(CONFIG_HP_ILO) += hpilo.o +obj-$(CONFIG_APDS9802ALS)+= apds9802als.o obj-$(CONFIG_ISL29003) += isl29003.o obj-$(CONFIG_SENSORS_TSL2550)+= tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c new file mode 100644 index 000..a52270d --- /dev/null +++ b/drivers/misc/apds9802als.c @@ -0,0 +1,308 @@ +/* + * apds9802als.c - apds9802 ALS Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~ + * + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/err.h +#include linux/delay.h +#include linux/mutex.h +#include linux/sysfs.h +#include linux/hwmon-sysfs.h + +#define ALS_MIN_RANGE_VAL 1 +#define ALS_MAX_RANGE_VAL 2 +#define POWER_STA_ENABLE 1 +#define POWER_STA_DISABLE 0 +#define APDS9802ALS_I2C_ADDR 0x29 + +#define DRIVER_NAME apds9802als + +struct als_data { + struct device *hwmon_dev; + bool needresume; + struct mutex mutex; +}; + +static ssize_t als_sensing_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + int val; + + val = i2c_smbus_read_byte_data(client, 0x81); + if (val 0) + return val; + if (val 1) + return sprintf(buf, 4095\n); + else + return sprintf(buf, 65535\n); +} + +static ssize_t als_lux_input0_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct als_data *data = i2c_get_clientdata(client); + unsigned int ret_val; + int temp; + + /* Protect against parallel reads */ + mutex_lock(data-mutex); + temp = i2c_smbus_read_byte_data(client, 0x8C);/*LSB data*/ + if (temp 0) { + ret_val = temp; + goto failed; + } + ret_val
Re: [PATCH V2] staging: iio: tmd2771x: Add tmd2771x proximity and ambient light sensor driver
On 09/15/10 07:32, Donggeun Kim wrote: Changes from V1 to V2: - I2C read and write wrapping functions are removed. - The error handling routines are inserted. - The similar functions are created by macro invocation. - Some attribute names are changed. - Some event attribute names are changed. - The comments are added to the code to explain the non standard attributes and fields of the platform data. This driver supports TAOS TMD27711 and TMD27713 proximity and ambient light sensor. When threshold condition for proximity or ambient light sensor is satisfied, an event is generated. The proximity raw value is exported through the 'proximity_raw' attribute. This driver uses 'illuminance0_input' attribute to export lux value by calculating ch0 and ch1 ADC values. Hi, Most of the comments inline are observations rather than requests that you change anything. You certainly like your macros! I'll cleanup the naming of the event codes along with all the others in the tree so don't worry about that, except to the extent that it may change and break your userspace code. I think you have a race condition in your interrupt handler. Please check that and fix if necessary. Also, I don't think you use anything from gpio.h so please remove that. Otherwise, I'm happy so having cleaned up those two issues please add Acked-by: Jonathan Cameron ji...@cam.ac.uk and send on to Greg KH g...@kroah.com Signed-off-by: Donggeun Kim dg77@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/staging/iio/light/Kconfig| 11 + drivers/staging/iio/light/Makefile |1 + drivers/staging/iio/light/tmd2771x.c | 706 ++ drivers/staging/iio/light/tmd2771x.h | 169 drivers/staging/iio/sysfs.h |3 + 5 files changed, 890 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/light/tmd2771x.c create mode 100644 drivers/staging/iio/light/tmd2771x.h diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index 3ddc478..ecf8e09 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -12,3 +12,14 @@ config SENSORS_TSL2563 This driver can also be built as a module. If so, the module will be called tsl2563. + +config SENSORS_TMD2771X I'll repeat that I'm anti wild cards in names. These tend to become pretty much set in stone once the merge occurs. Do you have a really strong reason to believe TAOS will not release either a chip outside this range that is compatible or one inside the range that isn't? + tristate TAOS TMD2771X proximity and ambient light sensor + depends on I2C + help + If you say yes here you get support for TAOS TMD27711, TMD27713 + proximity and ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called tmd2771x. + diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 30f3300..03b0d10 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_SENSORS_TSL2563)+= tsl2563.o +obj-$(CONFIG_SENSORS_TMD2771X) += tmd2771x.o diff --git a/drivers/staging/iio/light/tmd2771x.c b/drivers/staging/iio/light/tmd2771x.c new file mode 100644 index 000..7343d6c --- /dev/null +++ b/drivers/staging/iio/light/tmd2771x.c @@ -0,0 +1,706 @@ +/* + * tmd2771x.c - Texas Advanced Optoelectronic Solutions Inc. + *Proximity/Ambient light sensor + * + * Copyright (C) 2010 Samsung Electronics + * Donggeun Kim dg77@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/module.h +#include linux/init.h +#include linux/interrupt.h +#include linux/platform_device.h +#include linux/workqueue.h +#include linux/mutex.h +#include linux/err.h +#include linux/i2c.h +#include linux/delay.h not seeing any calls to gpio functions in the code. +#include linux/gpio.h +#include linux/slab.h +#include ../iio.h +#include light.h +#include tmd2771x.h + +struct tmd2771x_chip { + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct work_thresh; + s64 last_timestamp; + struct mutexlock; + + struct tmd2771x_platform_data *pdata; +}; + This heavy use of macros is a little unconventional, but it should work fine. The only real issue is that it will (I think) add a fair bit of bloat to the resulting binary size. It looks to me like a lot of this could be avoided by putting the cleverness of all these macros into the top level calling ones
Re: [PATCH 05/25] drivers/i2c: Use static const char arrays
On 09/14/10 08:36, Lothar Waßmann wrote: Hi, Jonathan Cameron writes: Commit message is somewhat inaccurate... On 09/13/10 20:47, Joe Perches wrote: Signed-off-by: Joe Perches j...@perches.com --- drivers/i2c/busses/i2c-stu300.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 495be45..2f7c09c 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -871,7 +871,7 @@ stu300_probe(struct platform_device *pdev) struct resource *res; int bus_nr; int ret = 0; - char clk_name[] = I2C0; + char clk_name[sizeof(I2Cx)]; dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL); if (!dev) { @@ -881,7 +881,7 @@ stu300_probe(struct platform_device *pdev) } bus_nr = pdev-id; - clk_name[3] += (char)bus_nr; + sprintf(clk_name, I2C%c, '0' + bus_nr); I'm guessing that there are never more than a couple of these. Why is this method a better bet than just putting %d? '%c' will only ever produce one byte of output while '%d' may produce up to 11 bytes depending on the value of bus_nr thus overflowing the buffer. Then use an snprintf, or apply a check to ensure it isn't bigger than 9. If you don't mind having clocks named i2c$ or something equally silly then I guess this is fine. To my mind, if that is possible this is a bug that should be fixed rather than avoided. -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/25] drivers/i2c: Use static const char arrays
Commit message is somewhat inaccurate... On 09/13/10 20:47, Joe Perches wrote: Signed-off-by: Joe Perches j...@perches.com --- drivers/i2c/busses/i2c-stu300.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 495be45..2f7c09c 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -871,7 +871,7 @@ stu300_probe(struct platform_device *pdev) struct resource *res; int bus_nr; int ret = 0; - char clk_name[] = I2C0; + char clk_name[sizeof(I2Cx)]; dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL); if (!dev) { @@ -881,7 +881,7 @@ stu300_probe(struct platform_device *pdev) } bus_nr = pdev-id; - clk_name[3] += (char)bus_nr; + sprintf(clk_name, I2C%c, '0' + bus_nr); I'm guessing that there are never more than a couple of these. Why is this method a better bet than just putting %d? dev-clk = clk_get(pdev-dev, clk_name); if (IS_ERR(dev-clk)) { ret = PTR_ERR(dev-clk); -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging: iio: tmd2771x: Add tmd2771x proximity and ambient light sensor driver
Hi Donggeun, ... If they were auxiliary adcs (measuring some pin input) they would be in0_raw and in1_raw. Here I believe they are providing raw access to the readings on two different light sensors? Can we have names that give us some clue of the range that each of these sensors cover? Because overall structure is similar to tsl2563, the channel 0 is resposive to both visible and infrared light and channel 1 is responsive to infraread light. I will change adc0 and adc1 into intensity_both_raw and intensity_ir_raw likewise in tsl2563.c file, respectively + dev_attr_adc0.attr, + dev_attr_adc1.attr, + dev_attr_illuminance0_input.attr, + dev_attr_power_on.attr, Please provide details on each of the next three attributes. They are non standard and so need to be documented. The device have bitfields for each proximity and light sensor. The proximity_en and light_en attributes are related to the corresponding bit fields in the register. And the device is in the sleep mode, after a power-on-reset. As soon as the power_on attribute is enabled, the device will move to the start state. It will then continue through proximity sensing state, wait state, light sensing state, and start state. This procedure will be continuing if the device does not enter into sleep mode. When wait_en attribute is disabled, the device jumps the wait state. That makes sense. Please add a comment to the code somewhere to explain this. + dev_attr_wait_en.attr, + dev_attr_proximity_en.attr, + dev_attr_light_en.attr, + iio_const_attr_name.dev_attr.attr, + NULL +}; ... As this isn't done yet, can I confirm what exactly we have here? I would propose updating to the new abi when it is confirmed as a separate patch (so as not to delay your driver). +static struct attribute *tmd2771x_event_attributes[] = { + iio_event_attr_proximity_mag_either_rising_en.dev_attr.attr, + dev_attr_proximity_mag_pos_rising_value.attr, + dev_attr_proximity_mag_neg_rising_value.attr, So we have a single enable for both directions. As this isn't signed, I guess we can put a threshold on the value falling and one on it rising? So if our current is say 10, we can get an event if it falls below 8 or rises above 20? I think under the previous scheme this should have been mag_pos_rising and mag_pos_falling (neg implies a theshold on the actual negative value). Is there any way of enabling only one of these at a time? Under the new scheme these will be (if it doesn't change) proxmity_thresh_en, proximity_thresh_rising_value and proximity_thresh_falling_value. Actually, every raw data is positive number. I made some mistakes when naming the event attributes. The threshold values allows the user to define thresholds above and below a desired channel0 of light sensor and proximity level. An interrupt can be generated when the raw data exceeds the upper threshold value or falls below the lower threshold value. I'm not the proper attribute name, but I want to change it as belows: proximity_mag_either_rising_en - proximity_thresh_en proximity_mag_pos_rising_value - proximity_thresh_high_value proximity_mag_neg_rising_value - proximity_thresh_low_value Rising and falling rather than low and high as we care about the direction of change causing the interrupt. Again, don't worry too much about these, now I know what they are I can sort them out along with all other drivers when we have agreed what the final interface will be. proximity_mag_either_rising_period - proximity_thresh_period light_mag_either_rising_en - intensity_both_thresh_en light_mag_pos_rising_value - intensity_both_thresh_high_value light_mag_neg_rising_value - intensity_both_thresh_low_value light_mag_either_rising_period - intensity_both_thresh_period + dev_attr_proximity_mag_either_rising_period.attr, + iio_event_attr_light_mag_either_rising_en.dev_attr.attr, + dev_attr_light_mag_pos_rising_value.attr, + dev_attr_light_mag_neg_rising_value.attr, + dev_attr_light_mag_either_rising_period.attr, +#define TMD2771X_POWERUP_WAIT_TIME 12 + Please document this structure. Kernel doc format ideally. Sorry. I'm not familiar with kernel doc format. Where sholud I locate it after making a document file? Stick (with all elements documented...) the following in here. /** * struct tmd2771x_platform_data - device instance specific data * @control_power_source: function that controls power to the device * @power_on: cache of poweron elements of TMD2771X_DEFAULT_COMMAND register * ... * @glass_attenuation: implementatation specific attenuation factor **/ +struct tmd2771x_platform_data { + void (*control_power_source)(int); + + u8 power_on;/* TMD2771X_PON */ + u8 wait_enable; /* TMD2771X_WEN */ + u8 wait_long; /* TMD2771X_WLONG */ + u8 wait_time; /* 0x00 ~ 0xff */ + + /* Proximity */ +
Re: [PATCH 1/1] iio: ak8975: Add Ak8975 magnetometer sensor
On 09/03/10 00:40, ac...@nvidia.com wrote: From: Andrew Chew ac...@nvidia.com This is for the Asahi Kasei AK8975 3-axis magnetometer. It resides within the magnetometer section of the IIO subsystem, and implements the raw magn_x,y,z attributes, as well as x,y,z factory calibration attributes. Signed-off-by: Andrew Chew ac...@nvidia.com Hi Andrew, Looks pretty clean. A nice little driver. Anyhow inline you will find: * A few nitpicking points about eating errors. Lots of drivers in kernel do it, but lets not encourage even more. * Couple of other cleanup suggestions (none of which are vital, but might be worth doing if you are respinning anyway) I'm particularly intrigued to know if the sannity check for existence of the device can ever fail... I'll take a final look after you have done the abi related changes. Thanks, Jonathan p.s. As Andrew said, please make it clear which version of a patch this is, typically make the subject [Patch 1/1 V2] iio: ak8975 ... And some brief comments to say what has changed from the previous version are a great time saver for reviewers. --- drivers/staging/iio/magnetometer/Kconfig | 11 + drivers/staging/iio/magnetometer/Makefile |1 + drivers/staging/iio/magnetometer/ak8975.c | 521 + 3 files changed, 533 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/magnetometer/ak8975.c diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig index d014450..00e1204 100644 --- a/drivers/staging/iio/magnetometer/Kconfig +++ b/drivers/staging/iio/magnetometer/Kconfig @@ -3,6 +3,17 @@ # comment Magnetometer sensors +config SENSORS_AK8975 + tristate Asahi Kasei AK8975 3-Axis Magnetometer + default n + depends on I2C + help + Say yes here to build support for Asahi Kasei AK8975 3-Axis + Magnetometer. + + To compile this driver as a module, choose M here: the module + will be called ak8975. + config SENSORS_HMC5843 tristate Honeywell HMC5843 3-Axis Magnetometer depends on I2C diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile index f9bfb2e..e3dbaa4 100644 --- a/drivers/staging/iio/magnetometer/Makefile +++ b/drivers/staging/iio/magnetometer/Makefile @@ -2,4 +2,5 @@ # Makefile for industrial I/O Magnetometer sensors # +obj-$(CONFIG_SENSORS_AK8975) := ak8975.o obj-$(CONFIG_SENSORS_HMC5843)+= hmc5843.o diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c new file mode 100644 index 000..ca39840 --- /dev/null +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -0,0 +1,521 @@ +/* + * A sensor driver for the magnetometer AK8975. + * + * Magnetic compass sensor driver for monitoring magnetic flux information. + * + * Copyright (c) 2010, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/slab.h +#include linux/i2c.h +#include linux/err.h +#include linux/mutex.h +#include linux/delay.h + +#include linux/gpio.h + +#include ../iio.h +#include magnet.h + +/* + * Register definitions, as well as various shifts and masks to get at the + * individual fields of the registers. + */ +#define AK8975_REG_WIA 0x00 +#define AK8975_DEVICE_ID 0x48 + +#define AK8975_REG_INFO 0x01 + +#define AK8975_REG_ST1 0x02 +#define AK8975_REG_ST1_DRDY_SHIFT0 +#define AK8975_REG_ST1_DRDY_MASK (1 AK8975_REG_ST1_DRDY_SHIFT) + +#define AK8975_REG_HXL 0x03 +#define AK8975_REG_HXH 0x04 +#define AK8975_REG_HYL 0x05 +#define AK8975_REG_HYH 0x06 +#define AK8975_REG_HZL 0x07 +#define AK8975_REG_HZH 0x08 +#define AK8975_REG_ST2 0x09 +#define AK8975_REG_ST2_DERR_SHIFT2 +#define AK8975_REG_ST2_DERR_MASK (1 AK8975_REG_ST2_DERR_SHIFT) + +#define AK8975_REG_ST2_HOFL_SHIFT3 +#define AK8975_REG_ST2_HOFL_MASK (1
Re: [PATCH 1/1] iio: ak8975: Add Ak8975 magnetometer sensor
On 09/03/10 06:18, samu.p.onk...@nokia.com wrote: -Original Message- From: linux-iio-ow...@vger.kernel.org [mailto:linux-iio- ow...@vger.kernel.org] On Behalf Of ext Alan Cox Sent: 03 September, 2010 01:20 To: ac...@nvidia.com Cc: linux-ker...@vger.kernel.org; linux-...@vger.kernel.org; linux- i...@vger.kernel.org; a...@linux-foundation.org; kh...@linux-fr.org; ldewan...@nvidia.com Subject: Re: [PATCH 1/1] iio: ak8975: Add Ak8975 magnetometer sensor +/* + * Shows the device's mode. 0 = off, 1 = on. + */ Should this not be handled by runtime pm nowdays ? + if ((oval 0) || (oval 1)) { + dev_err(dev, mode value is not supported\n); + return -EINVAL; + } ulong cannot be 0 and doesn't need all the brackets + /* Wait for the conversion to complete. */ + while (timeout_ms) { + msleep(AK8975_CONVERSION_DONE_POLL_TIME); + state = (gpio_get_value(data-eoc_gpio) ? 1 : 0); + if (state) + break; + timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME; + } This makes some fairly specific wiring assumptions about how the ak8975 is configured. I'm looking at the ak8974 driver in our tree and also wondering if they can be combined sanely. With ak8974 chip, it is possible to have similar functionality without interrupt pin. This is most probably true also for ak8975 chip. It is not good to assume that everyone uses interrupt pin if the same functionally can be achieved another way. I mean polling via I2C instead of checking GPIO state after the sleep. Of course this can be done, but it's up to Andrew to decide whether he wants to. I think the usual principal of writing only what people currently need applies here. Perhaps a comment in the code to point out this could be done is a sensible compromise? Based on the this driver it seems that ak8974 and ak8975 are quite similar, but also there are many differences like different register map. Maybe combining these two makes implementation just messy. + status = ak8975_read_data(client, AK8975_REG_ST1, 1, read_status); + if (!status) { + dev_err(client-dev, Error in reading ST1\n); + return false; I would have expected these to return a meaningful error code not 0 ? +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode, 0); +static IIO_DEVICE_ATTR(magn_x_calibscale, S_IRUGO, show_calibscale, NULL, 0); +static IIO_DEVICE_ATTR(magn_y_calibscale, S_IRUGO, show_calibscale, NULL, 1); +static IIO_DEVICE_ATTR(magn_z_calibscale, S_IRUGO, show_calibscale, NULL, 2); +static IIO_DEV_ATTR_MAGN_X(show_raw, AK8975_REG_HXL); +static IIO_DEV_ATTR_MAGN_Y(show_raw, AK8975_REG_HYL); +static IIO_DEV_ATTR_MAGN_Z(show_raw, AK8975_REG_HZL); This seems odd as an interface as it's raw when the maths to provide non-raw (and thus abstract and easy for user space) data is trivial enough to do in kernel (but then I still suspect it should jusst be an input device of course) +static int ak8975_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ak8975_data *data; + int err; + + /* Allocate our device context. */ + data = kzalloc(sizeof(struct ak8975_data), GFP_KERNEL); + if (!data) { + dev_err(client-dev, Memory allocation fails\n); + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data-client = client; + + mutex_init(data-lock); + + /* Grab and set up the supplied GPIO. */ + data-eoc_irq = client-irq; + data-eoc_gpio = irq_to_gpio(client-irq); It may not be via a GPIO. Better to do the GPIO handling in platform abstraction or accept passing IRQ and no GPIO value to mean just use the IRQ. Ie do all the gpio foo if (data-eoc_gpio) { ... } + + err = gpio_request(data-eoc_gpio, ak_8975); + if (err 0) { + dev_err(client-dev, failed to request GPIO %d, error %d\n, + data-eoc_gpio, err); + goto exit_free; + } + + err = gpio_direction_input(data-eoc_gpio); + if (err 0) { + dev_err(client-dev, Failed to configure input direction for +GPIO %d, error %d\n, data-eoc_gpio, err); + gpio_free(data-eoc_gpio); This frees the GPIO twice ? Looks basically sound to me. Alan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] drivers: misc: ak8974 / ami305 magnetometer driver
On 08/27/10 19:08, Dmitry Torokhov wrote: On Fri, Aug 27, 2010 at 07:59:13PM +0300, Onkalo Samu wrote: +static ssize_t ak8974_misc_read(struct file *file, char __user *buf, + size_t count, loff_t *offset) +{ + struct ak8974_chip *chip = container_of(file-private_data, + struct ak8974_chip, + miscdev); + struct ak8974_data data; So we have a different API to the ak8975 just posted and to the other existing devices. This needs sorting out across the devices before there is a complete disaster. Right now we have a mix of submissions pending which variously use misc + sysfs sysfs input (reporting X Y Z etc axes) About year ago I send driver for the same chip with input-device interface. During that time I asked from Dmitry Torokhov that is that a correct interface for this kind of driver. I understood that input should not be used for this kind of sensors. sysfs is quite handy interface for small sensors. However, one problem is that the driver doesn't know when the interface is in use. I ended up to misc device to get information about the usercount for PM purposes. Dmitry, what is your opinion about using input device interface for this kind of sensors? This is really hard question and I am going back and forth myself. When considering using input subsystem try answering the following question - is the device's main purpose is indeed to be a human interface device or do you want to use input subystem because evdev interface is convenient? If the answer is former- then it should be in input (or available through input - let's say IIO-to-input bridge module). If the answer is latter then input is not the right place for the device. The iio to input bridge is still on the todo list. Unfortunately none of the core developers are particularly interested in that so it isn't a high priority. Of course we would welcome someone working on it! If not it we will get to it. Lately I was persuaded that 3-axis accelerometers are mainly used as input devices so I took adxl driver in and I need to get back and review cma3000 patch... Someone needs to decide on a single API before it's too late. That is definitely true. Could it be IIO? I'm in favour ;) We already have one straight magnetometer and one imu which includes a magnetometer. I'd love to see more and would certainly welcome this driver. I was hpoing that IIO would take care of unnamed sensors. Here I mean sensors that measure something and only user/application know exactly what it is; the same device might measure different things depending on setup. Take a temperature sensor - ambient temperature, temperature of some technological process, patient temperature - it is hard for the kernel to know which one it would be. This is in contrast with input system that tries to classify events so that the event has the same meaning regarless of which device emitted it - KEY_A means the same regardless of keybord; we may route them differently (multiseat for example), but the meaning is the same. That's certainly our intent. The down side of going with IIO is that it is taking a while to cleanup the userspace abi (and the core code for that matter!). Manuel Stahl has been recently pinning down a few issues made apparent via the generic userspace code he has been working on, so there will be patches relating to that over the next week. Ultimately the lack of interface stability is on reason IIO is still in staging. All help on this and more general code review of IIO is welcomed! For the sysfs devices I'd request that people either match our naming convention or that of hwmon (which the IIO one extends). By this I mean the individual attributes, not the directory naming etc. That way whatever the resulting subsystems of the future, we will at least have one naming convention! The chrdev end of things are more complex. (I'm happy to go into why we have two types etc but that's a much larger discussion) As a quick note though, the structure you have used is obviously very much device (or at least narrow class of) device specific. Our approach to this is a description of the format via a set of sysfs params. Much as you have done we need to maintain the linkage between a 'scan' of the channels and this approach allows us to do this. Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH/RFC 2/4] hwmon: PMBus device driver
On 06/28/10 22:56, Guenter Roeck wrote: Hi Guenter, A few questions and inital comments... Ouch the pmbus spec is tricky to follow! Signed-off-by: Guenter Roeck guenter.ro...@ericsson.com --- drivers/hwmon/Kconfig | 12 + drivers/hwmon/Makefile |1 + drivers/hwmon/pmbus.c | 1227 drivers/hwmon/pmbus.h | 209 4 files changed, 1449 insertions(+), 0 deletions(-) create mode 100644 drivers/hwmon/pmbus.c create mode 100644 drivers/hwmon/pmbus.h diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index e19cf8e..8d53cf7 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -702,6 +702,18 @@ config SENSORS_PCF8591 These devices are hard to detect and rarely found on mainstream hardware. If unsure, say N. +config SENSORS_PMBUS + tristate PMBus devices + depends on I2C EXPERIMENTAL + default n + help + If you say yes here you get hardware monitoring support for various + PMBus devices, including but not limited to BMR45x, LTC2978, MAX16064, + MAX8688, and UCD92xx. + + This driver can also be built as a module. If so, the module will + be called pmbus. + config SENSORS_SHT15 tristate Sensiron humidity and temperature sensors. SHT15 and compat. depends on GENERIC_GPIO diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 2138ceb..88b043e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o obj-$(CONFIG_SENSORS_PC87360)+= pc87360.o obj-$(CONFIG_SENSORS_PC87427)+= pc87427.o obj-$(CONFIG_SENSORS_PCF8591)+= pcf8591.o +obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o obj-$(CONFIG_SENSORS_S3C)+= s3c-hwmon.o obj-$(CONFIG_SENSORS_SHT15) += sht15.o obj-$(CONFIG_SENSORS_SIS5595)+= sis5595.o diff --git a/drivers/hwmon/pmbus.c b/drivers/hwmon/pmbus.c new file mode 100644 index 000..418ee2c --- /dev/null +++ b/drivers/hwmon/pmbus.c @@ -0,0 +1,1227 @@ +/* + * Hardware monitoring driver for PMBus devices + * + * Copyright (C) 2010 Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/init.h +#include linux/err.h +#include linux/slab.h +#include linux/i2c.h +#include linux/hwmon.h +#include linux/hwmon-sysfs.h +#include linux/delay.h +#include pmbus.h + +#define PMBUS_SENSORS64 +#define PMBUS_BOOLEANS 64 +#define PMBUS_LABELS 32 +#define PMBUS_NUM_ATTR (PMBUS_BOOLEANS + PMBUS_SENSORS + PMBUS_LABELS) +#define PMBUS_PAGES 8 + +static int pages; +module_param(pages, int, 0); +MODULE_PARM_DESC(pages, Number of sensor pages); Why is this a module parameter? If you do it like this you will be overriding page count for all devices in the system. Is that the intent? + +enum chips { ltc2978, max16064, max8688, pmbus, ucd9220, ucd9240 }; + +enum pmbus_sensor_classes { + PSC_VOLTAGE = 0, + PSC_TEMPERATURE, + PSC_CURRENT, + PSC_POWER, Perhaps name this PSC_MAX_LABEL or similar to indicate it is just here to allow the number of possible classes to be established. + SENSOR_CLASSES +}; + +struct pmbus_config { + int pages; /* Total number of pages (= output sensors) */ + bool direct;/* true if device uses direct data format */ + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[SENSOR_CLASSES]; /* mantissa for direct data format */ + int b[SENSOR_CLASSES]; /* offset */ + int R[SENSOR_CLASSES]; /* exponent */ +}; + Can we name these something to do with PB to cut down on chance of name clashes. +#define HAVE_STATUS_VOUT (10) +#define HAVE_STATUS_IOUT (11) +#define HAVE_STATUS_INPUT(12) +#define HAVE_STATUS_TEMP (13) + +#define PB_STATUS_BASE 0 +#define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) +#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_INPUT_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_TEMP_BASE (PB_STATUS_INPUT_BASE +
Re: [PATCH] hmc6352: Add driver for the HMC6352 compass
On 06/17/10 12:50, Alan Cox wrote: + struct i2c_msg msg1[] = { + { client-addr, 0, 1, cmd1 }, + }; It's quite overkill IMHO to have two messages here. In the end you send only one. It would make sense if you made these messages static const, They can't be const but I cleaned it up based on your other suggestions and then jumped up and down on it a bit more. hmc6352: Add driver for the HMC6352 compass From: Kalhan Trisal kalhan.tri...@intel.com This driver will report the heading values in degrees to the sysfs interface. The values returned are headings . e.g. 245.6 Cleanups requested now all folded in and a sysfs description to keep Andrew happy. Signed-off-by: Kalhan Trisal kalhan.tri...@intel.com Signed-off-by: Alan Cox a...@linux.intel.com Hi Alan, I guess it is pretty unlikely anyone would ever have more than one compass and if they do they can deal with the mutex sharing if they care. I think there is a small issue where the code and documentation don't match for the calibration attribute. The version in the docs makes more sense to me and I think it will slightly simplify the code. Fix that and I'm happy to add: Acked-by: Jonathan Cameron ji...@cam.ac.uk --- .../ABI/testing/sysfs-bus-i2c-devices-hm6352 | 21 +++ drivers/misc/Kconfig |7 + drivers/misc/Makefile |1 drivers/misc/hmc6352.c | 165 4 files changed, 194 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 create mode 100644 drivers/misc/hmc6352.c diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 new file mode 100644 index 000..feb2e4a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 @@ -0,0 +1,21 @@ +Where: /sys/bus/i2c/devices/.../heading0_input +Date:April 2010 +Kernel Version: 2.6.36? +Contact: alan@intel.com +Description: Reports the current heading from the compass as a floating + point value in degrees. + +Where: /sys/bus/i2c/devices/.../power_state +Date:April 2010 +Kernel Version: 2.6.36? +Contact: alan@intel.com +Description: Sets the power state of the device. 0 sets the device into + sleep mode, 1 wakes it up. + +Where: /sys/bus/i2c/devices/.../calibration +Date:April 2010 +Kernel Version: 2.6.36? +Contact: alan@intel.com +Description: Sets the calibration on or off (1 = on, 0 = off). See the + chip data sheet. I think there is a disrepancy between what is described here and what the code does. Looks to me like values are 1 for on and 2 for off in the code (which is a little odd). + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 26386a9..9e825cb 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -304,6 +304,13 @@ config SENSORS_TSL2550 This driver can also be built as a module. If so, the module will be called tsl2550. +config HMC6352 + tristate Honeywell HMC6352 compass + depends on I2C + help + This driver provides support for the Honeywell HMC6352 compass, + providing configuration and heading data via sysfs. + config EP93XX_PWM tristate EP93xx PWM support depends on ARCH_EP93XX diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 6ed06a1..48597df 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_DS1682)+= ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ +obj-$(CONFIG_HMC6352)+= hmc6352.o obj-y+= eeprom/ obj-y+= cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c new file mode 100644 index 000..3243c8c --- /dev/null +++ b/drivers/misc/hmc6352.c @@ -0,0 +1,165 @@ +/* + * hmc6352.c - Honeywell Compass Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public
Re: [PATCH] hmc6352: Add driver for the HMC6352 compass
On 06/16/10 13:16, Alan Cox wrote: From: Kalhan Trisal kalhan.tri...@intel.com This driver will report the heading values in degrees to the sysfs interface. The values returned are headings . e.g. 245.6 Cleanups requested now all folded in and a sysfs descriptio to keep Andrew happy. Hi Alan, Others seem to have reviewed the code fairly thoroughly so the only question I want to raise is that of the attribute naming. As the only other magnetometer in tree afaik (adis16400 has one amongst numerous other things) doesn't actually overlap with any of your attributes things are pretty unconstrained. Still as people have suggested (and we have acted on wrt to IIO) I would advocate matching hwmon's naming structure where it doesn't carry a significant cost. Simple arguement being that it is the biggest sensor related subsystem and what it uses works. So here we would have heading0_input. As this only applies to the one attribute anyway and maintaining that if we ever sweep all these drivers up into a common system would be trivial, this doesn't really matter that much. Still if it doesn't cost anything (though obviously it does if you have userspace code in place!) Thanks, Jonathan Signed-off-by: Kalhan Trisal kalhan.tri...@intel.com Signed-off-by: Alan Cox a...@linux.intel.com --- .../ABI/testing/sysfs-bus-i2c-devices-hm6352 | 21 ++ drivers/misc/Kconfig |7 + drivers/misc/Makefile |1 drivers/misc/hmc6352.c | 199 4 files changed, 228 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 create mode 100644 drivers/misc/hmc6352.c diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 new file mode 100644 index 000..fbedf77 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 @@ -0,0 +1,21 @@ +Where: /sys/bus/i2c/devices/.../heading +Date:April 2010 +Kernel Version: 2.6.36? +Contact: alan@intel.com +Description: Reports the current heading from the compass as a floating + point value in degrees. + +Where: /sys/bus/i2c/devices/.../power_state +Date:April 2010 +Kernel Version: 2.6.36? +Contact: alan@intel.com +Description: Sets the power state of the device. 0 sets the device into + sleep mode, 1 wakes it up. + +Where: /sys/bus/i2c/devices/.../calibration +Date:April 2010 +Kernel Version: 2.6.36? +Contact: alan@intel.com +Description: Sets the calibration on or off (1 = on, 0 = off). See the + chip data sheet. + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 26386a9..9e825cb 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -304,6 +304,13 @@ config SENSORS_TSL2550 This driver can also be built as a module. If so, the module will be called tsl2550. +config HMC6352 + tristate Honeywell HMC6352 compass + depends on I2C + help + This driver provides support for the Honeywell HMC6352 compass, + providing configuration and heading data via sysfs. + config EP93XX_PWM tristate EP93xx PWM support depends on ARCH_EP93XX diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 6ed06a1..48597df 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_DS1682)+= ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ +obj-$(CONFIG_HMC6352)+= hmc6352.o obj-y+= eeprom/ obj-y+= cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c new file mode 100644 index 000..a62a03b --- /dev/null +++ b/drivers/misc/hmc6352.c @@ -0,0 +1,199 @@ +/* + * hmc6352.c - Honeywell Compass Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + *
Re: [PATCH 2/4] isl29020: ambient light sensor
On 04/15/10 07:20, Daniel Mack wrote: On Wed, Apr 14, 2010 at 11:35:54PM +0100, Alan Cox wrote: Would it be possible to make the existing driver for the ISL29003 support the ISL29020 as well? I dug the manuals out for these to take a look - the answer is they are quite different chips. Hmm, sad :( However, the driver should be applied to the ALS tree after all, unless Jonathan plans to drop the whole thing, which I doubt. Sadly ALS is dead. Linus made it pretty clear he wasn't going to pull it. Hence currently either ALS drivers are going into misc (and can be moved elsewhere later), or we are taking them into IIO (and hence staging) where they fit fine and we can sort out a bridge to input to answer Linus' issue with the original patch set. In the thread following Alan's repost (having moved this driver to misc) Greg just pointed out the sysfs interface needed documenting, and I've suggested that we sort out the naming properly (in a way compliant with hwmon and the new IIO abi. 90% of what the ALS subsystem contributed was defining the ABI anyway! Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] liss331d1: accelerometer driver
On 04/14/10 23:12, Éric Piel wrote: Op 14-04-10 14:52, Alan Cox schreef: From: Kalhan Trisal kalhan.tri...@intel.com The acceleremeter driver reads the x,y,z coordinate registers and provides the information to user through the input layer Conversion to input device, clean up and porting of retry fixes needed for AAVA done by Alan Cox. Hello, I wouldn't want to be too picky, if this driver works fine with your hardware and it's tested, why not, but from looking at the spec of this chip (and at the code of this driver), it looks like it could be completely compatible with the lis3lv02d driver (with lis3lv02d_i2c). Same registers, including the WHO_AM_I register which returns 0x3B (which is a supported version). Have you tried and there were some specific incompatibilities? To me, it looks like the only thing not in the lis3lv02d is the read with multiple retries, and it could be easily added if necessary for your hardware. Cheers, Eric Err. Anyone get a feeling of deja vu here? http://lists.lm-sensors.org/pipermail/lm-sensors/2009-September/026706.html When Kalhan originally posted this driver it was pointed out that it was compatible with the existing one. A complete lack of communications lead to Kalhan (and someone else, might have been Eric or Samu, can't recall) both implementing i2c support in the driver. Can't find it right now but I'm fairly sure Kahlan reported that worked fine for this chip as well? So looks like a lack of communications here and that Alan has picked up an unnecessary driver. Jonathan Signed-off-by: Kalhan Trisal kalhan.tri...@intel.com Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/hwmon/Kconfig|8 + drivers/hwmon/Makefile |1 drivers/hwmon/lis331dl.c | 286 ++ 3 files changed, 295 insertions(+), 0 deletions(-) create mode 100644 drivers/hwmon/lis331dl.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 1fa2533..6868b9d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1104,6 +1104,14 @@ config SENSORS_ISL29020 Range values can be configured using sysfs. Lux data is accessible via sysfs. +config SENSORS_LIS331DL +tristate STMicroeletronics LIS331DL three-axis digital accelerometer +depends on I2C +help + If you say yes here you get support for the Accelerometer Devices + Device can be configured using sysfs. + x y Z data can be accessible via sysfs. + if ACPI comment ACPI drivers diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 13d6832..ebeb2a2 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o +obj-$(CONFIG_SENSORS_LIS331DL) += lis331dl.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM73) += lm73.o diff --git a/drivers/hwmon/lis331dl.c b/drivers/hwmon/lis331dl.c new file mode 100644 index 000..34009eb --- /dev/null +++ b/drivers/hwmon/lis331dl.c @@ -0,0 +1,286 @@ +/* + * lis331dl.c - ST LIS331DL Accelerometer Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~ + * + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/err.h +#include linux/delay.h +#include linux/mutex.h +#include linux/sysfs.h +#include linux/input-polldev.h + + +#define POLL_INTERVAL 50 + +struct lis331dl { +struct input_polled_dev *idev; +struct i2c_client *client; +struct mutex update_lock; +}; + +static ssize_t data_rate_show(struct device *dev, +struct device_attribute *attr, char *buf) +{ +struct i2c_client *client = to_i2c_client(dev); +int val; +int speed = 100; + +val = i2c_smbus_read_byte_data(client, 0x20); +if (val
Re: isl29020: ALS driver as misc device
On 04/14/10 18:01, Greg KH wrote: On Wed, Apr 14, 2010 at 05:56:02PM +0100, Alan Cox wrote: And this adds the isl29020 as a misc device per discussions isl29020: ambient light sensor From: Kalhan Trisal kalhan.tri...@intel.com The LS driver will read the latest Lux measurement based upon the light brightness and will report the LUX output through sysfs interface. Please document this sysfs interface with an addition to the Documentatin/ABI/ directory. As documenting this abi (which indeed should be done) is going to set a precedence, perhaps this is a good time to discuss what this naming could be. In cleaning up the IIO abi Greg suggested that we match existing similar abi's a closely as possible, which where possible makes a great deal of sense (shared userspace code is possible and it makes everything a bit more predictable for driver writers... particularly as I expect someone will sooner or later make a combined hwmon and als chip). The obvious similarity here is with hwmon. So perhaps going with naming as lux- illuminance0_input (or I guess lux0_input would also work, I can change the iio abi to match this as well). It also occurs to me that we might want to associate the calibration with the particular channel? There's sure to be a dual ALS chip along at some point. Obviously the isl29020 would need updating as well. Everyone was happy to do that when were writing the ALS subsystem, so I guess that won't have changed! Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/1] BH1770GLC / SFH7770 combined ambient light / proximity sensor
Hi Samu, This patch introduces driver for Rohm BH1770GLC and Osram SFH7770 combined ambient light and proximity sensor. Driver is divided to 3 parts. Core-part contains common functionality for both parts of the chips. ALS and PS specific functionalities are in separate files. ALS part is fully based on threshold interrupts. Driver doesn't provide direct control for threshold levels. Instead, based on sensitivity setting, threshold levels are updated after every interrupt. This method keeps sensor to follow changes in the lightning. PS part uses interrupt for high threshold events and delayed work to simulate missing low threshold interrupts. This way driver is able to react proximity on / off events using only high threshold interrupt. Proximity sensing can utilize up to 3 IR leds for movement detection. Driver supports 1-3 leds configurations. Platform data is used to provide IR led configuration: number of channels and absolute maximum operating currents for the leds. Chip is kept running only when someone keeps device handles open. Otherwise chip is powered down and optionally power supplies are turned off. Interfaces: Both parts of the driver provides results via separate misc char device. sysfs interface: als_calib - (RW) calibration coeffient (default is neutral value) als_mode - (R) returns current chip operational state for ALS als_rate - (RW) ALS side measurement rate in ms als_sens - (RW) sensitivity for changes in lightning level This ALS stuff feeds in pretty directly to the discussion just started in response to Alan Cox's post of the isl20920 driver. Basically we need to try and match as much of the sysfs interface across these chips as possible. Obviously this one is different to the ALS sensors already in kernel in that it doesn't allow direct reading of the value. For his driver I suggested illuminance0_input (not matched here) illuminance0_calib (these also happen to match the new IIO spec by amazing coincidence :) I'll put some related comments in a review of the patch. ps_calib - (RW) calibration coeffient ps_leds - (RW) IR led currents in mA ps_mode - (R) returns current chip operational state for PS ps_rate - (RW) PS side measurement rates (separate rates for below / above threshold condition) ps_threshold - (RW) threshold level Likewise with the proximity sensing. If nothing else, please allow for a chip with multiple proximity sensors with separate parameters. chip_id - (R) chip version and revision information Tested in top of 2.6.32 kernel. Applies to 2.6.34-RC3. Samu Onkalo (1): misc: bh1770glc: Driver for bh1770glc combined als and ps sensor drivers/misc/Kconfig | 12 + drivers/misc/Makefile |3 + drivers/misc/bh1770glc.h | 169 drivers/misc/bh1770glc_als.c | 424 + drivers/misc/bh1770glc_core.c | 301 + drivers/misc/bh1770glc_ps.c | 585 + include/linux/bh1770glc.h | 39 +++ 7 files changed, 1533 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/bh1770glc.h create mode 100644 drivers/misc/bh1770glc_als.c create mode 100644 drivers/misc/bh1770glc_core.c create mode 100644 drivers/misc/bh1770glc_ps.c create mode 100644 include/linux/bh1770glc.h -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/4] Various intel small device drivers
On 04/14/10 14:49, Alan Cox wrote: Kalhan Trisal (4): emc1403: thermal sensor support liss331d1: accelerometer driver isl29020: ambient light sensor hmc6352: Add driver for the HMC6352 compass The liss331d1, isl29020 and hmc6352 are not hardware monitoring drivers Disagree somewhat. In fact on close grepping I find that there is another related lis33 implementation in drivers/hwmon already 8) Given all the accelerometers are in drivers/hwmon where do you think they should be, and do you have pending patches to move the others ? I'd also be interested where you think the compass fits if its not hwmon, ditto the ambient light sensor ? If you like, feel free to (re)start an argument with Linus on the ambient light sensor front. Or see that thread for yet another round about discussion of where these sensors should be. http://lkml.org/lkml/2010/3/1/367 Basically if it is primarily an input device for human interaction, see if Dmitry is willing to take it into input (though note he may quite rightly take some convincing!) Otherwise, I'm happy to take more general sensors into IIO, but obviously that is still in staging and evolving reasonably quickly at the moment (large number of abi clean up patches half way through cleanup at the mo.) Otherwise, misc with the intent to sweep them all up when an agreed upon subsystem is in place. I'll bounce the emc1403 onto lm-sensors. Thanks Alan -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] hmc6352: Add driver for the HMC6352 compass
Hi Alan, Kalhan, Couple of comments below. On 04/14/10 13:51, Alan Cox wrote: From: Kalhan Trisal kalhan.tri...@intel.com This driver will report the heading values in degrees to the sysfs interface. The values returned are headings . e.g. 245.6 (Some cleanups from Alan Cox) Signed-off-by: Kalhan Trisal kalhan.tri...@intel.com Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/hwmon/Kconfig |7 + drivers/hwmon/Makefile |1 drivers/hwmon/hmc6352.c | 235 +++ This is in no way a hwmon chip. Surely misc is a better location for now (pending the usual discussion about all singing all dancing sensors frameworks). 3 files changed, 243 insertions(+), 0 deletions(-) create mode 100644 drivers/hwmon/hmc6352.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index d38447f..74f672d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1088,6 +1088,13 @@ config SENSORS_MC13783_ADC help Support for the A/D converter on MC13783 PMIC. +config SENSORS_HMC6352 + tristate Honeywell HMC6352 compass + depends on I2C + help + This driver provides support for the Honeywell HMC6352 compass, + providing configuration and heading data via sysfs. + if ACPI comment ACPI drivers diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 4aa1a3d..ad2ed36 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o obj-$(CONFIG_SENSORS_GL520SM)+= gl520sm.o obj-$(CONFIG_SENSORS_ULTRA45)+= ultra45_env.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o +obj-$(CONFIG_SENSORS_HMC6352)+= hmc6352.o obj-$(CONFIG_SENSORS_I5K_AMB)+= i5k_amb.o obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o diff --git a/drivers/hwmon/hmc6352.c b/drivers/hwmon/hmc6352.c new file mode 100644 index 000..926982f --- /dev/null +++ b/drivers/hwmon/hmc6352.c @@ -0,0 +1,235 @@ +/* + * hmc6352.c - Honeywell Compass Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~ + * + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/hwmon.h Why these extra hwmon includes? At least at first glance I can't see any uses of them. The only call to hwmon is to stick this in the hwmon class. +#include linux/hwmon-sysfs.h +#include linux/hwmon-vid.h +#include linux/err.h +#include linux/delay.h or any mutex usage? +#include linux/mutex.h +#include linux/sysfs.h + I guess this makes the driver look like many others, but why bother with the wrapping structure? This is only used to keep track of the hwmon device to be able to remove it later. +struct compass_data { + struct device *hwmon_dev; +}; + +static ssize_t compass_calibration_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int ret; + unsigned long val; Personally I'd have gone with a couple of chars then passed their address into the i2c_msg initializations. Guess it doesn't matter either way though! + char cmd[] = {0x43}; + char cmd1[] = {0x45}; + struct i2c_msg msg[] = { + { client-addr, 0, 1, cmd }, + }; + struct i2c_msg msg1[] = { + { client-addr, 0, 1, cmd1 }, + }; + + if (strict_strtoul(buf, 10, val)) + return -EINVAL; + if (val == 1) { These address changes looking a little unusual to me. They may well be needed, but if so can we have an explanatory comment? + client-addr = 0x21; + ret = i2c_transfer(client-adapter, msg, 1); + if (ret != 1) { + dev_warn(dev, hmc6352_comp : i2c callib start cmd failed\n); + return ret; + } + } else if (val == 2) { + client-addr = 0x21; + ret = i2c_transfer(client-adapter, msg1, 1); +
Re: [PATCH 1/4] hmc6352: Add driver for the HMC6352 compass
On 04/14/10 15:32, Alan Cox wrote: This is in no way a hwmon chip. Surely misc is a better location for now (pending the usual discussion about all singing all dancing sensors frameworks). Yep it's moving at the moment +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/hwmon.h Why these extra hwmon includes? At least at first glance I can't see any uses of them. The only call to hwmon is to stick this in the hwmon class. I inherited it for cleanup so these are good points (I've been staring at piles of these for so long extra input is very useful - this is the tip of the iceberg !) Cool, post away. Feel free to cc me in on anything in the category of general sensors (accelerometers, magnetometers etc). If nothing else, I'm interested to see them to get ideas for drivers in IIO etc. +#include linux/hwmon-sysfs.h +#include linux/hwmon-vid.h +#include linux/err.h +#include linux/delay.h or any mutex usage? +#include linux/mutex.h +#include linux/sysfs.h + I guess this makes the driver look like many others, but why bother with the wrapping structure? This is only used to keep track of the hwmon device to be able to remove it later. Should go - agreed will remove These address changes looking a little unusual to me. They may well be needed, but if so can we have an explanatory comment? Will investigate. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] hmc6352: Add driver for the HMC6352 compass
Looks good to me, Acked-by: Jonathan Cameron ji...@cam.ac.uk On 04/14/10 16:19, Alan Cox wrote: Ripping it out of hwmon and applying the hedge trimmers to everything not needed and we get this for drivers/misc. I've also swapped the command codes to characters as the datasheet specifies them in ascii. 8-- hmc6352: Add driver for the HMC6352 compass From: Kalhan Trisal kalhan.tri...@intel.com This driver will report the heading values in degrees to the sysfs interface. The values returned are headings . e.g. 245.6 (Some cleanups from Alan Cox) Signed-off-by: Kalhan Trisal kalhan.tri...@intel.com Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/misc/Kconfig |7 ++ drivers/misc/Makefile |1 drivers/misc/hmc6352.c | 199 3 files changed, 207 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/hmc6352.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 2191c8d..e626bac 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -278,6 +278,13 @@ config SENSORS_TSL2550 This driver can also be built as a module. If so, the module will be called tsl2550. +config HMC6352 + tristate Honeywell HMC6352 compass + depends on I2C + help + This driver provides support for the Honeywell HMC6352 compass, + providing configuration and heading data via sysfs. + config EP93XX_PWM tristate EP93xx PWM support depends on ARCH_EP93XX diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 208ae30..620cf0b 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -26,5 +26,6 @@ obj-$(CONFIG_DS1682)+= ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ +obj-$(CONFIG_HMC6352)+= hmc6352.o obj-y+= eeprom/ obj-y+= cb710/ diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c new file mode 100644 index 000..f4162ea --- /dev/null +++ b/drivers/misc/hmc6352.c @@ -0,0 +1,199 @@ +/* + * hmc6352.c - Honeywell Compass Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~ + * + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/err.h +#include linux/delay.h +#include linux/sysfs.h + +static ssize_t compass_calibration_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int ret; + unsigned long val; + char cmd = 'C';/* Calibrate */ + char cmd1 = 'E'; /* Exit calibration mode */ + struct i2c_msg msg[] = { + { client-addr, 0, 1, cmd }, + }; + struct i2c_msg msg1[] = { + { client-addr, 0, 1, cmd1 }, + }; + + if (strict_strtoul(buf, 10, val)) + return -EINVAL; + if (val == 1) { + ret = i2c_transfer(client-adapter, msg, 1); + if (ret != 1) { + dev_warn(dev, hmc6352_comp: i2c calib start cmd failed\n); + return ret; + } + } else if (val == 2) { + ret = i2c_transfer(client-adapter, msg1, 1); + if (ret != 1) { + dev_warn(dev, hmc6352_comp: i2c calib stop cmd failed\n); + return ret; + } + } else + return -EINVAL; + + return count; +} + +static ssize_t compass_heading_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + struct i2c_client *client = to_i2c_client(dev); + static char cmd = 'A'; /* Get Data */ + unsigned char i2c_data[2]; + unsigned int ret, ret_val; + struct i2c_msg msg[] = { + { client-addr, 0, 1, cmd }, + }; + struct
Re: [PATCH 21/24] staging/iio/adc: fix dangling pointers
On 03/20/10 14:13, Wolfram Sang wrote: Fix I2C-drivers which missed setting clientdata to NULL before freeing the structure it points to. Also fix drivers which do this _after_ the structure was freed already. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Greg Kroah-Hartman gre...@suse.de Acked-by: Jonathan Cameron ji...@cam.ac.uk Thanks, --- Found using coccinelle, then reviewed. Full patchset is available via kernel-janitors, linux-i2c, and LKML. --- drivers/staging/iio/adc/max1363_core.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 9703881..1682fd0 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -556,6 +556,7 @@ error_put_reg: if (!IS_ERR(st-reg)) regulator_put(st-reg); error_free_st: + i2c_set_clientdata(client, NULL); kfree(st); error_ret: @@ -573,6 +574,7 @@ static int max1363_remove(struct i2c_client *client) regulator_disable(st-reg); regulator_put(st-reg); } + i2c_set_clientdata(client, NULL); kfree(st); return 0; -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 22/24] staging/iio/light: fix dangling pointers
On 03/20/10 14:13, Wolfram Sang wrote: Fix I2C-drivers which missed setting clientdata to NULL before freeing the structure it points to. Also fix drivers which do this _after_ the structure was freed already. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Greg Kroah-Hartman gre...@suse.de Acked-by: Jonathan Cameron ji...@cam.ac.uk Thanks for this one as well! --- Found using coccinelle, then reviewed. Full patchset is available via kernel-janitors, linux-i2c, and LKML. --- drivers/staging/iio/light/tsl2563.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 78b9432..286559d 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -681,6 +681,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client, fail2: iio_device_unregister(chip-indio_dev); fail1: + i2c_set_clientdata(client, NULL); kfree(chip); return err; } @@ -691,6 +692,7 @@ static int tsl2563_remove(struct i2c_client *client) iio_device_unregister(chip-indio_dev); + i2c_set_clientdata(client, NULL); kfree(chip); return 0; } -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/5] i2c: Add SMBus alert support
Hi Jean, I have a couple of parts I can test this on (connected to a pxa271) but it may be a little while before I get to it (so don't let me hold the patch up!) On tiny point below. Worth changing if you are doing another roll of the patch as at least in my dozy Monday evening state it confused me for a few moments! Thanks, Jonathan Acked-by: Jonathan Cameron ji...@cam.ac.uk SMBus alert support. The SMBus alert protocol allows several SMBus slave devices to share a single interrupt pin on the SMBus master, while still allowing the master to know which slave triggered the interrupt. This is based on preliminary work by David Brownell. The key difference between David's implementation and mine is that his was part of i2c-core, while mine is split into a separate, standalone module named i2c-smbus. The i2c-smbus module is meant to include support for all SMBus extensions to the I2C protocol in the future. The benefit of this approach is a zero cost for I2C bus segments which do not need SMBus alert support. Where David's implementation increased the size of struct i2c_adapter by 7% (40 bytes on i386), mine doesn't touch it. Where David's implementation added over 150 lines of code to i2c-core (+10%), mine doesn't touch it. The only change that touches all the users of the i2c subsystem is a new callback in struct i2c_driver (common to both implementations.) I seem to remember Trent was worried about the footprint of David'd implementation, hopefully mine addresses the issue. Signed-off-by: Jean Delvare kh...@linux-fr.org Cc: David Brownell dbrown...@users.sourceforge.net Cc: Trent Piepho tpie...@freescale.com --- Documentation/i2c/smbus-protocol | 16 ++ drivers/i2c/Makefile |2 drivers/i2c/i2c-smbus.c | 264 ++ include/linux/i2c-smbus.h| 50 +++ include/linux/i2c.h |7 + 5 files changed, 338 insertions(+), 1 deletion(-) --- linux-2.6.33-rc7.orig/Documentation/i2c/smbus-protocol2010-02-12 14:19:47.0 +0100 +++ linux-2.6.33-rc7/Documentation/i2c/smbus-protocol 2010-02-12 14:19:51.0 +0100 @@ -185,6 +185,22 @@ the protocol. All ARP communications use require PEC checksums. +SMBus Alert +=== + +SMBus Alert was introduced in Revision 1.0 of the specification. + +The SMBus alert protocol allows several SMBus slave devices to share a +single interrupt pin on the SMBus master, while still allowing the master +to know which slave triggered the interrupt. + +This is implemented the following way in the Linux kernel: +* I2C bus drivers which support SMBus alert should call + i2c_setup_smbus_alert() to setup SMBus alert support. +* I2C drivers for devices which can trigger SMBus alerts should implement + the optional alert() callback. + + I2C Block Transactions == --- linux-2.6.33-rc7.orig/drivers/i2c/Makefile2010-02-12 14:19:47.0 +0100 +++ linux-2.6.33-rc7/drivers/i2c/Makefile 2010-02-12 16:08:34.0 +0100 @@ -3,7 +3,7 @@ # obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o -obj-$(CONFIG_I2C)+= i2c-core.o +obj-$(CONFIG_I2C)+= i2c-core.o i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV)+= i2c-dev.o obj-y+= busses/ chips/ algos/ --- /dev/null 1970-01-01 00:00:00.0 + +++ linux-2.6.33-rc7/drivers/i2c/i2c-smbus.c 2010-02-12 16:11:34.0 +0100 ... +/* + * The alert IRQ handler needs to hand work off to a task which can issue + * SMBus calls, because those sleeping calls can't be made in IRQ context. + */ +static void smbus_alert(struct work_struct *work) +{ + struct i2c_smbus_alert *data; + struct i2c_client *ara; + unsigned short prev_addr = 0; /* Not a valid address */ + + data = container_of(work, struct i2c_smbus_alert, alert); + ara = data-ara; + + for (;;) { + s32 status; + struct alert_data data; Can we change the name of data here. From readability point of view it would be better not to have this reliance on scope (as data used for struct i2c_smbus_alert *data above. (obviously changing it above would work as well!) + + /* + * Devices with pending alerts reply in address order, low + * to high, because of slave transmit arbitration. After + * responding, an SMBus device stops asserting SMBALERT#. + * + * Note that SMBus 2.0 reserves 10-bit addresess for future + * use. We neither handle them, nor try to use PEC here. + */ + status = i2c_smbus_read_byte(ara); + if (status 0) + break; + + data.flag = status 1; + data.addr = status 1; + + if (data.addr == prev_addr) { + dev_warn(ara-dev
[PATCH V2] ALS: TSL2550 driver move from i2c/chips
Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- This is not a finished patch. We still need to resolve the debate on naming conventions with ALS. Basically is there are a pressing reason for not having /sys/class/als/als0/ etc and moving management into the core? Otherwise we end up with every driver having to implement their own management systems and a lot of code replication. This will however work with current ALS patch set. Additions since previous V1: Removed set operating mode sysfs and replaced with an illuminance0_range_max. If requested max is in low range it will go with that, otherwise maximum range is selected. For now I've left the device id code etc alone, as moving this into the ALS core is still under debate. Couple of trivial style fixes thrown up by checkpatch in the original driver that we might was well fix during this move. V1: Minimal changes made. Untested due to lack of hardware. Full patch this time rather than move one. Documentation/ABI/testing/sysfs-class-als |9 + drivers/als/Kconfig | 14 + drivers/als/Makefile |2 + drivers/als/tsl2550.c | 535 + drivers/i2c/chips/Kconfig | 10 - drivers/i2c/chips/Makefile|1 - drivers/i2c/chips/tsl2550.c | 470 - 7 files changed, 560 insertions(+), 481 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-als b/Documentation/ABI/testing/sysfs-class-als index d3b33f3..9db1936 100644 --- a/Documentation/ABI/testing/sysfs-class-als +++ b/Documentation/ABI/testing/sysfs-class-als @@ -7,3 +7,12 @@ Description: Current Ambient Light Illuminance reported by Unit: lux (lumens per square meter) RO +What: /sys/class/als/.../illuminance[n]_range_max +Date: Oct. 2009 +KernelVersion: 2.6.32 +Contact: Jonathan Cameron ji...@cam.ac.uk +Description: Maximum value of Ambient Light Illuminance as + reported by ALS driver. Used when a device + has a multiple operating ranges. + Unit: lux (lumens per square meter) + RW diff --git a/drivers/als/Kconfig b/drivers/als/Kconfig index 200c52b..1564ffc 100644 --- a/drivers/als/Kconfig +++ b/drivers/als/Kconfig @@ -8,3 +8,17 @@ menuconfig ALS This framework provides a generic sysfs I/F for Ambient Light Sensor devices. If you want this support, you should say Y or M here. + +if ALS + +config ALS_TSL2550 + tristate Taos TSL2550 ambient light sensor + depends on EXPERIMENTAL I2C + help + If you say yes here you get support for the Taos TSL2550 + ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called tsl2550. + +endif #ALS diff --git a/drivers/als/Makefile b/drivers/als/Makefile index a527197..7be5631 100644 --- a/drivers/als/Makefile +++ b/drivers/als/Makefile @@ -3,3 +3,5 @@ # obj-$(CONFIG_ALS) += als_sys.o + +obj-$(CONFIG_ALS_TSL2550) += tsl2550.o \ No newline at end of file diff --git a/drivers/als/tsl2550.c b/drivers/als/tsl2550.c new file mode 100644 index 000..b75c1a9 --- /dev/null +++ b/drivers/als/tsl2550.c @@ -0,0 +1,535 @@ +/* + * tsl2550.c - Linux kernel modules for ambient light sensor + * + * Copyright (C) 2007 Rodolfo Giometti giome...@linux.it + * Copyright (C) 2007 Eurotech S.p.A. i...@eurotech.it + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/mutex.h +#include linux/err.h +#include linux/idr.h +#include linux/als_sys.h + +#define TSL2550_DRV_NAME tsl2550 +#define DRIVER_VERSION 2.0 + +/* + * Defines + */ + +#define TSL2550_POWER_DOWN 0x00 +#define TSL2550_POWER_UP 0x03 +#define TSL2550_STANDARD_RANGE 0x18 +#define TSL2550_EXTENDED_RANGE 0x1d +#define TSL2550_READ_ADC0 0x43 +#define TSL2550_READ_ADC1 0x83 + +/* + * Structs + */ + +struct tsl2550_data { + struct device *classdev; + struct i2c_client *client; + struct mutex update_lock; + int id
Re: [PATCH V2] ALS: TSL2550 driver move from i2c/chips
Signed-off-by: Jonathan Cameron ji...@cam.ac.uk --- Since V2: Fix of silly idr allocation code mistake. Illustrated Jean's point that someone would muck this up rather too well. (thanks Frederick!) Additions since previous V1: Removed set operating mode sysfs and replaced with an illuminance0_range_max. If requested max is in low range it will go with that, otherwise maximum range is selected. For now I've left the device id code etc alone, as moving this into the ALS core is still under debate. Couple of trivial style fixes. V1: Minimal changes made. Untested due to lack of hardware. --- Documentation/ABI/testing/sysfs-class-als |9 + drivers/als/Kconfig | 14 + drivers/als/Makefile |2 + drivers/als/tsl2550.c | 536 + drivers/i2c/chips/Kconfig | 10 - drivers/i2c/chips/Makefile|1 - drivers/i2c/chips/tsl2550.c | 470 - 7 files changed, 561 insertions(+), 481 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-als b/Documentation/ABI/testing/sysfs-class-als index d3b33f3..9db1936 100644 --- a/Documentation/ABI/testing/sysfs-class-als +++ b/Documentation/ABI/testing/sysfs-class-als @@ -7,3 +7,12 @@ Description:Current Ambient Light Illuminance reported by Unit: lux (lumens per square meter) RO +What:/sys/class/als/.../illuminance[n]_range_max +Date:Oct. 2009 +KernelVersion:2.6.32 +Contact:Jonathan Cameron ji...@cam.ac.uk +Description:Maximum value of Ambient Light Illuminance as +reported by ALS driver. Used when a device +has a multiple operating ranges. +Unit: lux (lumens per square meter) +RW diff --git a/drivers/als/Kconfig b/drivers/als/Kconfig index 200c52b..1564ffc 100644 --- a/drivers/als/Kconfig +++ b/drivers/als/Kconfig @@ -8,3 +8,17 @@ menuconfig ALS This framework provides a generic sysfs I/F for Ambient Light Sensor devices. If you want this support, you should say Y or M here. + +if ALS + +config ALS_TSL2550 +tristate Taos TSL2550 ambient light sensor +depends on EXPERIMENTAL I2C +help + If you say yes here you get support for the Taos TSL2550 + ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called tsl2550. + +endif #ALS diff --git a/drivers/als/Makefile b/drivers/als/Makefile index a527197..7be5631 100644 --- a/drivers/als/Makefile +++ b/drivers/als/Makefile @@ -3,3 +3,5 @@ # obj-$(CONFIG_ALS)+= als_sys.o + +obj-$(CONFIG_ALS_TSL2550)+= tsl2550.o \ No newline at end of file diff --git a/drivers/als/tsl2550.c b/drivers/als/tsl2550.c new file mode 100644 index 000..28ef17d --- /dev/null +++ b/drivers/als/tsl2550.c @@ -0,0 +1,536 @@ +/* + * tsl2550.c - Linux kernel modules for ambient light sensor + * + * Copyright (C) 2007 Rodolfo Giometti giome...@linux.it + * Copyright (C) 2007 Eurotech S.p.A. i...@eurotech.it + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/init.h +#include linux/slab.h +#include linux/i2c.h +#include linux/mutex.h +#include linux/err.h +#include linux/idr.h +#include linux/als_sys.h + +#define TSL2550_DRV_NAMEtsl2550 +#define DRIVER_VERSION2.0 + +/* + * Defines + */ + +#define TSL2550_POWER_DOWN0x00 +#define TSL2550_POWER_UP0x03 +#define TSL2550_STANDARD_RANGE0x18 +#define TSL2550_EXTENDED_RANGE0x1d +#define TSL2550_READ_ADC00x43 +#define TSL2550_READ_ADC10x83 + +/* + * Structs + */ + +struct tsl2550_data { +struct device *classdev; +struct i2c_client *client; +struct mutex update_lock; +int id; + +unsigned int power_state:1; +unsigned int operating_mode:1; +}; + +/* + * Global data + */ + +static const u8 TSL2550_MODE_RANGE[2] = { +TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE, +}; + +/* + * IDR to assign each registered device a unique id + */ +static DEFINE_IDR(tsl2550_idr); +static DEFINE_SPINLOCK(tsl2550_idr_lock); +#define TSL2550_DEV_MAX 9 + +/* + * Management functions + */ + +static int tsl2550_get_id(void) +{ +int ret, val; + +idr_again: +if (unlikely