From: Johan Hovold <johan@kernel.org>
To: Octavian Purdila <octavian.purdila@intel.com>
Cc: gregkh@linuxfoundation.org, linus.walleij@linaro.org,
gnurou@gmail.com, wsa@the-dreams.de, sameo@linux.intel.com,
lee.jones@linaro.org, arnd@arndb.de, johan@kernel.org,
daniel.baluta@intel.com, laurentiu.palcu@intel.com,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-i2c@vger.kernel.org
Subject: Re: [PATCH v5 2/4] i2c: add support for Diolan DLN-2 USB-I2C adapter
Date: Wed, 24 Sep 2014 12:58:28 +0200 [thread overview]
Message-ID: <20140924105828.GB17019@localhost> (raw)
In-Reply-To: <1411158165-25794-3-git-send-email-octavian.purdila@intel.com>
On Fri, Sep 19, 2014 at 11:22:43PM +0300, Octavian Purdila wrote:
> +struct dln2_i2c {
> + struct platform_device *pdev;
> + struct i2c_adapter adapter;
> + u32 freq;
> + u32 min_freq;
> + u32 max_freq;
> + /*
> + * Buffer to hold the packet for read or write transfers. One
> + * is enough since we can't have multiple transfers in
> + * parallel on the i2c adapter.
> + */
> + union {
> + struct {
> + u8 port;
> + u8 addr;
> + u8 mem_addr_len;
> + __le32 mem_addr;
> + __le16 buf_len;
> + u8 buf[DLN2_I2C_MAX_XFER_SIZE];
> + } __packed tx;
> + struct {
> + __le16 buf_len;
> + u8 buf[DLN2_I2C_MAX_XFER_SIZE];
> + } __packed rx;
> + } *buf;
Please declare these structs separately from the dln2_i2c struct so you
can use temporary pointers below.
Perhaps just allocate a large enough buffer (or page) here and keep you
transfer-buffer declarations in the two functions where they are used if
you prefer.
> +};
>
> +static int dln2_i2c_enable(struct dln2_i2c *dln2, bool enable)
> +{
> + struct dln2_platform_data *pdata = dev_get_platdata(&dln2->pdev->dev);
> + int ret;
> + u8 port;
> + u16 cmd;
> +
> + port = pdata->port;
Store the port number in the dln2_i2c struct rather than access it
through the platform data for every I/O operation.
> +
> + if (enable)
> + cmd = DLN2_I2C_ENABLE;
> + else
> + cmd = DLN2_I2C_DISABLE;
> +
> + ret = dln2_transfer(dln2->pdev, cmd, &port, sizeof(port), NULL, NULL);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int dln2_i2c_set_frequency(struct dln2_i2c *dln2, u32 freq)
> +{
> + int ret;
> + struct tx_data {
> + u8 port;
> + __le32 freq;
> + } __packed tx;
> + struct dln2_platform_data *pdata = dev_get_platdata(&dln2->pdev->dev);
> +
> + tx.port = pdata->port;
> + tx.freq = cpu_to_le32(freq);
> +
> + ret = dln2_transfer(dln2->pdev, DLN2_I2C_SET_FREQUENCY, &tx, sizeof(tx),
> + NULL, NULL);
> + if (ret < 0)
> + return ret;
> +
> + dln2->freq = freq;
> +
> + return 0;
> +}
> +
> +static int dln2_i2c_get_freq(struct dln2_i2c *dln2, u16 cmd, u32 *res)
> +{
> + int ret;
> + struct dln2_platform_data *pdata = dev_get_platdata(&dln2->pdev->dev);
> + u8 port = pdata->port;
> + __le32 freq;
> + unsigned len = sizeof(freq);
> +
> + ret = dln2_transfer(dln2->pdev, cmd, &port, sizeof(port),
> + &freq, &len);
> + if (ret < 0)
> + return ret;
> + if (len < sizeof(freq))
> + return -EPROTO;
> +
> + *res = le32_to_cpu(freq);
> +
> + return 0;
> +}
> +
> +static int dln2_i2c_setup(struct dln2_i2c *dln2)
> +{
> + int ret;
> +
> + ret = dln2_i2c_enable(dln2, false);
> + if (ret < 0)
> + return ret;
> +
> + ret = dln2_i2c_get_freq(dln2, DLN2_I2C_GET_MIN_FREQUENCY,
> + &dln2->min_freq);
> + if (ret < 0)
> + return 0;
return ret
> +
> + ret = dln2_i2c_get_freq(dln2, DLN2_I2C_GET_MAX_FREQUENCY,
> + &dln2->max_freq);
> + if (ret < 0)
> + return 0;
return ret
> +
> + ret = dln2_i2c_set_frequency(dln2, DLN2_I2C_FREQ_STD);
> + if (ret < 0)
> + return ret;
> +
> + ret = dln2_i2c_enable(dln2, true);
> +
> + return ret;
> +}
> +
> +static int dln2_i2c_write(struct dln2_i2c *dln2, u8 addr,
> + u8 *data, u16 data_len)
> +{
> + struct dln2_platform_data *pdata = dev_get_platdata(&dln2->pdev->dev);
> + int ret;
> + unsigned len;
> +
> + dln2->buf->tx.port = pdata->port;
> + dln2->buf->tx.addr = addr;
> + dln2->buf->tx.mem_addr_len = 0;
> + dln2->buf->tx.mem_addr = 0;
> + dln2->buf->tx.buf_len = cpu_to_le16(data_len);
> + memcpy(dln2->buf->tx.buf, data, data_len);
> +
> + len = sizeof(dln2->buf->tx) + data_len - DLN2_I2C_MAX_XFER_SIZE;
> + ret = dln2_transfer(dln2->pdev, DLN2_I2C_WRITE, &dln2->buf->tx, len,
> + NULL, NULL);
Use a temporary pointer to the tx struct above for readability.
> + if (ret < 0)
> + return ret;
> +
> + return data_len;
> +}
> +
> +static int dln2_i2c_read(struct dln2_i2c *dln2, u16 addr, u8 *data,
> + u16 data_len)
> +{
> + struct dln2_platform_data *pdata = dev_get_platdata(&dln2->pdev->dev);
> + int ret;
> + struct {
> + u8 port;
> + u8 addr;
> + u8 mem_addr_len;
> + __le32 mem_addr;
> + __le16 buf_len;
> + } __packed tx;
> + unsigned rx_len;
> +
> + tx.port = pdata->port;
> + tx.addr = addr;
> + tx.mem_addr_len = 0;
> + tx.mem_addr = 0;
> + tx.buf_len = cpu_to_le16(data_len);
> +
> + rx_len = sizeof(dln2->buf->rx);
> +
> + ret = dln2_transfer(dln2->pdev, DLN2_I2C_READ, &tx, sizeof(tx),
> + &dln2->buf->rx, &rx_len);
> + if (ret < 0)
> + return ret;
> + if (rx_len < sizeof(dln2->buf->rx.buf_len) + data_len)
> + return -EPROTO;
> + if (le16_to_cpu(dln2->buf->rx.buf_len) != data_len)
> + return -EPROTO;
> +
> + memcpy(data, dln2->buf->rx.buf, data_len);'
Use a temporary pointer to the rx struct above.
> +
> + return data_len;
> +}
[...]
> +static DEVICE_ATTR_RW(dln2_i2c_freq);
Any new sysfs attribute must to be documented under Documentation/ABI.
[...]
> +static struct platform_driver dln2_i2c_driver = {
> + .driver.name = "dln2-i2c",
> + .driver.owner = THIS_MODULE,
No need to set the owner field when using the module_platform_driver
macro.
> + .probe = dln2_i2c_probe,
> + .remove = dln2_i2c_remove,
> +};
> +
> +module_platform_driver(dln2_i2c_driver);
> +
> +MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@intel.com>");
> +MODULE_DESCRIPTION("Driver for the Diolan DLN2 I2C master interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:dln2-i2c");
Johan
next prev parent reply other threads:[~2014-09-24 10:58 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-19 20:22 [PATCH v5 0/4] mfd: add support for Diolan DLN-2 Octavian Purdila
[not found] ` <1411158165-25794-1-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-09-19 20:22 ` [PATCH v5 1/4] mfd: add support for Diolan DLN-2 devices Octavian Purdila
2014-09-19 20:22 ` Octavian Purdila
[not found] ` <1411158165-25794-2-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-09-24 10:48 ` Johan Hovold
2014-09-24 10:48 ` Johan Hovold
2014-09-24 13:36 ` Octavian Purdila
2014-09-24 13:36 ` Octavian Purdila
2014-09-24 13:54 ` Johan Hovold
2014-09-24 14:54 ` Octavian Purdila
2014-09-24 15:07 ` Johan Hovold
2014-09-24 15:22 ` Octavian Purdila
2014-09-25 10:25 ` Octavian Purdila
2014-09-25 10:30 ` Johan Hovold
2014-09-25 10:41 ` Octavian Purdila
2014-09-25 10:43 ` Johan Hovold
2014-09-19 20:22 ` [PATCH v5 4/4] gpio: add support for the Diolan DLN-2 USB GPIO driver Octavian Purdila
2014-09-19 20:22 ` Octavian Purdila
2014-09-20 2:48 ` Arnd Bergmann
[not found] ` <201409200448.48180.arnd-r2nGTMty4D4@public.gmane.org>
2014-09-20 6:32 ` Octavian Purdila
2014-09-20 6:32 ` Octavian Purdila
2014-09-24 12:39 ` Johan Hovold
2014-09-19 20:22 ` [PATCH v5 2/4] i2c: add support for Diolan DLN-2 USB-I2C adapter Octavian Purdila
2014-09-24 10:58 ` Johan Hovold [this message]
2014-09-19 20:22 ` [PATCH v5 3/4] gpiolib: add irq_not_threaded flag to gpio_chip Octavian Purdila
2014-09-24 8:54 ` Linus Walleij
2014-09-24 11:01 ` Johan Hovold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140924105828.GB17019@localhost \
--to=johan@kernel.org \
--cc=arnd@arndb.de \
--cc=daniel.baluta@intel.com \
--cc=gnurou@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=laurentiu.palcu@intel.com \
--cc=lee.jones@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=octavian.purdila@intel.com \
--cc=sameo@linux.intel.com \
--cc=wsa@the-dreams.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.