Hi Uli,
> +static void wait_for_transaction(struct max9260_device *dev)
> +{
> + wait_event_interruptible_timeout(dev->rx_wq,
> + dev->rx_state <= RX_FRAME_ERROR,
> + HZ/2);
> +}
> +static void transact(struct max9260_device *dev,
max9260_transact?
> + int expect,
> + u8 *request, int len)
> +{
> + serdev_device_mux_select(dev->serdev);
> +
> + serdev_device_set_baudrate(dev->serdev, 115200);
> + serdev_device_set_parity(dev->serdev, 1, 0);
> +
> + dev->rx_state = expect;
> + serdev_device_write_buf(dev->serdev, request, len);
> +
> + wait_for_transaction(dev);
> +
> + serdev_device_mux_deselect(dev->serdev);
> +}
> +
> +static int max9260_read_reg(struct max9260_device *dev, int reg)
> +{
> + u8 request[] = { 0x79, 0x91, reg, 1 };
> + u8 rx;
> +
> + dev->rx_len = 1;
> + dev->rx_buf = ℞
> +
> + transact(dev, RX_EXPECT_ACK_DATA, request, 4);
> +
> + if (dev->rx_state == RX_FINISHED)
> + return rx;
> +
> + return -1;
-EIO?
> +}
> +
> +static int max9260_setup(struct max9260_device *dev)
> +{
> + int ret;
> +
> + ret = max9260_read_reg(dev, 0x1e);
> +
> + if (ret != 0x02) {
> + dev_err(&dev->serdev->dev,
> + "device does not identify as MAX9260\n");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static void max9260_uart_write_wakeup(struct serdev_device *serdev)
> +{
> +}
> +
> +static int max9260_uart_receive_buf(struct serdev_device *serdev,
> + const u8 *data, size_t count)
> +{
> + struct max9260_device *dev = serdev_device_get_drvdata(serdev);
> + int accepted;
> +
> + switch (dev->rx_state) {
> + case RX_FINISHED:
> + dev_dbg(&dev->serdev->dev, "excess data ignored\n");
> + return count;
> +
> + case RX_EXPECT_ACK:
> + case RX_EXPECT_ACK_DATA:
> + if (data[0] != ACK) {
> + dev_dbg(&dev->serdev->dev, "frame error");
> + dev->rx_state = RX_FRAME_ERROR;
> + wake_up_interruptible(&dev->rx_wq);
> + return 1;
> + }
> + switch (dev->rx_state) {
> + case RX_EXPECT_ACK_DATA:
> + dev->rx_state = RX_EXPECT_DATA;
> + break;
> + case RX_EXPECT_ACK:
> + dev->rx_state = RX_FINISHED;
> + wake_up_interruptible(&dev->rx_wq);
> + break;
> + }
This switch inside a switch evaluating the same variable is easy to
misunderstand. What about a simple if-else for the second switch block
above?
> + return 1;
> +
> + case RX_EXPECT_DATA:
> + accepted = dev->rx_len < count ? dev->rx_len : count;
> +
> + memcpy(dev->rx_buf, data, accepted);
> +
> + dev->rx_len -= accepted;
> + dev->rx_buf += accepted;
> +
> + if (!dev->rx_len) {
> + dev->rx_state = RX_FINISHED;
> + wake_up_interruptible(&dev->rx_wq);
> + }
> +
> + return accepted;
> +
> + case RX_FRAME_ERROR:
> + dev_dbg(&dev->serdev->dev, "%d bytes ignored\n", count);
> + return count;
> +
> + }
> + return 0;
> +}
> +
> +struct serdev_device_ops max9260_serdev_client_ops = {
> + .receive_buf = max9260_uart_receive_buf,
> + .write_wakeup = max9260_uart_write_wakeup,
> +};
> +
> +static u32 max9260_i2c_func(struct i2c_adapter *adapter)
> +{
> + return I2C_FUNC_SMBUS_EMUL;
According to the below xfer function, it should return:
I2C_SMBUS_BYTE | I2C_SMBUS_BYTE_DATA;
> +}
> +
...
> +static int max9260_probe(struct serdev_device *serdev)
> +{
> + struct max9260_device *dev;
> + struct i2c_adapter *adap;
> + int ret;
> +
> + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
devm_kzalloc?
> + if (!dev)
> + return -ENOMEM;
> +
> + init_waitqueue_head(&dev->rx_wq);
> +
> + dev->serdev = serdev;
> + serdev_device_open(serdev);
> + serdev_device_set_drvdata(serdev, dev);
> +
> + serdev_device_set_client_ops(serdev, &max9260_serdev_client_ops);
> +
> + ret = max9260_setup(dev);
> +
Newline can go.
> + if (ret < 0)
> + goto err_free;
> +
> + adap = &dev->adap;
> + i2c_set_adapdata(adap, dev);
> +
> + adap->owner = THIS_MODULE;
> + adap->algo = &max9260_i2c_algorithm;
> + adap->dev.parent = &serdev->dev;
> + adap->retries = 5;
> + adap->nr = -1;
You can skip this...
> + strlcpy(adap->name, dev_name(&serdev->dev), sizeof(adap->name));
> +
> + ret = i2c_add_numbered_adapter(adap);
... if you use i2c_add_adapter(adap); here. No 'numbered'.
> + if (ret < 0) {
> + dev_err(&serdev->dev, "failed to register i2c adapter\n");
No need for dev_err. The core will properly report failures.
> + return ret;
> + }
> +
> + return 0;
> +
> +err_free:
> + kfree(dev);
> + return ret;
> +}
Regards,
Wolfram
signature.asc
Description: PGP signature
