167a95c21SRishi Gupta // SPDX-License-Identifier: GPL-2.0-only 267a95c21SRishi Gupta /* 367a95c21SRishi Gupta * MCP2221A - Microchip USB to I2C Host Protocol Bridge 467a95c21SRishi Gupta * 567a95c21SRishi Gupta * Copyright (c) 2020, Rishi Gupta <gupt21@gmail.com> 667a95c21SRishi Gupta * 7b266eacfSAlexander A. Klimov * Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/20005565B.pdf 867a95c21SRishi Gupta */ 967a95c21SRishi Gupta 1067a95c21SRishi Gupta #include <linux/module.h> 1167a95c21SRishi Gupta #include <linux/err.h> 1267a95c21SRishi Gupta #include <linux/mutex.h> 1367a95c21SRishi Gupta #include <linux/completion.h> 1467a95c21SRishi Gupta #include <linux/delay.h> 1567a95c21SRishi Gupta #include <linux/hid.h> 1667a95c21SRishi Gupta #include <linux/hidraw.h> 1767a95c21SRishi Gupta #include <linux/i2c.h> 18328de1c5SRishi Gupta #include <linux/gpio/driver.h> 1967a95c21SRishi Gupta #include "hid-ids.h" 2067a95c21SRishi Gupta 2167a95c21SRishi Gupta /* Commands codes in a raw output report */ 2267a95c21SRishi Gupta enum { 2367a95c21SRishi Gupta MCP2221_I2C_WR_DATA = 0x90, 2467a95c21SRishi Gupta MCP2221_I2C_WR_NO_STOP = 0x94, 2567a95c21SRishi Gupta MCP2221_I2C_RD_DATA = 0x91, 2667a95c21SRishi Gupta MCP2221_I2C_RD_RPT_START = 0x93, 2767a95c21SRishi Gupta MCP2221_I2C_GET_DATA = 0x40, 2867a95c21SRishi Gupta MCP2221_I2C_PARAM_OR_STATUS = 0x10, 2967a95c21SRishi Gupta MCP2221_I2C_SET_SPEED = 0x20, 3067a95c21SRishi Gupta MCP2221_I2C_CANCEL = 0x10, 31328de1c5SRishi Gupta MCP2221_GPIO_SET = 0x50, 32328de1c5SRishi Gupta MCP2221_GPIO_GET = 0x51, 3367a95c21SRishi Gupta }; 3467a95c21SRishi Gupta 3567a95c21SRishi Gupta /* Response codes in a raw input report */ 3667a95c21SRishi Gupta enum { 3767a95c21SRishi Gupta MCP2221_SUCCESS = 0x00, 3867a95c21SRishi Gupta MCP2221_I2C_ENG_BUSY = 0x01, 3967a95c21SRishi Gupta MCP2221_I2C_START_TOUT = 0x12, 4067a95c21SRishi Gupta MCP2221_I2C_STOP_TOUT = 0x62, 4167a95c21SRishi Gupta MCP2221_I2C_WRADDRL_TOUT = 0x23, 4267a95c21SRishi Gupta MCP2221_I2C_WRDATA_TOUT = 0x44, 4367a95c21SRishi Gupta MCP2221_I2C_WRADDRL_NACK = 0x25, 4467a95c21SRishi Gupta MCP2221_I2C_MASK_ADDR_NACK = 0x40, 4567a95c21SRishi Gupta MCP2221_I2C_WRADDRL_SEND = 0x21, 4667a95c21SRishi Gupta MCP2221_I2C_ADDR_NACK = 0x25, 4767a95c21SRishi Gupta MCP2221_I2C_READ_COMPL = 0x55, 48328de1c5SRishi Gupta MCP2221_ALT_F_NOT_GPIOV = 0xEE, 49328de1c5SRishi Gupta MCP2221_ALT_F_NOT_GPIOD = 0xEF, 5067a95c21SRishi Gupta }; 5167a95c21SRishi Gupta 52567b8e9fSLars Povlsen /* MCP GPIO direction encoding */ 53567b8e9fSLars Povlsen enum { 54567b8e9fSLars Povlsen MCP2221_DIR_OUT = 0x00, 55567b8e9fSLars Povlsen MCP2221_DIR_IN = 0x01, 56567b8e9fSLars Povlsen }; 57567b8e9fSLars Povlsen 58567b8e9fSLars Povlsen #define MCP_NGPIO 4 59567b8e9fSLars Povlsen 60567b8e9fSLars Povlsen /* MCP GPIO set command layout */ 61567b8e9fSLars Povlsen struct mcp_set_gpio { 62567b8e9fSLars Povlsen u8 cmd; 63567b8e9fSLars Povlsen u8 dummy; 64567b8e9fSLars Povlsen struct { 65567b8e9fSLars Povlsen u8 change_value; 66567b8e9fSLars Povlsen u8 value; 67567b8e9fSLars Povlsen u8 change_direction; 68567b8e9fSLars Povlsen u8 direction; 69567b8e9fSLars Povlsen } gpio[MCP_NGPIO]; 70567b8e9fSLars Povlsen } __packed; 71567b8e9fSLars Povlsen 72567b8e9fSLars Povlsen /* MCP GPIO get command layout */ 73567b8e9fSLars Povlsen struct mcp_get_gpio { 74567b8e9fSLars Povlsen u8 cmd; 75567b8e9fSLars Povlsen u8 dummy; 76567b8e9fSLars Povlsen struct { 77567b8e9fSLars Povlsen u8 direction; 78567b8e9fSLars Povlsen u8 value; 79567b8e9fSLars Povlsen } gpio[MCP_NGPIO]; 80567b8e9fSLars Povlsen } __packed; 81567b8e9fSLars Povlsen 8267a95c21SRishi Gupta /* 8367a95c21SRishi Gupta * There is no way to distinguish responses. Therefore next command 8467a95c21SRishi Gupta * is sent only after response to previous has been received. Mutex 8567a95c21SRishi Gupta * lock is used for this purpose mainly. 8667a95c21SRishi Gupta */ 8767a95c21SRishi Gupta struct mcp2221 { 8867a95c21SRishi Gupta struct hid_device *hdev; 8967a95c21SRishi Gupta struct i2c_adapter adapter; 9067a95c21SRishi Gupta struct mutex lock; 9167a95c21SRishi Gupta struct completion wait_in_report; 9267a95c21SRishi Gupta u8 *rxbuf; 9367a95c21SRishi Gupta u8 txbuf[64]; 9467a95c21SRishi Gupta int rxbuf_idx; 9567a95c21SRishi Gupta int status; 9667a95c21SRishi Gupta u8 cur_i2c_clk_div; 97328de1c5SRishi Gupta struct gpio_chip *gc; 98328de1c5SRishi Gupta u8 gp_idx; 99328de1c5SRishi Gupta u8 gpio_dir; 10067a95c21SRishi Gupta }; 10167a95c21SRishi Gupta 10267a95c21SRishi Gupta /* 10367a95c21SRishi Gupta * Default i2c bus clock frequency 400 kHz. Modify this if you 10467a95c21SRishi Gupta * want to set some other frequency (min 50 kHz - max 400 kHz). 10567a95c21SRishi Gupta */ 10667a95c21SRishi Gupta static uint i2c_clk_freq = 400; 10767a95c21SRishi Gupta 10867a95c21SRishi Gupta /* Synchronously send output report to the device */ 10967a95c21SRishi Gupta static int mcp_send_report(struct mcp2221 *mcp, 11067a95c21SRishi Gupta u8 *out_report, size_t len) 11167a95c21SRishi Gupta { 11267a95c21SRishi Gupta u8 *buf; 11367a95c21SRishi Gupta int ret; 11467a95c21SRishi Gupta 11567a95c21SRishi Gupta buf = kmemdup(out_report, len, GFP_KERNEL); 11667a95c21SRishi Gupta if (!buf) 11767a95c21SRishi Gupta return -ENOMEM; 11867a95c21SRishi Gupta 11967a95c21SRishi Gupta /* mcp2221 uses interrupt endpoint for out reports */ 12067a95c21SRishi Gupta ret = hid_hw_output_report(mcp->hdev, buf, len); 12167a95c21SRishi Gupta kfree(buf); 12267a95c21SRishi Gupta 12367a95c21SRishi Gupta if (ret < 0) 12467a95c21SRishi Gupta return ret; 12567a95c21SRishi Gupta return 0; 12667a95c21SRishi Gupta } 12767a95c21SRishi Gupta 12867a95c21SRishi Gupta /* 12967a95c21SRishi Gupta * Send o/p report to the device and wait for i/p report to be 13067a95c21SRishi Gupta * received from the device. If the device does not respond, 13167a95c21SRishi Gupta * we timeout. 13267a95c21SRishi Gupta */ 13367a95c21SRishi Gupta static int mcp_send_data_req_status(struct mcp2221 *mcp, 13467a95c21SRishi Gupta u8 *out_report, int len) 13567a95c21SRishi Gupta { 13667a95c21SRishi Gupta int ret; 13767a95c21SRishi Gupta unsigned long t; 13867a95c21SRishi Gupta 13967a95c21SRishi Gupta reinit_completion(&mcp->wait_in_report); 14067a95c21SRishi Gupta 14167a95c21SRishi Gupta ret = mcp_send_report(mcp, out_report, len); 14267a95c21SRishi Gupta if (ret) 14367a95c21SRishi Gupta return ret; 14467a95c21SRishi Gupta 14567a95c21SRishi Gupta t = wait_for_completion_timeout(&mcp->wait_in_report, 14667a95c21SRishi Gupta msecs_to_jiffies(4000)); 14767a95c21SRishi Gupta if (!t) 14867a95c21SRishi Gupta return -ETIMEDOUT; 14967a95c21SRishi Gupta 15067a95c21SRishi Gupta return mcp->status; 15167a95c21SRishi Gupta } 15267a95c21SRishi Gupta 15367a95c21SRishi Gupta /* Check pass/fail for actual communication with i2c slave */ 15467a95c21SRishi Gupta static int mcp_chk_last_cmd_status(struct mcp2221 *mcp) 15567a95c21SRishi Gupta { 15667a95c21SRishi Gupta memset(mcp->txbuf, 0, 8); 15767a95c21SRishi Gupta mcp->txbuf[0] = MCP2221_I2C_PARAM_OR_STATUS; 15867a95c21SRishi Gupta 15967a95c21SRishi Gupta return mcp_send_data_req_status(mcp, mcp->txbuf, 8); 16067a95c21SRishi Gupta } 16167a95c21SRishi Gupta 16267a95c21SRishi Gupta /* Cancels last command releasing i2c bus just in case occupied */ 16367a95c21SRishi Gupta static int mcp_cancel_last_cmd(struct mcp2221 *mcp) 16467a95c21SRishi Gupta { 16567a95c21SRishi Gupta memset(mcp->txbuf, 0, 8); 16667a95c21SRishi Gupta mcp->txbuf[0] = MCP2221_I2C_PARAM_OR_STATUS; 16767a95c21SRishi Gupta mcp->txbuf[2] = MCP2221_I2C_CANCEL; 16867a95c21SRishi Gupta 16967a95c21SRishi Gupta return mcp_send_data_req_status(mcp, mcp->txbuf, 8); 17067a95c21SRishi Gupta } 17167a95c21SRishi Gupta 17267a95c21SRishi Gupta static int mcp_set_i2c_speed(struct mcp2221 *mcp) 17367a95c21SRishi Gupta { 17467a95c21SRishi Gupta int ret; 17567a95c21SRishi Gupta 17667a95c21SRishi Gupta memset(mcp->txbuf, 0, 8); 17767a95c21SRishi Gupta mcp->txbuf[0] = MCP2221_I2C_PARAM_OR_STATUS; 17867a95c21SRishi Gupta mcp->txbuf[3] = MCP2221_I2C_SET_SPEED; 17967a95c21SRishi Gupta mcp->txbuf[4] = mcp->cur_i2c_clk_div; 18067a95c21SRishi Gupta 18167a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 8); 18267a95c21SRishi Gupta if (ret) { 18367a95c21SRishi Gupta /* Small delay is needed here */ 18467a95c21SRishi Gupta usleep_range(980, 1000); 18567a95c21SRishi Gupta mcp_cancel_last_cmd(mcp); 18667a95c21SRishi Gupta } 18767a95c21SRishi Gupta 18867a95c21SRishi Gupta return 0; 18967a95c21SRishi Gupta } 19067a95c21SRishi Gupta 19167a95c21SRishi Gupta /* 19267a95c21SRishi Gupta * An output report can contain minimum 1 and maximum 60 user data 19367a95c21SRishi Gupta * bytes. If the number of data bytes is more then 60, we send it 19467a95c21SRishi Gupta * in chunks of 60 bytes. Last chunk may contain exactly 60 or less 19567a95c21SRishi Gupta * bytes. Total number of bytes is informed in very first report to 19667a95c21SRishi Gupta * mcp2221, from that point onwards it first collect all the data 19767a95c21SRishi Gupta * from host and then send to i2c slave device. 19867a95c21SRishi Gupta */ 19967a95c21SRishi Gupta static int mcp_i2c_write(struct mcp2221 *mcp, 20067a95c21SRishi Gupta struct i2c_msg *msg, int type, u8 last_status) 20167a95c21SRishi Gupta { 20267a95c21SRishi Gupta int ret, len, idx, sent; 20367a95c21SRishi Gupta 20467a95c21SRishi Gupta idx = 0; 20567a95c21SRishi Gupta sent = 0; 20667a95c21SRishi Gupta if (msg->len < 60) 20767a95c21SRishi Gupta len = msg->len; 20867a95c21SRishi Gupta else 20967a95c21SRishi Gupta len = 60; 21067a95c21SRishi Gupta 21167a95c21SRishi Gupta do { 21267a95c21SRishi Gupta mcp->txbuf[0] = type; 21367a95c21SRishi Gupta mcp->txbuf[1] = msg->len & 0xff; 21467a95c21SRishi Gupta mcp->txbuf[2] = msg->len >> 8; 21567a95c21SRishi Gupta mcp->txbuf[3] = (u8)(msg->addr << 1); 21667a95c21SRishi Gupta 21767a95c21SRishi Gupta memcpy(&mcp->txbuf[4], &msg->buf[idx], len); 21867a95c21SRishi Gupta 21967a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, len + 4); 22067a95c21SRishi Gupta if (ret) 22167a95c21SRishi Gupta return ret; 22267a95c21SRishi Gupta 22367a95c21SRishi Gupta usleep_range(980, 1000); 22467a95c21SRishi Gupta 22567a95c21SRishi Gupta if (last_status) { 22667a95c21SRishi Gupta ret = mcp_chk_last_cmd_status(mcp); 22767a95c21SRishi Gupta if (ret) 22867a95c21SRishi Gupta return ret; 22967a95c21SRishi Gupta } 23067a95c21SRishi Gupta 23167a95c21SRishi Gupta sent = sent + len; 23267a95c21SRishi Gupta if (sent >= msg->len) 23367a95c21SRishi Gupta break; 23467a95c21SRishi Gupta 23567a95c21SRishi Gupta idx = idx + len; 23667a95c21SRishi Gupta if ((msg->len - sent) < 60) 23767a95c21SRishi Gupta len = msg->len - sent; 23867a95c21SRishi Gupta else 23967a95c21SRishi Gupta len = 60; 24067a95c21SRishi Gupta 24167a95c21SRishi Gupta /* 24267a95c21SRishi Gupta * Testing shows delay is needed between successive writes 24367a95c21SRishi Gupta * otherwise next write fails on first-try from i2c core. 24467a95c21SRishi Gupta * This value is obtained through automated stress testing. 24567a95c21SRishi Gupta */ 24667a95c21SRishi Gupta usleep_range(980, 1000); 24767a95c21SRishi Gupta } while (len > 0); 24867a95c21SRishi Gupta 24967a95c21SRishi Gupta return ret; 25067a95c21SRishi Gupta } 25167a95c21SRishi Gupta 25267a95c21SRishi Gupta /* 25367a95c21SRishi Gupta * Device reads all data (0 - 65535 bytes) from i2c slave device and 25467a95c21SRishi Gupta * stores it in device itself. This data is read back from device to 25567a95c21SRishi Gupta * host in multiples of 60 bytes using input reports. 25667a95c21SRishi Gupta */ 25767a95c21SRishi Gupta static int mcp_i2c_smbus_read(struct mcp2221 *mcp, 25867a95c21SRishi Gupta struct i2c_msg *msg, int type, u16 smbus_addr, 25967a95c21SRishi Gupta u8 smbus_len, u8 *smbus_buf) 26067a95c21SRishi Gupta { 26167a95c21SRishi Gupta int ret; 26267a95c21SRishi Gupta u16 total_len; 26367a95c21SRishi Gupta 26467a95c21SRishi Gupta mcp->txbuf[0] = type; 26567a95c21SRishi Gupta if (msg) { 26667a95c21SRishi Gupta mcp->txbuf[1] = msg->len & 0xff; 26767a95c21SRishi Gupta mcp->txbuf[2] = msg->len >> 8; 26867a95c21SRishi Gupta mcp->txbuf[3] = (u8)(msg->addr << 1); 26967a95c21SRishi Gupta total_len = msg->len; 27067a95c21SRishi Gupta mcp->rxbuf = msg->buf; 27167a95c21SRishi Gupta } else { 27267a95c21SRishi Gupta mcp->txbuf[1] = smbus_len; 27367a95c21SRishi Gupta mcp->txbuf[2] = 0; 27467a95c21SRishi Gupta mcp->txbuf[3] = (u8)(smbus_addr << 1); 27567a95c21SRishi Gupta total_len = smbus_len; 27667a95c21SRishi Gupta mcp->rxbuf = smbus_buf; 27767a95c21SRishi Gupta } 27867a95c21SRishi Gupta 27967a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4); 28067a95c21SRishi Gupta if (ret) 28167a95c21SRishi Gupta return ret; 28267a95c21SRishi Gupta 28367a95c21SRishi Gupta mcp->rxbuf_idx = 0; 28467a95c21SRishi Gupta 28567a95c21SRishi Gupta do { 28667a95c21SRishi Gupta memset(mcp->txbuf, 0, 4); 28767a95c21SRishi Gupta mcp->txbuf[0] = MCP2221_I2C_GET_DATA; 28867a95c21SRishi Gupta 28967a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 29067a95c21SRishi Gupta if (ret) 29167a95c21SRishi Gupta return ret; 29267a95c21SRishi Gupta 29367a95c21SRishi Gupta ret = mcp_chk_last_cmd_status(mcp); 29467a95c21SRishi Gupta if (ret) 29567a95c21SRishi Gupta return ret; 29667a95c21SRishi Gupta 29767a95c21SRishi Gupta usleep_range(980, 1000); 29867a95c21SRishi Gupta } while (mcp->rxbuf_idx < total_len); 29967a95c21SRishi Gupta 30067a95c21SRishi Gupta return ret; 30167a95c21SRishi Gupta } 30267a95c21SRishi Gupta 30367a95c21SRishi Gupta static int mcp_i2c_xfer(struct i2c_adapter *adapter, 30467a95c21SRishi Gupta struct i2c_msg msgs[], int num) 30567a95c21SRishi Gupta { 30667a95c21SRishi Gupta int ret; 30767a95c21SRishi Gupta struct mcp2221 *mcp = i2c_get_adapdata(adapter); 30867a95c21SRishi Gupta 30967a95c21SRishi Gupta hid_hw_power(mcp->hdev, PM_HINT_FULLON); 31067a95c21SRishi Gupta 31167a95c21SRishi Gupta mutex_lock(&mcp->lock); 31267a95c21SRishi Gupta 31367a95c21SRishi Gupta /* Setting speed before every transaction is required for mcp2221 */ 31467a95c21SRishi Gupta ret = mcp_set_i2c_speed(mcp); 31567a95c21SRishi Gupta if (ret) 31667a95c21SRishi Gupta goto exit; 31767a95c21SRishi Gupta 31867a95c21SRishi Gupta if (num == 1) { 31967a95c21SRishi Gupta if (msgs->flags & I2C_M_RD) { 32067a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, msgs, MCP2221_I2C_RD_DATA, 32167a95c21SRishi Gupta 0, 0, NULL); 32267a95c21SRishi Gupta } else { 32367a95c21SRishi Gupta ret = mcp_i2c_write(mcp, msgs, MCP2221_I2C_WR_DATA, 1); 32467a95c21SRishi Gupta } 32567a95c21SRishi Gupta if (ret) 32667a95c21SRishi Gupta goto exit; 32767a95c21SRishi Gupta ret = num; 32867a95c21SRishi Gupta } else if (num == 2) { 32967a95c21SRishi Gupta /* Ex transaction; send reg address and read its contents */ 33067a95c21SRishi Gupta if (msgs[0].addr == msgs[1].addr && 33167a95c21SRishi Gupta !(msgs[0].flags & I2C_M_RD) && 33267a95c21SRishi Gupta (msgs[1].flags & I2C_M_RD)) { 33367a95c21SRishi Gupta 33467a95c21SRishi Gupta ret = mcp_i2c_write(mcp, &msgs[0], 33567a95c21SRishi Gupta MCP2221_I2C_WR_NO_STOP, 0); 33667a95c21SRishi Gupta if (ret) 33767a95c21SRishi Gupta goto exit; 33867a95c21SRishi Gupta 33967a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, &msgs[1], 34067a95c21SRishi Gupta MCP2221_I2C_RD_RPT_START, 34167a95c21SRishi Gupta 0, 0, NULL); 34267a95c21SRishi Gupta if (ret) 34367a95c21SRishi Gupta goto exit; 34467a95c21SRishi Gupta ret = num; 34567a95c21SRishi Gupta } else { 34667a95c21SRishi Gupta dev_err(&adapter->dev, 34767a95c21SRishi Gupta "unsupported multi-msg i2c transaction\n"); 34867a95c21SRishi Gupta ret = -EOPNOTSUPP; 34967a95c21SRishi Gupta } 35067a95c21SRishi Gupta } else { 35167a95c21SRishi Gupta dev_err(&adapter->dev, 35267a95c21SRishi Gupta "unsupported multi-msg i2c transaction\n"); 35367a95c21SRishi Gupta ret = -EOPNOTSUPP; 35467a95c21SRishi Gupta } 35567a95c21SRishi Gupta 35667a95c21SRishi Gupta exit: 35767a95c21SRishi Gupta hid_hw_power(mcp->hdev, PM_HINT_NORMAL); 35867a95c21SRishi Gupta mutex_unlock(&mcp->lock); 35967a95c21SRishi Gupta return ret; 36067a95c21SRishi Gupta } 36167a95c21SRishi Gupta 36267a95c21SRishi Gupta static int mcp_smbus_write(struct mcp2221 *mcp, u16 addr, 36367a95c21SRishi Gupta u8 command, u8 *buf, u8 len, int type, 36467a95c21SRishi Gupta u8 last_status) 36567a95c21SRishi Gupta { 36667a95c21SRishi Gupta int data_len, ret; 36767a95c21SRishi Gupta 36867a95c21SRishi Gupta mcp->txbuf[0] = type; 36967a95c21SRishi Gupta mcp->txbuf[1] = len + 1; /* 1 is due to command byte itself */ 37067a95c21SRishi Gupta mcp->txbuf[2] = 0; 37167a95c21SRishi Gupta mcp->txbuf[3] = (u8)(addr << 1); 37267a95c21SRishi Gupta mcp->txbuf[4] = command; 37367a95c21SRishi Gupta 37467a95c21SRishi Gupta switch (len) { 37567a95c21SRishi Gupta case 0: 37667a95c21SRishi Gupta data_len = 5; 37767a95c21SRishi Gupta break; 37867a95c21SRishi Gupta case 1: 37967a95c21SRishi Gupta mcp->txbuf[5] = buf[0]; 38067a95c21SRishi Gupta data_len = 6; 38167a95c21SRishi Gupta break; 38267a95c21SRishi Gupta case 2: 38367a95c21SRishi Gupta mcp->txbuf[5] = buf[0]; 38467a95c21SRishi Gupta mcp->txbuf[6] = buf[1]; 38567a95c21SRishi Gupta data_len = 7; 38667a95c21SRishi Gupta break; 38767a95c21SRishi Gupta default: 38862ac2473SHarshit Mogalapalli if (len > I2C_SMBUS_BLOCK_MAX) 38962ac2473SHarshit Mogalapalli return -EINVAL; 39062ac2473SHarshit Mogalapalli 39167a95c21SRishi Gupta memcpy(&mcp->txbuf[5], buf, len); 39267a95c21SRishi Gupta data_len = len + 5; 39367a95c21SRishi Gupta } 39467a95c21SRishi Gupta 39567a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, data_len); 39667a95c21SRishi Gupta if (ret) 39767a95c21SRishi Gupta return ret; 39867a95c21SRishi Gupta 39967a95c21SRishi Gupta if (last_status) { 40067a95c21SRishi Gupta usleep_range(980, 1000); 40167a95c21SRishi Gupta 40267a95c21SRishi Gupta ret = mcp_chk_last_cmd_status(mcp); 40367a95c21SRishi Gupta if (ret) 40467a95c21SRishi Gupta return ret; 40567a95c21SRishi Gupta } 40667a95c21SRishi Gupta 40767a95c21SRishi Gupta return ret; 40867a95c21SRishi Gupta } 40967a95c21SRishi Gupta 41067a95c21SRishi Gupta static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr, 41167a95c21SRishi Gupta unsigned short flags, char read_write, 41267a95c21SRishi Gupta u8 command, int size, 41367a95c21SRishi Gupta union i2c_smbus_data *data) 41467a95c21SRishi Gupta { 41567a95c21SRishi Gupta int ret; 41667a95c21SRishi Gupta struct mcp2221 *mcp = i2c_get_adapdata(adapter); 41767a95c21SRishi Gupta 41867a95c21SRishi Gupta hid_hw_power(mcp->hdev, PM_HINT_FULLON); 41967a95c21SRishi Gupta 42067a95c21SRishi Gupta mutex_lock(&mcp->lock); 42167a95c21SRishi Gupta 42267a95c21SRishi Gupta ret = mcp_set_i2c_speed(mcp); 42367a95c21SRishi Gupta if (ret) 42467a95c21SRishi Gupta goto exit; 42567a95c21SRishi Gupta 42667a95c21SRishi Gupta switch (size) { 42767a95c21SRishi Gupta 42867a95c21SRishi Gupta case I2C_SMBUS_QUICK: 42967a95c21SRishi Gupta if (read_write == I2C_SMBUS_READ) 43067a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, NULL, MCP2221_I2C_RD_DATA, 43167a95c21SRishi Gupta addr, 0, &data->byte); 43267a95c21SRishi Gupta else 43367a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, NULL, 43467a95c21SRishi Gupta 0, MCP2221_I2C_WR_DATA, 1); 43567a95c21SRishi Gupta break; 43667a95c21SRishi Gupta case I2C_SMBUS_BYTE: 43767a95c21SRishi Gupta if (read_write == I2C_SMBUS_READ) 43867a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, NULL, MCP2221_I2C_RD_DATA, 43967a95c21SRishi Gupta addr, 1, &data->byte); 44067a95c21SRishi Gupta else 44167a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, NULL, 44267a95c21SRishi Gupta 0, MCP2221_I2C_WR_DATA, 1); 44367a95c21SRishi Gupta break; 44467a95c21SRishi Gupta case I2C_SMBUS_BYTE_DATA: 44567a95c21SRishi Gupta if (read_write == I2C_SMBUS_READ) { 44667a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, NULL, 44767a95c21SRishi Gupta 0, MCP2221_I2C_WR_NO_STOP, 0); 44867a95c21SRishi Gupta if (ret) 44967a95c21SRishi Gupta goto exit; 45067a95c21SRishi Gupta 45167a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, NULL, 45267a95c21SRishi Gupta MCP2221_I2C_RD_RPT_START, 45367a95c21SRishi Gupta addr, 1, &data->byte); 45467a95c21SRishi Gupta } else { 45567a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, &data->byte, 45667a95c21SRishi Gupta 1, MCP2221_I2C_WR_DATA, 1); 45767a95c21SRishi Gupta } 45867a95c21SRishi Gupta break; 45967a95c21SRishi Gupta case I2C_SMBUS_WORD_DATA: 46067a95c21SRishi Gupta if (read_write == I2C_SMBUS_READ) { 46167a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, NULL, 46267a95c21SRishi Gupta 0, MCP2221_I2C_WR_NO_STOP, 0); 46367a95c21SRishi Gupta if (ret) 46467a95c21SRishi Gupta goto exit; 46567a95c21SRishi Gupta 46667a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, NULL, 46767a95c21SRishi Gupta MCP2221_I2C_RD_RPT_START, 46867a95c21SRishi Gupta addr, 2, (u8 *)&data->word); 46967a95c21SRishi Gupta } else { 47067a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, 47167a95c21SRishi Gupta (u8 *)&data->word, 2, 47267a95c21SRishi Gupta MCP2221_I2C_WR_DATA, 1); 47367a95c21SRishi Gupta } 47467a95c21SRishi Gupta break; 47567a95c21SRishi Gupta case I2C_SMBUS_BLOCK_DATA: 47667a95c21SRishi Gupta if (read_write == I2C_SMBUS_READ) { 47767a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, NULL, 47867a95c21SRishi Gupta 0, MCP2221_I2C_WR_NO_STOP, 1); 47967a95c21SRishi Gupta if (ret) 48067a95c21SRishi Gupta goto exit; 48167a95c21SRishi Gupta 48267a95c21SRishi Gupta mcp->rxbuf_idx = 0; 48367a95c21SRishi Gupta mcp->rxbuf = data->block; 48467a95c21SRishi Gupta mcp->txbuf[0] = MCP2221_I2C_GET_DATA; 48567a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 48667a95c21SRishi Gupta if (ret) 48767a95c21SRishi Gupta goto exit; 48867a95c21SRishi Gupta } else { 48967a95c21SRishi Gupta if (!data->block[0]) { 49067a95c21SRishi Gupta ret = -EINVAL; 49167a95c21SRishi Gupta goto exit; 49267a95c21SRishi Gupta } 49367a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, data->block, 49467a95c21SRishi Gupta data->block[0] + 1, 49567a95c21SRishi Gupta MCP2221_I2C_WR_DATA, 1); 49667a95c21SRishi Gupta } 49767a95c21SRishi Gupta break; 49867a95c21SRishi Gupta case I2C_SMBUS_I2C_BLOCK_DATA: 49967a95c21SRishi Gupta if (read_write == I2C_SMBUS_READ) { 50067a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, NULL, 50167a95c21SRishi Gupta 0, MCP2221_I2C_WR_NO_STOP, 1); 50267a95c21SRishi Gupta if (ret) 50367a95c21SRishi Gupta goto exit; 50467a95c21SRishi Gupta 50567a95c21SRishi Gupta mcp->rxbuf_idx = 0; 50667a95c21SRishi Gupta mcp->rxbuf = data->block; 50767a95c21SRishi Gupta mcp->txbuf[0] = MCP2221_I2C_GET_DATA; 50867a95c21SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 50967a95c21SRishi Gupta if (ret) 51067a95c21SRishi Gupta goto exit; 51167a95c21SRishi Gupta } else { 51267a95c21SRishi Gupta if (!data->block[0]) { 51367a95c21SRishi Gupta ret = -EINVAL; 51467a95c21SRishi Gupta goto exit; 51567a95c21SRishi Gupta } 51667a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, 51767a95c21SRishi Gupta &data->block[1], data->block[0], 51867a95c21SRishi Gupta MCP2221_I2C_WR_DATA, 1); 51967a95c21SRishi Gupta } 52067a95c21SRishi Gupta break; 52167a95c21SRishi Gupta case I2C_SMBUS_PROC_CALL: 52267a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, 52367a95c21SRishi Gupta (u8 *)&data->word, 52467a95c21SRishi Gupta 2, MCP2221_I2C_WR_NO_STOP, 0); 52567a95c21SRishi Gupta if (ret) 52667a95c21SRishi Gupta goto exit; 52767a95c21SRishi Gupta 52867a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, NULL, 52967a95c21SRishi Gupta MCP2221_I2C_RD_RPT_START, 53067a95c21SRishi Gupta addr, 2, (u8 *)&data->word); 53167a95c21SRishi Gupta break; 53267a95c21SRishi Gupta case I2C_SMBUS_BLOCK_PROC_CALL: 53367a95c21SRishi Gupta ret = mcp_smbus_write(mcp, addr, command, data->block, 53467a95c21SRishi Gupta data->block[0] + 1, 53567a95c21SRishi Gupta MCP2221_I2C_WR_NO_STOP, 0); 53667a95c21SRishi Gupta if (ret) 53767a95c21SRishi Gupta goto exit; 53867a95c21SRishi Gupta 53967a95c21SRishi Gupta ret = mcp_i2c_smbus_read(mcp, NULL, 54067a95c21SRishi Gupta MCP2221_I2C_RD_RPT_START, 54167a95c21SRishi Gupta addr, I2C_SMBUS_BLOCK_MAX, 54267a95c21SRishi Gupta data->block); 54367a95c21SRishi Gupta break; 54467a95c21SRishi Gupta default: 54567a95c21SRishi Gupta dev_err(&mcp->adapter.dev, 54667a95c21SRishi Gupta "unsupported smbus transaction size:%d\n", size); 54767a95c21SRishi Gupta ret = -EOPNOTSUPP; 54867a95c21SRishi Gupta } 54967a95c21SRishi Gupta 55067a95c21SRishi Gupta exit: 55167a95c21SRishi Gupta hid_hw_power(mcp->hdev, PM_HINT_NORMAL); 55267a95c21SRishi Gupta mutex_unlock(&mcp->lock); 55367a95c21SRishi Gupta return ret; 55467a95c21SRishi Gupta } 55567a95c21SRishi Gupta 55667a95c21SRishi Gupta static u32 mcp_i2c_func(struct i2c_adapter *adapter) 55767a95c21SRishi Gupta { 55867a95c21SRishi Gupta return I2C_FUNC_I2C | 55967a95c21SRishi Gupta I2C_FUNC_SMBUS_READ_BLOCK_DATA | 56067a95c21SRishi Gupta I2C_FUNC_SMBUS_BLOCK_PROC_CALL | 56167a95c21SRishi Gupta (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_PEC); 56267a95c21SRishi Gupta } 56367a95c21SRishi Gupta 56467a95c21SRishi Gupta static const struct i2c_algorithm mcp_i2c_algo = { 56567a95c21SRishi Gupta .master_xfer = mcp_i2c_xfer, 56667a95c21SRishi Gupta .smbus_xfer = mcp_smbus_xfer, 56767a95c21SRishi Gupta .functionality = mcp_i2c_func, 56867a95c21SRishi Gupta }; 56967a95c21SRishi Gupta 570328de1c5SRishi Gupta static int mcp_gpio_get(struct gpio_chip *gc, 571328de1c5SRishi Gupta unsigned int offset) 572328de1c5SRishi Gupta { 573328de1c5SRishi Gupta int ret; 574328de1c5SRishi Gupta struct mcp2221 *mcp = gpiochip_get_data(gc); 575328de1c5SRishi Gupta 576328de1c5SRishi Gupta mcp->txbuf[0] = MCP2221_GPIO_GET; 577328de1c5SRishi Gupta 578567b8e9fSLars Povlsen mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].value); 579328de1c5SRishi Gupta 580328de1c5SRishi Gupta mutex_lock(&mcp->lock); 581328de1c5SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 582328de1c5SRishi Gupta mutex_unlock(&mcp->lock); 583328de1c5SRishi Gupta 584328de1c5SRishi Gupta return ret; 585328de1c5SRishi Gupta } 586328de1c5SRishi Gupta 587328de1c5SRishi Gupta static void mcp_gpio_set(struct gpio_chip *gc, 588328de1c5SRishi Gupta unsigned int offset, int value) 589328de1c5SRishi Gupta { 590328de1c5SRishi Gupta struct mcp2221 *mcp = gpiochip_get_data(gc); 591328de1c5SRishi Gupta 592328de1c5SRishi Gupta memset(mcp->txbuf, 0, 18); 593328de1c5SRishi Gupta mcp->txbuf[0] = MCP2221_GPIO_SET; 594328de1c5SRishi Gupta 595567b8e9fSLars Povlsen mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].value); 596328de1c5SRishi Gupta 597328de1c5SRishi Gupta mcp->txbuf[mcp->gp_idx - 1] = 1; 598328de1c5SRishi Gupta mcp->txbuf[mcp->gp_idx] = !!value; 599328de1c5SRishi Gupta 600328de1c5SRishi Gupta mutex_lock(&mcp->lock); 601328de1c5SRishi Gupta mcp_send_data_req_status(mcp, mcp->txbuf, 18); 602328de1c5SRishi Gupta mutex_unlock(&mcp->lock); 603328de1c5SRishi Gupta } 604328de1c5SRishi Gupta 605328de1c5SRishi Gupta static int mcp_gpio_dir_set(struct mcp2221 *mcp, 606328de1c5SRishi Gupta unsigned int offset, u8 val) 607328de1c5SRishi Gupta { 608328de1c5SRishi Gupta memset(mcp->txbuf, 0, 18); 609328de1c5SRishi Gupta mcp->txbuf[0] = MCP2221_GPIO_SET; 610328de1c5SRishi Gupta 611567b8e9fSLars Povlsen mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].direction); 612328de1c5SRishi Gupta 613328de1c5SRishi Gupta mcp->txbuf[mcp->gp_idx - 1] = 1; 614328de1c5SRishi Gupta mcp->txbuf[mcp->gp_idx] = val; 615328de1c5SRishi Gupta 616328de1c5SRishi Gupta return mcp_send_data_req_status(mcp, mcp->txbuf, 18); 617328de1c5SRishi Gupta } 618328de1c5SRishi Gupta 619328de1c5SRishi Gupta static int mcp_gpio_direction_input(struct gpio_chip *gc, 620328de1c5SRishi Gupta unsigned int offset) 621328de1c5SRishi Gupta { 622328de1c5SRishi Gupta int ret; 623328de1c5SRishi Gupta struct mcp2221 *mcp = gpiochip_get_data(gc); 624328de1c5SRishi Gupta 625328de1c5SRishi Gupta mutex_lock(&mcp->lock); 626567b8e9fSLars Povlsen ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_IN); 627328de1c5SRishi Gupta mutex_unlock(&mcp->lock); 628328de1c5SRishi Gupta 629328de1c5SRishi Gupta return ret; 630328de1c5SRishi Gupta } 631328de1c5SRishi Gupta 632328de1c5SRishi Gupta static int mcp_gpio_direction_output(struct gpio_chip *gc, 633328de1c5SRishi Gupta unsigned int offset, int value) 634328de1c5SRishi Gupta { 635328de1c5SRishi Gupta int ret; 636328de1c5SRishi Gupta struct mcp2221 *mcp = gpiochip_get_data(gc); 637328de1c5SRishi Gupta 638328de1c5SRishi Gupta mutex_lock(&mcp->lock); 639567b8e9fSLars Povlsen ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_OUT); 640328de1c5SRishi Gupta mutex_unlock(&mcp->lock); 641328de1c5SRishi Gupta 642328de1c5SRishi Gupta /* Can't configure as output, bailout early */ 643328de1c5SRishi Gupta if (ret) 644328de1c5SRishi Gupta return ret; 645328de1c5SRishi Gupta 646328de1c5SRishi Gupta mcp_gpio_set(gc, offset, value); 647328de1c5SRishi Gupta 648328de1c5SRishi Gupta return 0; 649328de1c5SRishi Gupta } 650328de1c5SRishi Gupta 651328de1c5SRishi Gupta static int mcp_gpio_get_direction(struct gpio_chip *gc, 652328de1c5SRishi Gupta unsigned int offset) 653328de1c5SRishi Gupta { 654328de1c5SRishi Gupta int ret; 655328de1c5SRishi Gupta struct mcp2221 *mcp = gpiochip_get_data(gc); 656328de1c5SRishi Gupta 657328de1c5SRishi Gupta mcp->txbuf[0] = MCP2221_GPIO_GET; 658328de1c5SRishi Gupta 659567b8e9fSLars Povlsen mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].direction); 660328de1c5SRishi Gupta 661328de1c5SRishi Gupta mutex_lock(&mcp->lock); 662328de1c5SRishi Gupta ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 663328de1c5SRishi Gupta mutex_unlock(&mcp->lock); 664328de1c5SRishi Gupta 665328de1c5SRishi Gupta if (ret) 666328de1c5SRishi Gupta return ret; 667328de1c5SRishi Gupta 668567b8e9fSLars Povlsen if (mcp->gpio_dir == MCP2221_DIR_IN) 669328de1c5SRishi Gupta return GPIO_LINE_DIRECTION_IN; 670328de1c5SRishi Gupta 671328de1c5SRishi Gupta return GPIO_LINE_DIRECTION_OUT; 672328de1c5SRishi Gupta } 673328de1c5SRishi Gupta 67467a95c21SRishi Gupta /* Gives current state of i2c engine inside mcp2221 */ 67567a95c21SRishi Gupta static int mcp_get_i2c_eng_state(struct mcp2221 *mcp, 67667a95c21SRishi Gupta u8 *data, u8 idx) 67767a95c21SRishi Gupta { 67867a95c21SRishi Gupta int ret; 67967a95c21SRishi Gupta 68067a95c21SRishi Gupta switch (data[idx]) { 68167a95c21SRishi Gupta case MCP2221_I2C_WRADDRL_NACK: 68267a95c21SRishi Gupta case MCP2221_I2C_WRADDRL_SEND: 68367a95c21SRishi Gupta ret = -ENXIO; 68467a95c21SRishi Gupta break; 68567a95c21SRishi Gupta case MCP2221_I2C_START_TOUT: 68667a95c21SRishi Gupta case MCP2221_I2C_STOP_TOUT: 68767a95c21SRishi Gupta case MCP2221_I2C_WRADDRL_TOUT: 68867a95c21SRishi Gupta case MCP2221_I2C_WRDATA_TOUT: 68967a95c21SRishi Gupta ret = -ETIMEDOUT; 69067a95c21SRishi Gupta break; 69167a95c21SRishi Gupta case MCP2221_I2C_ENG_BUSY: 69267a95c21SRishi Gupta ret = -EAGAIN; 69367a95c21SRishi Gupta break; 69467a95c21SRishi Gupta case MCP2221_SUCCESS: 69567a95c21SRishi Gupta ret = 0x00; 69667a95c21SRishi Gupta break; 69767a95c21SRishi Gupta default: 69867a95c21SRishi Gupta ret = -EIO; 69967a95c21SRishi Gupta } 70067a95c21SRishi Gupta 70167a95c21SRishi Gupta return ret; 70267a95c21SRishi Gupta } 70367a95c21SRishi Gupta 70467a95c21SRishi Gupta /* 70567a95c21SRishi Gupta * MCP2221 uses interrupt endpoint for input reports. This function 70667a95c21SRishi Gupta * is called by HID layer when it receives i/p report from mcp2221, 70767a95c21SRishi Gupta * which is actually a response to the previously sent command. 70867a95c21SRishi Gupta * 70967a95c21SRishi Gupta * MCP2221A firmware specific return codes are parsed and 0 or 71067a95c21SRishi Gupta * appropriate negative error code is returned. Delayed response 71167a95c21SRishi Gupta * results in timeout error and stray reponses results in -EIO. 71267a95c21SRishi Gupta */ 71367a95c21SRishi Gupta static int mcp2221_raw_event(struct hid_device *hdev, 71467a95c21SRishi Gupta struct hid_report *report, u8 *data, int size) 71567a95c21SRishi Gupta { 71667a95c21SRishi Gupta u8 *buf; 71767a95c21SRishi Gupta struct mcp2221 *mcp = hid_get_drvdata(hdev); 71867a95c21SRishi Gupta 71967a95c21SRishi Gupta switch (data[0]) { 72067a95c21SRishi Gupta 72167a95c21SRishi Gupta case MCP2221_I2C_WR_DATA: 72267a95c21SRishi Gupta case MCP2221_I2C_WR_NO_STOP: 72367a95c21SRishi Gupta case MCP2221_I2C_RD_DATA: 72467a95c21SRishi Gupta case MCP2221_I2C_RD_RPT_START: 72567a95c21SRishi Gupta switch (data[1]) { 72667a95c21SRishi Gupta case MCP2221_SUCCESS: 72767a95c21SRishi Gupta mcp->status = 0; 72867a95c21SRishi Gupta break; 72967a95c21SRishi Gupta default: 73067a95c21SRishi Gupta mcp->status = mcp_get_i2c_eng_state(mcp, data, 2); 73167a95c21SRishi Gupta } 73267a95c21SRishi Gupta complete(&mcp->wait_in_report); 73367a95c21SRishi Gupta break; 73467a95c21SRishi Gupta 73567a95c21SRishi Gupta case MCP2221_I2C_PARAM_OR_STATUS: 73667a95c21SRishi Gupta switch (data[1]) { 73767a95c21SRishi Gupta case MCP2221_SUCCESS: 73867a95c21SRishi Gupta if ((mcp->txbuf[3] == MCP2221_I2C_SET_SPEED) && 73967a95c21SRishi Gupta (data[3] != MCP2221_I2C_SET_SPEED)) { 74067a95c21SRishi Gupta mcp->status = -EAGAIN; 74167a95c21SRishi Gupta break; 74267a95c21SRishi Gupta } 74367a95c21SRishi Gupta if (data[20] & MCP2221_I2C_MASK_ADDR_NACK) { 74467a95c21SRishi Gupta mcp->status = -ENXIO; 74567a95c21SRishi Gupta break; 74667a95c21SRishi Gupta } 74767a95c21SRishi Gupta mcp->status = mcp_get_i2c_eng_state(mcp, data, 8); 74867a95c21SRishi Gupta break; 74967a95c21SRishi Gupta default: 75067a95c21SRishi Gupta mcp->status = -EIO; 75167a95c21SRishi Gupta } 75267a95c21SRishi Gupta complete(&mcp->wait_in_report); 75367a95c21SRishi Gupta break; 75467a95c21SRishi Gupta 75567a95c21SRishi Gupta case MCP2221_I2C_GET_DATA: 75667a95c21SRishi Gupta switch (data[1]) { 75767a95c21SRishi Gupta case MCP2221_SUCCESS: 75867a95c21SRishi Gupta if (data[2] == MCP2221_I2C_ADDR_NACK) { 75967a95c21SRishi Gupta mcp->status = -ENXIO; 76067a95c21SRishi Gupta break; 76167a95c21SRishi Gupta } 76267a95c21SRishi Gupta if (!mcp_get_i2c_eng_state(mcp, data, 2) 76367a95c21SRishi Gupta && (data[3] == 0)) { 76467a95c21SRishi Gupta mcp->status = 0; 76567a95c21SRishi Gupta break; 76667a95c21SRishi Gupta } 76767a95c21SRishi Gupta if (data[3] == 127) { 76867a95c21SRishi Gupta mcp->status = -EIO; 76967a95c21SRishi Gupta break; 77067a95c21SRishi Gupta } 77167a95c21SRishi Gupta if (data[2] == MCP2221_I2C_READ_COMPL) { 77267a95c21SRishi Gupta buf = mcp->rxbuf; 77367a95c21SRishi Gupta memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]); 77467a95c21SRishi Gupta mcp->rxbuf_idx = mcp->rxbuf_idx + data[3]; 77567a95c21SRishi Gupta mcp->status = 0; 77667a95c21SRishi Gupta break; 77767a95c21SRishi Gupta } 77867a95c21SRishi Gupta mcp->status = -EIO; 77967a95c21SRishi Gupta break; 78067a95c21SRishi Gupta default: 78167a95c21SRishi Gupta mcp->status = -EIO; 78267a95c21SRishi Gupta } 78367a95c21SRishi Gupta complete(&mcp->wait_in_report); 78467a95c21SRishi Gupta break; 78567a95c21SRishi Gupta 786328de1c5SRishi Gupta case MCP2221_GPIO_GET: 787328de1c5SRishi Gupta switch (data[1]) { 788328de1c5SRishi Gupta case MCP2221_SUCCESS: 789328de1c5SRishi Gupta if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) || 790328de1c5SRishi Gupta (data[mcp->gp_idx + 1] == MCP2221_ALT_F_NOT_GPIOD)) { 791328de1c5SRishi Gupta mcp->status = -ENOENT; 792328de1c5SRishi Gupta } else { 793328de1c5SRishi Gupta mcp->status = !!data[mcp->gp_idx]; 794567b8e9fSLars Povlsen mcp->gpio_dir = data[mcp->gp_idx + 1]; 795328de1c5SRishi Gupta } 796328de1c5SRishi Gupta break; 797328de1c5SRishi Gupta default: 798328de1c5SRishi Gupta mcp->status = -EAGAIN; 799328de1c5SRishi Gupta } 800328de1c5SRishi Gupta complete(&mcp->wait_in_report); 801328de1c5SRishi Gupta break; 802328de1c5SRishi Gupta 803328de1c5SRishi Gupta case MCP2221_GPIO_SET: 804328de1c5SRishi Gupta switch (data[1]) { 805328de1c5SRishi Gupta case MCP2221_SUCCESS: 806328de1c5SRishi Gupta if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) || 807328de1c5SRishi Gupta (data[mcp->gp_idx - 1] == MCP2221_ALT_F_NOT_GPIOV)) { 808328de1c5SRishi Gupta mcp->status = -ENOENT; 809328de1c5SRishi Gupta } else { 810328de1c5SRishi Gupta mcp->status = 0; 811328de1c5SRishi Gupta } 812328de1c5SRishi Gupta break; 813328de1c5SRishi Gupta default: 814328de1c5SRishi Gupta mcp->status = -EAGAIN; 815328de1c5SRishi Gupta } 816328de1c5SRishi Gupta complete(&mcp->wait_in_report); 817328de1c5SRishi Gupta break; 818328de1c5SRishi Gupta 81967a95c21SRishi Gupta default: 82067a95c21SRishi Gupta mcp->status = -EIO; 82167a95c21SRishi Gupta complete(&mcp->wait_in_report); 82267a95c21SRishi Gupta } 82367a95c21SRishi Gupta 82467a95c21SRishi Gupta return 1; 82567a95c21SRishi Gupta } 82667a95c21SRishi Gupta 827deb3b88bSMatt Ranostay /* Device resource managed function for HID unregistration */ 828deb3b88bSMatt Ranostay static void mcp2221_hid_unregister(void *ptr) 829deb3b88bSMatt Ranostay { 830deb3b88bSMatt Ranostay struct hid_device *hdev = ptr; 831deb3b88bSMatt Ranostay 832deb3b88bSMatt Ranostay hid_hw_close(hdev); 833deb3b88bSMatt Ranostay hid_hw_stop(hdev); 834deb3b88bSMatt Ranostay } 835deb3b88bSMatt Ranostay 836deb3b88bSMatt Ranostay /* This is needed to be sure hid_hw_stop() isn't called twice by the subsystem */ 837deb3b88bSMatt Ranostay static void mcp2221_remove(struct hid_device *hdev) 838deb3b88bSMatt Ranostay { 839deb3b88bSMatt Ranostay } 840deb3b88bSMatt Ranostay 84167a95c21SRishi Gupta static int mcp2221_probe(struct hid_device *hdev, 84267a95c21SRishi Gupta const struct hid_device_id *id) 84367a95c21SRishi Gupta { 84467a95c21SRishi Gupta int ret; 84567a95c21SRishi Gupta struct mcp2221 *mcp; 84667a95c21SRishi Gupta 84767a95c21SRishi Gupta mcp = devm_kzalloc(&hdev->dev, sizeof(*mcp), GFP_KERNEL); 84867a95c21SRishi Gupta if (!mcp) 84967a95c21SRishi Gupta return -ENOMEM; 85067a95c21SRishi Gupta 85167a95c21SRishi Gupta ret = hid_parse(hdev); 85267a95c21SRishi Gupta if (ret) { 85367a95c21SRishi Gupta hid_err(hdev, "can't parse reports\n"); 85467a95c21SRishi Gupta return ret; 85567a95c21SRishi Gupta } 85667a95c21SRishi Gupta 85767a95c21SRishi Gupta ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 85867a95c21SRishi Gupta if (ret) { 85967a95c21SRishi Gupta hid_err(hdev, "can't start hardware\n"); 86067a95c21SRishi Gupta return ret; 86167a95c21SRishi Gupta } 86267a95c21SRishi Gupta 86367a95c21SRishi Gupta ret = hid_hw_open(hdev); 86467a95c21SRishi Gupta if (ret) { 86567a95c21SRishi Gupta hid_err(hdev, "can't open device\n"); 866deb3b88bSMatt Ranostay hid_hw_stop(hdev); 867deb3b88bSMatt Ranostay return ret; 86867a95c21SRishi Gupta } 86967a95c21SRishi Gupta 87067a95c21SRishi Gupta mutex_init(&mcp->lock); 87167a95c21SRishi Gupta init_completion(&mcp->wait_in_report); 87267a95c21SRishi Gupta hid_set_drvdata(hdev, mcp); 87367a95c21SRishi Gupta mcp->hdev = hdev; 87467a95c21SRishi Gupta 875deb3b88bSMatt Ranostay ret = devm_add_action_or_reset(&hdev->dev, mcp2221_hid_unregister, hdev); 876deb3b88bSMatt Ranostay if (ret) 877deb3b88bSMatt Ranostay return ret; 878deb3b88bSMatt Ranostay 87967a95c21SRishi Gupta /* Set I2C bus clock diviser */ 88067a95c21SRishi Gupta if (i2c_clk_freq > 400) 88167a95c21SRishi Gupta i2c_clk_freq = 400; 88267a95c21SRishi Gupta if (i2c_clk_freq < 50) 88367a95c21SRishi Gupta i2c_clk_freq = 50; 88467a95c21SRishi Gupta mcp->cur_i2c_clk_div = (12000000 / (i2c_clk_freq * 1000)) - 3; 88567a95c21SRishi Gupta 88667a95c21SRishi Gupta mcp->adapter.owner = THIS_MODULE; 88767a95c21SRishi Gupta mcp->adapter.class = I2C_CLASS_HWMON; 88867a95c21SRishi Gupta mcp->adapter.algo = &mcp_i2c_algo; 88967a95c21SRishi Gupta mcp->adapter.retries = 1; 89067a95c21SRishi Gupta mcp->adapter.dev.parent = &hdev->dev; 89167a95c21SRishi Gupta snprintf(mcp->adapter.name, sizeof(mcp->adapter.name), 89267a95c21SRishi Gupta "MCP2221 usb-i2c bridge on hidraw%d", 89367a95c21SRishi Gupta ((struct hidraw *)hdev->hidraw)->minor); 89467a95c21SRishi Gupta 895deb3b88bSMatt Ranostay ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter); 89667a95c21SRishi Gupta if (ret) { 89767a95c21SRishi Gupta hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret); 898deb3b88bSMatt Ranostay return ret; 89967a95c21SRishi Gupta } 90067a95c21SRishi Gupta i2c_set_adapdata(&mcp->adapter, mcp); 90167a95c21SRishi Gupta 902328de1c5SRishi Gupta /* Setup GPIO chip */ 903328de1c5SRishi Gupta mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL); 904deb3b88bSMatt Ranostay if (!mcp->gc) 905deb3b88bSMatt Ranostay return -ENOMEM; 906328de1c5SRishi Gupta 907328de1c5SRishi Gupta mcp->gc->label = "mcp2221_gpio"; 908328de1c5SRishi Gupta mcp->gc->direction_input = mcp_gpio_direction_input; 909328de1c5SRishi Gupta mcp->gc->direction_output = mcp_gpio_direction_output; 910328de1c5SRishi Gupta mcp->gc->get_direction = mcp_gpio_get_direction; 911328de1c5SRishi Gupta mcp->gc->set = mcp_gpio_set; 912328de1c5SRishi Gupta mcp->gc->get = mcp_gpio_get; 913567b8e9fSLars Povlsen mcp->gc->ngpio = MCP_NGPIO; 914328de1c5SRishi Gupta mcp->gc->base = -1; 915328de1c5SRishi Gupta mcp->gc->can_sleep = 1; 916328de1c5SRishi Gupta mcp->gc->parent = &hdev->dev; 917328de1c5SRishi Gupta 918*ea418b35SMatt Ranostay #if IS_REACHABLE(CONFIG_GPIOLIB) 919328de1c5SRishi Gupta ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp); 920328de1c5SRishi Gupta if (ret) 921deb3b88bSMatt Ranostay return ret; 922*ea418b35SMatt Ranostay #endif 923328de1c5SRishi Gupta 92467a95c21SRishi Gupta return 0; 92567a95c21SRishi Gupta } 92667a95c21SRishi Gupta 92767a95c21SRishi Gupta static const struct hid_device_id mcp2221_devices[] = { 92867a95c21SRishi Gupta { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_MCP2221) }, 92967a95c21SRishi Gupta { } 93067a95c21SRishi Gupta }; 93167a95c21SRishi Gupta MODULE_DEVICE_TABLE(hid, mcp2221_devices); 93267a95c21SRishi Gupta 93367a95c21SRishi Gupta static struct hid_driver mcp2221_driver = { 93467a95c21SRishi Gupta .name = "mcp2221", 93567a95c21SRishi Gupta .id_table = mcp2221_devices, 93667a95c21SRishi Gupta .probe = mcp2221_probe, 93767a95c21SRishi Gupta .remove = mcp2221_remove, 93867a95c21SRishi Gupta .raw_event = mcp2221_raw_event, 93967a95c21SRishi Gupta }; 94067a95c21SRishi Gupta 94167a95c21SRishi Gupta /* Register with HID core */ 94267a95c21SRishi Gupta module_hid_driver(mcp2221_driver); 94367a95c21SRishi Gupta 94467a95c21SRishi Gupta MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>"); 94567a95c21SRishi Gupta MODULE_DESCRIPTION("MCP2221 Microchip HID USB to I2C master bridge"); 94667a95c21SRishi Gupta MODULE_LICENSE("GPL v2"); 947