^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2015 - 2016 Red Hat, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2011, 2012 Synaptics Incorporated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011 Unixphere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kconfig.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/lockdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/rmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "rmi_driver.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define SMB_PROTOCOL_VERSION_ADDRESS 0xfd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define SMB_MAX_COUNT 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define RMI_SMB2_MAP_SIZE 8 /* 8 entry of 4 bytes each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define RMI_SMB2_MAP_FLAGS_WE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct mapping_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) __le16 rmiaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u8 readcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct rmi_smb_xport {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct rmi_transport_dev xport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct mutex page_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u8 table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct mutex mappingtable_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct mapping_table_entry mapping_table[RMI_SMB2_MAP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int rmi_smb_get_version(struct rmi_smb_xport *rmi_smb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct i2c_client *client = rmi_smb->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Check if for SMBus new version device by reading version byte. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) retval = i2c_smbus_read_byte_data(client, SMB_PROTOCOL_VERSION_ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) dev_err(&client->dev, "failed to get SMBus version number!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return retval + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* SMB block write - wrapper over ic2_smb_write_block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int smb_block_write(struct rmi_transport_dev *xport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u8 commandcode, const void *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct rmi_smb_xport *rmi_smb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) container_of(xport, struct rmi_smb_xport, xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct i2c_client *client = rmi_smb->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) retval = i2c_smbus_write_block_data(client, commandcode, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) rmi_dbg(RMI_DEBUG_XPORT, &client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "wrote %zd bytes at %#04x: %d (%*ph)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) len, commandcode, retval, (int)len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * The function to get command code for smbus operations and keeps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * records to the driver mapping table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int rmi_smb_get_command_code(struct rmi_transport_dev *xport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u16 rmiaddr, int bytecount, bool isread, u8 *commandcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct rmi_smb_xport *rmi_smb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) container_of(xport, struct rmi_smb_xport, xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct mapping_table_entry new_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mutex_lock(&rmi_smb->mappingtable_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) for (i = 0; i < RMI_SMB2_MAP_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct mapping_table_entry *entry = &rmi_smb->mapping_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (le16_to_cpu(entry->rmiaddr) == rmiaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (isread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (entry->readcount == bytecount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (entry->flags & RMI_SMB2_MAP_FLAGS_WE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) i = rmi_smb->table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) rmi_smb->table_index = (i + 1) % RMI_SMB2_MAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* constructs mapping table data entry. 4 bytes each entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) memset(&new_map, 0, sizeof(new_map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) new_map.rmiaddr = cpu_to_le16(rmiaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) new_map.readcount = bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) new_map.flags = !isread ? RMI_SMB2_MAP_FLAGS_WE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) retval = smb_block_write(xport, i + 0x80, &new_map, sizeof(new_map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * if not written to device mapping table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * clear the driver mapping table records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) memset(&new_map, 0, sizeof(new_map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* save to the driver level mapping table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rmi_smb->mapping_table[i] = new_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) mutex_unlock(&rmi_smb->mappingtable_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *commandcode = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int rmi_smb_write_block(struct rmi_transport_dev *xport, u16 rmiaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) const void *databuff, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u8 commandcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct rmi_smb_xport *rmi_smb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) container_of(xport, struct rmi_smb_xport, xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int cur_len = (int)len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mutex_lock(&rmi_smb->page_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) while (cur_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * break into 32 bytes chunks to write get command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int block_len = min_t(int, len, SMB_MAX_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) retval = rmi_smb_get_command_code(xport, rmiaddr, block_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) false, &commandcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) retval = smb_block_write(xport, commandcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) databuff, block_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* prepare to write next block of bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) cur_len -= SMB_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) databuff += SMB_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rmiaddr += SMB_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) mutex_unlock(&rmi_smb->page_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* SMB block read - wrapper over ic2_smb_read_block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int smb_block_read(struct rmi_transport_dev *xport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 commandcode, void *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct rmi_smb_xport *rmi_smb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) container_of(xport, struct rmi_smb_xport, xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct i2c_client *client = rmi_smb->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) retval = i2c_smbus_read_block_data(client, commandcode, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static int rmi_smb_read_block(struct rmi_transport_dev *xport, u16 rmiaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void *databuff, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct rmi_smb_xport *rmi_smb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) container_of(xport, struct rmi_smb_xport, xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 commandcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int cur_len = (int)len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) mutex_lock(&rmi_smb->page_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) memset(databuff, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) while (cur_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* break into 32 bytes chunks to write get command code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int block_len = min_t(int, cur_len, SMB_MAX_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) retval = rmi_smb_get_command_code(xport, rmiaddr, block_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) true, &commandcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) retval = smb_block_read(xport, commandcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) databuff, block_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* prepare to read next block of bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cur_len -= SMB_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) databuff += SMB_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rmiaddr += SMB_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mutex_unlock(&rmi_smb->page_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void rmi_smb_clear_state(struct rmi_smb_xport *rmi_smb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* the mapping table has been flushed, discard the current one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) mutex_lock(&rmi_smb->mappingtable_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) memset(rmi_smb->mapping_table, 0, sizeof(rmi_smb->mapping_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mutex_unlock(&rmi_smb->mappingtable_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int rmi_smb_enable_smbus_mode(struct rmi_smb_xport *rmi_smb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* we need to get the smbus version to activate the touchpad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) retval = rmi_smb_get_version(rmi_smb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int rmi_smb_reset(struct rmi_transport_dev *xport, u16 reset_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct rmi_smb_xport *rmi_smb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) container_of(xport, struct rmi_smb_xport, xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rmi_smb_clear_state(rmi_smb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * we do not call the actual reset command, it has to be handled in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * PS/2 or there will be races between PS/2 and SMBus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * PS/2 should ensure that a psmouse_reset is called before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * intializing the device and after it has been removed to be in a known
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return rmi_smb_enable_smbus_mode(rmi_smb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static const struct rmi_transport_ops rmi_smb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .write_block = rmi_smb_write_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .read_block = rmi_smb_read_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .reset = rmi_smb_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int rmi_smb_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct rmi_smb_xport *rmi_smb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int smbus_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev_err(&client->dev, "no platform data, aborting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (!i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) I2C_FUNC_SMBUS_READ_BLOCK_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) I2C_FUNC_SMBUS_HOST_NOTIFY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) "adapter does not support required functionality\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (client->irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dev_err(&client->dev, "no IRQ provided, giving up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return client->irq ? client->irq : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) rmi_smb = devm_kzalloc(&client->dev, sizeof(struct rmi_smb_xport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (!rmi_smb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Probing %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_name(&client->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) rmi_smb->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mutex_init(&rmi_smb->page_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) mutex_init(&rmi_smb->mappingtable_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) rmi_smb->xport.dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) rmi_smb->xport.pdata = *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) rmi_smb->xport.pdata.irq = client->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) rmi_smb->xport.proto_name = "smb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) rmi_smb->xport.ops = &rmi_smb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) smbus_version = rmi_smb_get_version(rmi_smb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (smbus_version < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return smbus_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) smbus_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (smbus_version != 2 && smbus_version != 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dev_err(&client->dev, "Unrecognized SMB version %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) smbus_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) i2c_set_clientdata(client, rmi_smb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev_info(&client->dev, "registering SMbus-connected sensor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) error = rmi_register_transport_device(&rmi_smb->xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev_err(&client->dev, "failed to register sensor: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int rmi_smb_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rmi_unregister_transport_device(&rmi_smb->xport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int __maybe_unused rmi_smb_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ret = rmi_driver_suspend(rmi_smb->xport.rmi_dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dev_warn(dev, "Failed to suspend device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int __maybe_unused rmi_smb_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = rmi_driver_suspend(rmi_smb->xport.rmi_dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dev_warn(dev, "Failed to suspend device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static int __maybe_unused rmi_smb_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct i2c_client *client = container_of(dev, struct i2c_client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct rmi_device *rmi_dev = rmi_smb->xport.rmi_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) rmi_smb_reset(&rmi_smb->xport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) rmi_reset(rmi_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ret = rmi_driver_resume(rmi_smb->xport.rmi_dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_warn(dev, "Failed to resume device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int __maybe_unused rmi_smb_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = rmi_driver_resume(rmi_smb->xport.rmi_dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dev_warn(dev, "Failed to resume device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static const struct dev_pm_ops rmi_smb_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) SET_SYSTEM_SLEEP_PM_OPS(rmi_smb_suspend, rmi_smb_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) SET_RUNTIME_PM_OPS(rmi_smb_runtime_suspend, rmi_smb_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static const struct i2c_device_id rmi_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { "rmi4_smbus", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) MODULE_DEVICE_TABLE(i2c, rmi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static struct i2c_driver rmi_smb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .name = "rmi4_smbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .pm = &rmi_smb_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .id_table = rmi_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .probe = rmi_smb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .remove = rmi_smb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) module_i2c_driver(rmi_smb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) MODULE_DESCRIPTION("RMI4 SMBus driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) MODULE_LICENSE("GPL");