* [PATCH v3 0/5] HID: mcp2221: iio support and device resource management
@ 2022-09-12 17:31 Matt Ranostay
2022-09-12 17:31 ` [PATCH v3 1/5] i2c: muxes: ltc4306: fix future recursive dependencies Matt Ranostay
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Matt Ranostay @ 2022-09-12 17:31 UTC (permalink / raw)
To: gupt21, jic23; +Cc: linux-iio, linux-input, linux-i2c, Matt Ranostay
From: Matt Ranostay <mranostay@konsulko.com>
This patchset is primarily to enable iio support for the MCP2221 HID driver,
but requires several Kconfig changes and device resource management.
First attempt of this patchset is referenced here:
Link: https://lore.kernel.org/all/20220729154723.99947-1-matt.ranostay@konsulko.com/
Changes from v1:
* Fixing various Kconfig recursive dependencies that appear with 'imply IIO'
* Switch hid-mcp2221 driver to device managed resources for i2c support
* Reworking patchset per advice on lore.kernel.org link above
Changes from v2:
* add linux-iio list to CC
This is a resend since forgot linux-iio@vger.kernel.org in original post
Sorry for the spam to other lists..
Matt Ranostay (5):
i2c: muxes: ltc4306: fix future recursive dependencies
iio: addac: stx104: fix future recursive dependencies
iio: dac: fix future recursive dependencies
HID: mcp2221: switch i2c registration to devm functions
HID: mcp2221: add ADC/DAC support via iio subsystem
drivers/hid/Kconfig | 1 +
drivers/hid/hid-mcp2221.c | 196 ++++++++++++++++++++++++++++++++++++--
drivers/i2c/muxes/Kconfig | 2 +-
drivers/iio/addac/Kconfig | 3 +-
drivers/iio/dac/Kconfig | 6 +-
5 files changed, 195 insertions(+), 13 deletions(-)
--
2.37.2
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v3 1/5] i2c: muxes: ltc4306: fix future recursive dependencies 2022-09-12 17:31 [PATCH v3 0/5] HID: mcp2221: iio support and device resource management Matt Ranostay @ 2022-09-12 17:31 ` Matt Ranostay 2022-09-12 17:31 ` [PATCH v3 2/5] iio: addac: stx104: " Matt Ranostay ` (3 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Matt Ranostay @ 2022-09-12 17:31 UTC (permalink / raw) To: gupt21, jic23; +Cc: linux-iio, linux-input, linux-i2c, Matt Ranostay When using 'imply IIO' for other configurations which have 'select GPIOLIB' the following recursive dependency detected happens for I2C_MUX_LTC4306 Switch from 'select GPIOLIB' to 'depends on GPIOLIB' to avoid this per recommendation in kconfig-language.rst drivers/gpio/Kconfig:14:error: recursive dependency detected! drivers/gpio/Kconfig:14: symbol GPIOLIB is selected by I2C_MUX_LTC4306 drivers/i2c/muxes/Kconfig:47: symbol I2C_MUX_LTC4306 depends on I2C_MUX drivers/i2c/Kconfig:62: symbol I2C_MUX is selected by MPU3050_I2C drivers/iio/gyro/Kconfig:127: symbol MPU3050_I2C depends on IIO drivers/iio/Kconfig:6: symbol IIO is implied by HID_MCP2221 drivers/hid/Kconfig:1227: symbol HID_MCP2221 depends on GPIOLIB Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> --- drivers/i2c/muxes/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index ea838dbae32e..7b6a68df4a39 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -46,7 +46,7 @@ config I2C_MUX_GPMUX config I2C_MUX_LTC4306 tristate "LTC LTC4306/5 I2C multiplexer" - select GPIOLIB + depends on GPIOLIB select REGMAP_I2C help If you say yes here you get support for the Analog Devices -- 2.37.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 2/5] iio: addac: stx104: fix future recursive dependencies 2022-09-12 17:31 [PATCH v3 0/5] HID: mcp2221: iio support and device resource management Matt Ranostay 2022-09-12 17:31 ` [PATCH v3 1/5] i2c: muxes: ltc4306: fix future recursive dependencies Matt Ranostay @ 2022-09-12 17:31 ` Matt Ranostay 2022-09-12 17:32 ` [PATCH v3 3/5] iio: dac: " Matt Ranostay ` (2 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Matt Ranostay @ 2022-09-12 17:31 UTC (permalink / raw) To: gupt21, jic23; +Cc: linux-iio, linux-input, linux-i2c, Matt Ranostay When using 'imply IIO' for other configurations which have 'select GPIOLIB' the following recursive dependency detected happens for STX1040 Switch from 'select GPIOLIB' to 'depends on GPIOLIB' to avoid this per recommendation in kconfig-language.rst drivers/gpio/Kconfig:14:error: recursive dependency detected! drivers/gpio/Kconfig:14: symbol GPIOLIB is selected by STX104 drivers/iio/addac/Kconfig:20: symbol STX104 depends on IIO drivers/iio/Kconfig:6: symbol IIO is implied by HID_MCP2221 drivers/hid/Kconfig:1227: symbol HID_MCP2221 depends on GPIOLIB Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> --- drivers/iio/addac/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/addac/Kconfig b/drivers/iio/addac/Kconfig index fcf6d2269bfc..494790816ac7 100644 --- a/drivers/iio/addac/Kconfig +++ b/drivers/iio/addac/Kconfig @@ -19,9 +19,8 @@ config AD74413R config STX104 tristate "Apex Embedded Systems STX104 driver" - depends on PC104 && X86 + depends on PC104 && X86 && GPIOLIB select ISA_BUS_API - select GPIOLIB help Say yes here to build support for the Apex Embedded Systems STX104 integrated analog PC/104 card. -- 2.37.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 3/5] iio: dac: fix future recursive dependencies 2022-09-12 17:31 [PATCH v3 0/5] HID: mcp2221: iio support and device resource management Matt Ranostay 2022-09-12 17:31 ` [PATCH v3 1/5] i2c: muxes: ltc4306: fix future recursive dependencies Matt Ranostay 2022-09-12 17:31 ` [PATCH v3 2/5] iio: addac: stx104: " Matt Ranostay @ 2022-09-12 17:32 ` Matt Ranostay 2022-09-12 17:32 ` [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions Matt Ranostay 2022-09-12 17:32 ` [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem Matt Ranostay 4 siblings, 0 replies; 10+ messages in thread From: Matt Ranostay @ 2022-09-12 17:32 UTC (permalink / raw) To: gupt21, jic23; +Cc: linux-iio, linux-input, linux-i2c, Matt Ranostay When using 'imply IIO' for other configurations which have 'select GPIOLIB' the following recursive dependency detected happens for AD5592R and AD5593R. Switch from 'select GPIOLIB' to 'depends on GPIOLIB' to avoid this per recommendation in kconfig-language.rst drivers/gpio/Kconfig:14:error: recursive dependency detected! drivers/gpio/Kconfig:14: symbol GPIOLIB is selected by AD5592R drivers/iio/dac/Kconfig:93: symbol AD5592R depends on IIO drivers/iio/Kconfig:6: symbol IIO is implied by HID_MCP2221 drivers/hid/Kconfig:1227: symbol HID_MCP2221 depends on GPIOLIB Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> --- drivers/iio/dac/Kconfig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 80521bd28d0f..b93003e80b70 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -92,8 +92,7 @@ config AD5592R_BASE config AD5592R tristate "Analog Devices AD5592R ADC/DAC driver" - depends on SPI_MASTER - select GPIOLIB + depends on SPI_MASTER && GPIOLIB select AD5592R_BASE help Say yes here to build support for Analog Devices AD5592R @@ -104,8 +103,7 @@ config AD5592R config AD5593R tristate "Analog Devices AD5593R ADC/DAC driver" - depends on I2C - select GPIOLIB + depends on I2C && GPIOLIB select AD5592R_BASE help Say yes here to build support for Analog Devices AD5593R -- 2.37.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions 2022-09-12 17:31 [PATCH v3 0/5] HID: mcp2221: iio support and device resource management Matt Ranostay ` (2 preceding siblings ...) 2022-09-12 17:32 ` [PATCH v3 3/5] iio: dac: " Matt Ranostay @ 2022-09-12 17:32 ` Matt Ranostay 2022-09-18 15:39 ` Jonathan Cameron 2022-09-12 17:32 ` [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem Matt Ranostay 4 siblings, 1 reply; 10+ messages in thread From: Matt Ranostay @ 2022-09-12 17:32 UTC (permalink / raw) To: gupt21, jic23; +Cc: linux-iio, linux-input, linux-i2c, Matt Ranostay Switch from i2c_add_adapter() to resource managed devm_i2c_add_adapter() for matching rest of driver initialization, and more concise code. Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> --- drivers/hid/hid-mcp2221.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index de52e9f7bb8c..29e69576c3d4 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c @@ -873,7 +873,7 @@ static int mcp2221_probe(struct hid_device *hdev, "MCP2221 usb-i2c bridge on hidraw%d", ((struct hidraw *)hdev->hidraw)->minor); - ret = i2c_add_adapter(&mcp->adapter); + ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter); if (ret) { hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret); goto err_i2c; @@ -884,7 +884,7 @@ static int mcp2221_probe(struct hid_device *hdev, mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL); if (!mcp->gc) { ret = -ENOMEM; - goto err_gc; + goto err_i2c; } mcp->gc->label = "mcp2221_gpio"; @@ -900,12 +900,10 @@ static int mcp2221_probe(struct hid_device *hdev, ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp); if (ret) - goto err_gc; + goto err_i2c; return 0; -err_gc: - i2c_del_adapter(&mcp->adapter); err_i2c: hid_hw_close(mcp->hdev); err_hstop: @@ -917,7 +915,6 @@ static void mcp2221_remove(struct hid_device *hdev) { struct mcp2221 *mcp = hid_get_drvdata(hdev); - i2c_del_adapter(&mcp->adapter); hid_hw_close(mcp->hdev); hid_hw_stop(mcp->hdev); } -- 2.37.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions 2022-09-12 17:32 ` [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions Matt Ranostay @ 2022-09-18 15:39 ` Jonathan Cameron 2022-09-18 19:01 ` Matt Ranostay 0 siblings, 1 reply; 10+ messages in thread From: Jonathan Cameron @ 2022-09-18 15:39 UTC (permalink / raw) To: Matt Ranostay; +Cc: gupt21, linux-iio, linux-input, linux-i2c On Mon, 12 Sep 2022 10:32:01 -0700 Matt Ranostay <matt.ranostay@konsulko.com> wrote: > Switch from i2c_add_adapter() to resource managed devm_i2c_add_adapter() > for matching rest of driver initialization, and more concise code. > > Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> This doesn't necessarily make things worse, but I'm not keen on the potential ordering issues that result form mixed devm / non-devm in this function. It's too hard too think about! Easiest way to avoid people staring at the code to figure out if there are nasty issues would be to take the whole thing devm with a couple of devm_add_action_or_reset() to handle the hid_hw_stop()/hid_hw_close() at right points in the error / remove flows. Jonathan > --- > drivers/hid/hid-mcp2221.c | 9 +++------ > 1 file changed, 3 insertions(+), 6 deletions(-) > > diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c > index de52e9f7bb8c..29e69576c3d4 100644 > --- a/drivers/hid/hid-mcp2221.c > +++ b/drivers/hid/hid-mcp2221.c > @@ -873,7 +873,7 @@ static int mcp2221_probe(struct hid_device *hdev, > "MCP2221 usb-i2c bridge on hidraw%d", > ((struct hidraw *)hdev->hidraw)->minor); > > - ret = i2c_add_adapter(&mcp->adapter); > + ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter); > if (ret) { > hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret); > goto err_i2c; > @@ -884,7 +884,7 @@ static int mcp2221_probe(struct hid_device *hdev, > mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL); > if (!mcp->gc) { > ret = -ENOMEM; > - goto err_gc; > + goto err_i2c; > } > > mcp->gc->label = "mcp2221_gpio"; > @@ -900,12 +900,10 @@ static int mcp2221_probe(struct hid_device *hdev, > > ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp); > if (ret) > - goto err_gc; > + goto err_i2c; > > return 0; > > -err_gc: > - i2c_del_adapter(&mcp->adapter); > err_i2c: > hid_hw_close(mcp->hdev); > err_hstop: > @@ -917,7 +915,6 @@ static void mcp2221_remove(struct hid_device *hdev) > { > struct mcp2221 *mcp = hid_get_drvdata(hdev); > > - i2c_del_adapter(&mcp->adapter); > hid_hw_close(mcp->hdev); > hid_hw_stop(mcp->hdev); > } ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions 2022-09-18 15:39 ` Jonathan Cameron @ 2022-09-18 19:01 ` Matt Ranostay 0 siblings, 0 replies; 10+ messages in thread From: Matt Ranostay @ 2022-09-18 19:01 UTC (permalink / raw) To: Jonathan Cameron; +Cc: gupt21, linux-iio, linux-input, linux-i2c On Sun, Sep 18, 2022 at 8:39 AM Jonathan Cameron <jic23@kernel.org> wrote: > > On Mon, 12 Sep 2022 10:32:01 -0700 > Matt Ranostay <matt.ranostay@konsulko.com> wrote: > > > Switch from i2c_add_adapter() to resource managed devm_i2c_add_adapter() > > for matching rest of driver initialization, and more concise code. > > > > Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> > > This doesn't necessarily make things worse, but I'm not keen on the > potential ordering issues that result form mixed devm / non-devm > in this function. It's too hard too think about! > > Easiest way to avoid people staring at the code to figure out if > there are nasty issues would be to take the whole thing devm > with a couple of devm_add_action_or_reset() to handle the > hid_hw_stop()/hid_hw_close() at right points in the error / remove > flows. Good idea. Even if .remove() may be valid with the device resource management it is a bit confusing. - Matt > > Jonathan > > > > --- > > drivers/hid/hid-mcp2221.c | 9 +++------ > > 1 file changed, 3 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c > > index de52e9f7bb8c..29e69576c3d4 100644 > > --- a/drivers/hid/hid-mcp2221.c > > +++ b/drivers/hid/hid-mcp2221.c > > @@ -873,7 +873,7 @@ static int mcp2221_probe(struct hid_device *hdev, > > "MCP2221 usb-i2c bridge on hidraw%d", > > ((struct hidraw *)hdev->hidraw)->minor); > > > > - ret = i2c_add_adapter(&mcp->adapter); > > + ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter); > > if (ret) { > > hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret); > > goto err_i2c; > > @@ -884,7 +884,7 @@ static int mcp2221_probe(struct hid_device *hdev, > > mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL); > > if (!mcp->gc) { > > ret = -ENOMEM; > > - goto err_gc; > > + goto err_i2c; > > } > > > > mcp->gc->label = "mcp2221_gpio"; > > @@ -900,12 +900,10 @@ static int mcp2221_probe(struct hid_device *hdev, > > > > ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp); > > if (ret) > > - goto err_gc; > > + goto err_i2c; > > > > return 0; > > > > -err_gc: > > - i2c_del_adapter(&mcp->adapter); > > err_i2c: > > hid_hw_close(mcp->hdev); > > err_hstop: > > @@ -917,7 +915,6 @@ static void mcp2221_remove(struct hid_device *hdev) > > { > > struct mcp2221 *mcp = hid_get_drvdata(hdev); > > > > - i2c_del_adapter(&mcp->adapter); > > hid_hw_close(mcp->hdev); > > hid_hw_stop(mcp->hdev); > > } > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem 2022-09-12 17:31 [PATCH v3 0/5] HID: mcp2221: iio support and device resource management Matt Ranostay ` (3 preceding siblings ...) 2022-09-12 17:32 ` [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions Matt Ranostay @ 2022-09-12 17:32 ` Matt Ranostay 2022-09-18 15:49 ` Jonathan Cameron 4 siblings, 1 reply; 10+ messages in thread From: Matt Ranostay @ 2022-09-12 17:32 UTC (permalink / raw) To: gupt21, jic23; +Cc: linux-iio, linux-input, linux-i2c, Matt Ranostay Add support for 3x 10-bit ADC and 1x DAC channels registered via the iio subsystem. To prevent breakage and unexpected dependencies this support only is only built if CONFIG_IIO is enabled, and is only weakly referenced by 'imply IIO' within the respective Kconfig. Additionally the iio device only gets registered if at least one channel is enabled in the power-on configuration read from SRAM. Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> --- drivers/hid/Kconfig | 1 + drivers/hid/hid-mcp2221.c | 187 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 863d1f96ea57..cdae312f4795 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1228,6 +1228,7 @@ config HID_MCP2221 tristate "Microchip MCP2221 HID USB-to-I2C/SMbus host support" depends on USB_HID && I2C depends on GPIOLIB + imply IIO help Provides I2C and SMBUS host adapter functionality over USB-HID through MCP2221 device. diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index 29e69576c3d4..923b41eb76b3 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c @@ -16,6 +16,7 @@ #include <linux/hidraw.h> #include <linux/i2c.h> #include <linux/gpio/driver.h> +#include <linux/iio/iio.h> #include "hid-ids.h" /* Commands codes in a raw output report */ @@ -30,6 +31,8 @@ enum { MCP2221_I2C_CANCEL = 0x10, MCP2221_GPIO_SET = 0x50, MCP2221_GPIO_GET = 0x51, + MCP2221_SET_SRAM_SETTINGS = 0x60, + MCP2221_GET_SRAM_SETTINGS = 0x61, }; /* Response codes in a raw input report */ @@ -89,6 +92,7 @@ struct mcp2221 { struct i2c_adapter adapter; struct mutex lock; struct completion wait_in_report; + struct delayed_work init_work; u8 *rxbuf; u8 txbuf[64]; int rxbuf_idx; @@ -97,6 +101,16 @@ struct mcp2221 { struct gpio_chip *gc; u8 gp_idx; u8 gpio_dir; + u8 mode[4]; +#if IS_REACHABLE(CONFIG_IIO) + struct iio_chan_spec iio_channels[3]; + u16 adc_values[3]; + u8 dac_value; +#endif +}; + +struct mcp2221_iio { + struct mcp2221 *mcp; }; /* @@ -745,6 +759,9 @@ static int mcp2221_raw_event(struct hid_device *hdev, break; } mcp->status = mcp_get_i2c_eng_state(mcp, data, 8); +#if IS_REACHABLE(CONFIG_IIO) + memcpy(&mcp->adc_values, &data[50], sizeof(mcp->adc_values)); +#endif break; default: mcp->status = -EIO; @@ -816,6 +833,32 @@ static int mcp2221_raw_event(struct hid_device *hdev, complete(&mcp->wait_in_report); break; + case MCP2221_SET_SRAM_SETTINGS: + switch (data[1]) { + case MCP2221_SUCCESS: + mcp->status = 0; + break; + default: + mcp->status = -EAGAIN; + } + complete(&mcp->wait_in_report); + break; + + case MCP2221_GET_SRAM_SETTINGS: + switch (data[1]) { + case MCP2221_SUCCESS: + memcpy(&mcp->mode, &data[22], 4); +#if IS_REACHABLE(CONFIG_IIO) + mcp->dac_value = data[6] & GENMASK(4, 0); +#endif + mcp->status = 0; + break; + default: + mcp->status = -EAGAIN; + } + complete(&mcp->wait_in_report); + break; + default: mcp->status = -EIO; complete(&mcp->wait_in_report); @@ -824,6 +867,145 @@ static int mcp2221_raw_event(struct hid_device *hdev, return 1; } +#if IS_REACHABLE(CONFIG_IIO) +static int mcp2221_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int *val, + int *val2, long mask) +{ + struct mcp2221_iio *priv = iio_priv(indio_dev); + struct mcp2221 *mcp = priv->mcp; + int ret; + + mutex_lock(&mcp->lock); + + if (channel->output) { + *val = mcp->dac_value; + ret = IIO_VAL_INT; + } else { + /* Read ADC values */ + ret = mcp_chk_last_cmd_status(mcp); + + if (!ret) { + *val = le16_to_cpu(mcp->adc_values[channel->address]); + if (*val >= BIT(10)) + ret = -EINVAL; + else + ret = IIO_VAL_INT; + } + } + + mutex_unlock(&mcp->lock); + + return ret; +} + +static int mcp2221_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct mcp2221_iio *priv = iio_priv(indio_dev); + struct mcp2221 *mcp = priv->mcp; + int ret; + + if (val < 0 || val >= BIT(5)) + return -EINVAL; + + mutex_lock(&mcp->lock); + + memset(mcp->txbuf, 0, 12); + mcp->txbuf[0] = MCP2221_SET_SRAM_SETTINGS; + mcp->txbuf[4] = BIT(7) | val; + + ret = mcp_send_data_req_status(mcp, mcp->txbuf, 12); + + if (!ret) + mcp->dac_value = val; + + mutex_unlock(&mcp->lock); + + return ret; +} + +static const struct iio_info mcp2221_info = { + .read_raw = &mcp2221_read_raw, + .write_raw = &mcp2221_write_raw, +}; + +static int mcp_iio_channels(struct mcp2221 *mcp) +{ + int idx, cnt = 0; + bool dac_created = false; + + /* GP0 doesn't have ADC/DAC alternative function */ + for (idx = 1; idx < MCP_NGPIO; idx++) { + struct iio_chan_spec *chan = &mcp->iio_channels[cnt]; + + switch (mcp->mode[idx]) { + case 2: + chan->address = idx - 1; + chan->channel = cnt++; + break; + case 3: + /* GP1 doesn't have DAC alternative function */ + if (idx == 1 || dac_created) + continue; + /* DAC1 and DAC2 outputs are connected to the same DAC */ + dac_created = true; + chan->output = 1; + cnt++; + break; + default: + continue; + }; + + chan->type = IIO_VOLTAGE; + chan->indexed = 1; + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->scan_index = -1; + } + + return cnt; +} + +static void mcp_init_work(struct work_struct *work) +{ + struct iio_dev *indio_dev; + struct mcp2221 *mcp = container_of(work, struct mcp2221, init_work.work); + struct mcp2221_iio *data; + int ret, num_channels; + + hid_hw_power(mcp->hdev, PM_HINT_FULLON); + mutex_lock(&mcp->lock); + + mcp->txbuf[0] = MCP2221_GET_SRAM_SETTINGS; + ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); + mutex_unlock(&mcp->lock); + hid_hw_power(mcp->hdev, PM_HINT_NORMAL); + + if (ret) + return; + + num_channels = mcp_iio_channels(mcp); + if (!num_channels) + return; + + indio_dev = devm_iio_device_alloc(&mcp->hdev->dev, sizeof(*data)); + if (!indio_dev) + return; + + data = iio_priv(indio_dev); + data->mcp = mcp; + + indio_dev->name = "mcp2221"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &mcp2221_info; + indio_dev->channels = mcp->iio_channels; + indio_dev->num_channels = num_channels; + + devm_iio_device_register(&mcp->hdev->dev, indio_dev); +} +#endif + static int mcp2221_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -902,6 +1084,11 @@ static int mcp2221_probe(struct hid_device *hdev, if (ret) goto err_i2c; +#if IS_REACHABLE(CONFIG_IIO) + INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); + schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(500)); +#endif + return 0; err_i2c: -- 2.37.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem 2022-09-12 17:32 ` [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem Matt Ranostay @ 2022-09-18 15:49 ` Jonathan Cameron 2022-09-18 20:12 ` Matt Ranostay 0 siblings, 1 reply; 10+ messages in thread From: Jonathan Cameron @ 2022-09-18 15:49 UTC (permalink / raw) To: Matt Ranostay; +Cc: gupt21, linux-iio, linux-input, linux-i2c On Mon, 12 Sep 2022 10:32:02 -0700 Matt Ranostay <matt.ranostay@konsulko.com> wrote: > Add support for 3x 10-bit ADC and 1x DAC channels registered via the iio > subsystem. > > To prevent breakage and unexpected dependencies this support only is > only built if CONFIG_IIO is enabled, and is only weakly referenced by > 'imply IIO' within the respective Kconfig. > > Additionally the iio device only gets registered if at least one channel > is enabled in the power-on configuration read from SRAM. > > Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> Hi Matt, Can we not provide a _scale? Whilst not technically required in all IIO Drivers, a bare _raw interface is rarely that much use and here the ADC and DAC clearly have very different scales. Otherwise, as seen below, I'd like a comment on why the registration is kicked off in a delayed work item. Right now that looks like a hack to ensure something else has happened first. That's fine, but there doesn't seem to be rescheduling if whatever that 'thing' is hasn't happened yet. To use this sort of delayed trick, I'd definitely expect a backoff again to be implemented... > --- > drivers/hid/Kconfig | 1 + > drivers/hid/hid-mcp2221.c | 187 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 188 insertions(+) ... > static int mcp2221_probe(struct hid_device *hdev, > const struct hid_device_id *id) > { > @@ -902,6 +1084,11 @@ static int mcp2221_probe(struct hid_device *hdev, > if (ret) > goto err_i2c; > > +#if IS_REACHABLE(CONFIG_IIO) > + INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); > + schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(500)); Good to have a comment here to say why you are kicking the registration of the IIO device onto a delayed work path. > +#endif > + > return 0; > > err_i2c: ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem 2022-09-18 15:49 ` Jonathan Cameron @ 2022-09-18 20:12 ` Matt Ranostay 0 siblings, 0 replies; 10+ messages in thread From: Matt Ranostay @ 2022-09-18 20:12 UTC (permalink / raw) To: Jonathan Cameron; +Cc: gupt21, linux-iio, linux-input, linux-i2c On Sun, Sep 18, 2022 at 8:49 AM Jonathan Cameron <jic23@kernel.org> wrote: > > On Mon, 12 Sep 2022 10:32:02 -0700 > Matt Ranostay <matt.ranostay@konsulko.com> wrote: > > > Add support for 3x 10-bit ADC and 1x DAC channels registered via the iio > > subsystem. > > > > To prevent breakage and unexpected dependencies this support only is > > only built if CONFIG_IIO is enabled, and is only weakly referenced by > > 'imply IIO' within the respective Kconfig. > > > > Additionally the iio device only gets registered if at least one channel > > is enabled in the power-on configuration read from SRAM. > > > > Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> > > Hi Matt, > > Can we not provide a _scale? > Whilst not technically required in all IIO Drivers, a bare _raw interface > is rarely that much use and here the ADC and DAC clearly have very different > scales. I will check into that. The sampling voltage range is configurable though and will need to see > > Otherwise, as seen below, I'd like a comment on why the registration > is kicked off in a delayed work item. Right now that looks like a hack > to ensure something else has happened first. That's fine, but there > doesn't seem to be rescheduling if whatever that 'thing' is hasn't happened yet. > To use this sort of delayed trick, I'd definitely expect a backoff again > to be implemented... Ok a retry here maybe would make sense to be sure the SRAM configuration is read. This hack is just because we have to be sure the MCP2221 is up and running before attempting to read the SRAM via a USB message, and is less ugly/wrong to pop a msleep in a probe function. Also in this case we can back down the half second delay since that is the worst case. - Matt > > > --- > > drivers/hid/Kconfig | 1 + > > drivers/hid/hid-mcp2221.c | 187 ++++++++++++++++++++++++++++++++++++++ > > 2 files changed, 188 insertions(+) > > > ... > > > static int mcp2221_probe(struct hid_device *hdev, > > const struct hid_device_id *id) > > { > > @@ -902,6 +1084,11 @@ static int mcp2221_probe(struct hid_device *hdev, > > if (ret) > > goto err_i2c; > > > > +#if IS_REACHABLE(CONFIG_IIO) > > + INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); > > + schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(500)); > > Good to have a comment here to say why you are kicking the registration of the > IIO device onto a delayed work path. > > > +#endif > > + > > return 0; > > > > err_i2c: > ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-09-18 20:12 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-09-12 17:31 [PATCH v3 0/5] HID: mcp2221: iio support and device resource management Matt Ranostay 2022-09-12 17:31 ` [PATCH v3 1/5] i2c: muxes: ltc4306: fix future recursive dependencies Matt Ranostay 2022-09-12 17:31 ` [PATCH v3 2/5] iio: addac: stx104: " Matt Ranostay 2022-09-12 17:32 ` [PATCH v3 3/5] iio: dac: " Matt Ranostay 2022-09-12 17:32 ` [PATCH v3 4/5] HID: mcp2221: switch i2c registration to devm functions Matt Ranostay 2022-09-18 15:39 ` Jonathan Cameron 2022-09-18 19:01 ` Matt Ranostay 2022-09-12 17:32 ` [PATCH v3 5/5] HID: mcp2221: add ADC/DAC support via iio subsystem Matt Ranostay 2022-09-18 15:49 ` Jonathan Cameron 2022-09-18 20:12 ` Matt Ranostay
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox