cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rmi_i2c.c (9654B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2011-2016 Synaptics Incorporated
      4 * Copyright (c) 2011 Unixphere
      5 */
      6
      7#include <linux/i2c.h>
      8#include <linux/rmi.h>
      9#include <linux/of.h>
     10#include <linux/delay.h>
     11#include <linux/regulator/consumer.h>
     12#include "rmi_driver.h"
     13
     14#define BUFFER_SIZE_INCREMENT 32
     15
     16/**
     17 * struct rmi_i2c_xport - stores information for i2c communication
     18 *
     19 * @xport: The transport interface structure
     20 * @client: The I2C client device structure
     21 *
     22 * @page_mutex: Locks current page to avoid changing pages in unexpected ways.
     23 * @page: Keeps track of the current virtual page
     24 *
     25 * @tx_buf: Buffer used for transmitting data to the sensor over i2c.
     26 * @tx_buf_size: Size of the buffer
     27 *
     28 * @supplies: Array of voltage regulators
     29 * @startup_delay: Milliseconds to pause after powering up the regulators
     30 */
     31struct rmi_i2c_xport {
     32	struct rmi_transport_dev xport;
     33	struct i2c_client *client;
     34
     35	struct mutex page_mutex;
     36	int page;
     37
     38	u8 *tx_buf;
     39	size_t tx_buf_size;
     40
     41	struct regulator_bulk_data supplies[2];
     42	u32 startup_delay;
     43};
     44
     45#define RMI_PAGE_SELECT_REGISTER 0xff
     46#define RMI_I2C_PAGE(addr) (((addr) >> 8) & 0xff)
     47
     48/*
     49 * rmi_set_page - Set RMI page
     50 * @xport: The pointer to the rmi_transport_dev struct
     51 * @page: The new page address.
     52 *
     53 * RMI devices have 16-bit addressing, but some of the transport
     54 * implementations (like SMBus) only have 8-bit addressing. So RMI implements
     55 * a page address at 0xff of every page so we can reliable page addresses
     56 * every 256 registers.
     57 *
     58 * The page_mutex lock must be held when this function is entered.
     59 *
     60 * Returns zero on success, non-zero on failure.
     61 */
     62static int rmi_set_page(struct rmi_i2c_xport *rmi_i2c, u8 page)
     63{
     64	struct i2c_client *client = rmi_i2c->client;
     65	u8 txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page};
     66	int retval;
     67
     68	retval = i2c_master_send(client, txbuf, sizeof(txbuf));
     69	if (retval != sizeof(txbuf)) {
     70		dev_err(&client->dev,
     71			"%s: set page failed: %d.", __func__, retval);
     72		return (retval < 0) ? retval : -EIO;
     73	}
     74
     75	rmi_i2c->page = page;
     76	return 0;
     77}
     78
     79static int rmi_i2c_write_block(struct rmi_transport_dev *xport, u16 addr,
     80			       const void *buf, size_t len)
     81{
     82	struct rmi_i2c_xport *rmi_i2c =
     83		container_of(xport, struct rmi_i2c_xport, xport);
     84	struct i2c_client *client = rmi_i2c->client;
     85	size_t tx_size = len + 1;
     86	int retval;
     87
     88	mutex_lock(&rmi_i2c->page_mutex);
     89
     90	if (!rmi_i2c->tx_buf || rmi_i2c->tx_buf_size < tx_size) {
     91		if (rmi_i2c->tx_buf)
     92			devm_kfree(&client->dev, rmi_i2c->tx_buf);
     93		rmi_i2c->tx_buf_size = tx_size + BUFFER_SIZE_INCREMENT;
     94		rmi_i2c->tx_buf = devm_kzalloc(&client->dev,
     95					       rmi_i2c->tx_buf_size,
     96					       GFP_KERNEL);
     97		if (!rmi_i2c->tx_buf) {
     98			rmi_i2c->tx_buf_size = 0;
     99			retval = -ENOMEM;
    100			goto exit;
    101		}
    102	}
    103
    104	rmi_i2c->tx_buf[0] = addr & 0xff;
    105	memcpy(rmi_i2c->tx_buf + 1, buf, len);
    106
    107	if (RMI_I2C_PAGE(addr) != rmi_i2c->page) {
    108		retval = rmi_set_page(rmi_i2c, RMI_I2C_PAGE(addr));
    109		if (retval)
    110			goto exit;
    111	}
    112
    113	retval = i2c_master_send(client, rmi_i2c->tx_buf, tx_size);
    114	if (retval == tx_size)
    115		retval = 0;
    116	else if (retval >= 0)
    117		retval = -EIO;
    118
    119exit:
    120	rmi_dbg(RMI_DEBUG_XPORT, &client->dev,
    121		"write %zd bytes at %#06x: %d (%*ph)\n",
    122		len, addr, retval, (int)len, buf);
    123
    124	mutex_unlock(&rmi_i2c->page_mutex);
    125	return retval;
    126}
    127
    128static int rmi_i2c_read_block(struct rmi_transport_dev *xport, u16 addr,
    129			      void *buf, size_t len)
    130{
    131	struct rmi_i2c_xport *rmi_i2c =
    132		container_of(xport, struct rmi_i2c_xport, xport);
    133	struct i2c_client *client = rmi_i2c->client;
    134	u8 addr_offset = addr & 0xff;
    135	int retval;
    136	struct i2c_msg msgs[] = {
    137		{
    138			.addr	= client->addr,
    139			.len	= sizeof(addr_offset),
    140			.buf	= &addr_offset,
    141		},
    142		{
    143			.addr	= client->addr,
    144			.flags	= I2C_M_RD,
    145			.len	= len,
    146			.buf	= buf,
    147		},
    148	};
    149
    150	mutex_lock(&rmi_i2c->page_mutex);
    151
    152	if (RMI_I2C_PAGE(addr) != rmi_i2c->page) {
    153		retval = rmi_set_page(rmi_i2c, RMI_I2C_PAGE(addr));
    154		if (retval)
    155			goto exit;
    156	}
    157
    158	retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
    159	if (retval == ARRAY_SIZE(msgs))
    160		retval = 0; /* success */
    161	else if (retval >= 0)
    162		retval = -EIO;
    163
    164exit:
    165	rmi_dbg(RMI_DEBUG_XPORT, &client->dev,
    166		"read %zd bytes at %#06x: %d (%*ph)\n",
    167		len, addr, retval, (int)len, buf);
    168
    169	mutex_unlock(&rmi_i2c->page_mutex);
    170	return retval;
    171}
    172
    173static const struct rmi_transport_ops rmi_i2c_ops = {
    174	.write_block	= rmi_i2c_write_block,
    175	.read_block	= rmi_i2c_read_block,
    176};
    177
    178#ifdef CONFIG_OF
    179static const struct of_device_id rmi_i2c_of_match[] = {
    180	{ .compatible = "syna,rmi4-i2c" },
    181	{},
    182};
    183MODULE_DEVICE_TABLE(of, rmi_i2c_of_match);
    184#endif
    185
    186static void rmi_i2c_regulator_bulk_disable(void *data)
    187{
    188	struct rmi_i2c_xport *rmi_i2c = data;
    189
    190	regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
    191			       rmi_i2c->supplies);
    192}
    193
    194static void rmi_i2c_unregister_transport(void *data)
    195{
    196	struct rmi_i2c_xport *rmi_i2c = data;
    197
    198	rmi_unregister_transport_device(&rmi_i2c->xport);
    199}
    200
    201static int rmi_i2c_probe(struct i2c_client *client,
    202			 const struct i2c_device_id *id)
    203{
    204	struct rmi_device_platform_data *pdata;
    205	struct rmi_device_platform_data *client_pdata =
    206					dev_get_platdata(&client->dev);
    207	struct rmi_i2c_xport *rmi_i2c;
    208	int error;
    209
    210	rmi_i2c = devm_kzalloc(&client->dev, sizeof(struct rmi_i2c_xport),
    211				GFP_KERNEL);
    212	if (!rmi_i2c)
    213		return -ENOMEM;
    214
    215	pdata = &rmi_i2c->xport.pdata;
    216
    217	if (!client->dev.of_node && client_pdata)
    218		*pdata = *client_pdata;
    219
    220	pdata->irq = client->irq;
    221
    222	rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Probing %s.\n",
    223			dev_name(&client->dev));
    224
    225	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
    226		dev_err(&client->dev,
    227			"adapter does not support required functionality\n");
    228		return -ENODEV;
    229	}
    230
    231	rmi_i2c->supplies[0].supply = "vdd";
    232	rmi_i2c->supplies[1].supply = "vio";
    233	error = devm_regulator_bulk_get(&client->dev,
    234					 ARRAY_SIZE(rmi_i2c->supplies),
    235					 rmi_i2c->supplies);
    236	if (error < 0)
    237		return error;
    238
    239	error = regulator_bulk_enable(ARRAY_SIZE(rmi_i2c->supplies),
    240				       rmi_i2c->supplies);
    241	if (error < 0)
    242		return error;
    243
    244	error = devm_add_action_or_reset(&client->dev,
    245					  rmi_i2c_regulator_bulk_disable,
    246					  rmi_i2c);
    247	if (error)
    248		return error;
    249
    250	of_property_read_u32(client->dev.of_node, "syna,startup-delay-ms",
    251			     &rmi_i2c->startup_delay);
    252
    253	msleep(rmi_i2c->startup_delay);
    254
    255	rmi_i2c->client = client;
    256	mutex_init(&rmi_i2c->page_mutex);
    257
    258	rmi_i2c->xport.dev = &client->dev;
    259	rmi_i2c->xport.proto_name = "i2c";
    260	rmi_i2c->xport.ops = &rmi_i2c_ops;
    261
    262	i2c_set_clientdata(client, rmi_i2c);
    263
    264	/*
    265	 * Setting the page to zero will (a) make sure the PSR is in a
    266	 * known state, and (b) make sure we can talk to the device.
    267	 */
    268	error = rmi_set_page(rmi_i2c, 0);
    269	if (error) {
    270		dev_err(&client->dev, "Failed to set page select to 0\n");
    271		return error;
    272	}
    273
    274	dev_info(&client->dev, "registering I2C-connected sensor\n");
    275
    276	error = rmi_register_transport_device(&rmi_i2c->xport);
    277	if (error) {
    278		dev_err(&client->dev, "failed to register sensor: %d\n", error);
    279		return error;
    280	}
    281
    282	error = devm_add_action_or_reset(&client->dev,
    283					  rmi_i2c_unregister_transport,
    284					  rmi_i2c);
    285	if (error)
    286		return error;
    287
    288	return 0;
    289}
    290
    291#ifdef CONFIG_PM_SLEEP
    292static int rmi_i2c_suspend(struct device *dev)
    293{
    294	struct i2c_client *client = to_i2c_client(dev);
    295	struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
    296	int ret;
    297
    298	ret = rmi_driver_suspend(rmi_i2c->xport.rmi_dev, true);
    299	if (ret)
    300		dev_warn(dev, "Failed to resume device: %d\n", ret);
    301
    302	regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
    303			       rmi_i2c->supplies);
    304
    305	return ret;
    306}
    307
    308static int rmi_i2c_resume(struct device *dev)
    309{
    310	struct i2c_client *client = to_i2c_client(dev);
    311	struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
    312	int ret;
    313
    314	ret = regulator_bulk_enable(ARRAY_SIZE(rmi_i2c->supplies),
    315				    rmi_i2c->supplies);
    316	if (ret)
    317		return ret;
    318
    319	msleep(rmi_i2c->startup_delay);
    320
    321	ret = rmi_driver_resume(rmi_i2c->xport.rmi_dev, true);
    322	if (ret)
    323		dev_warn(dev, "Failed to resume device: %d\n", ret);
    324
    325	return ret;
    326}
    327#endif
    328
    329#ifdef CONFIG_PM
    330static int rmi_i2c_runtime_suspend(struct device *dev)
    331{
    332	struct i2c_client *client = to_i2c_client(dev);
    333	struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
    334	int ret;
    335
    336	ret = rmi_driver_suspend(rmi_i2c->xport.rmi_dev, false);
    337	if (ret)
    338		dev_warn(dev, "Failed to resume device: %d\n", ret);
    339
    340	regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
    341			       rmi_i2c->supplies);
    342
    343	return 0;
    344}
    345
    346static int rmi_i2c_runtime_resume(struct device *dev)
    347{
    348	struct i2c_client *client = to_i2c_client(dev);
    349	struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
    350	int ret;
    351
    352	ret = regulator_bulk_enable(ARRAY_SIZE(rmi_i2c->supplies),
    353				    rmi_i2c->supplies);
    354	if (ret)
    355		return ret;
    356
    357	msleep(rmi_i2c->startup_delay);
    358
    359	ret = rmi_driver_resume(rmi_i2c->xport.rmi_dev, false);
    360	if (ret)
    361		dev_warn(dev, "Failed to resume device: %d\n", ret);
    362
    363	return 0;
    364}
    365#endif
    366
    367static const struct dev_pm_ops rmi_i2c_pm = {
    368	SET_SYSTEM_SLEEP_PM_OPS(rmi_i2c_suspend, rmi_i2c_resume)
    369	SET_RUNTIME_PM_OPS(rmi_i2c_runtime_suspend, rmi_i2c_runtime_resume,
    370			   NULL)
    371};
    372
    373static const struct i2c_device_id rmi_id[] = {
    374	{ "rmi4_i2c", 0 },
    375	{ }
    376};
    377MODULE_DEVICE_TABLE(i2c, rmi_id);
    378
    379static struct i2c_driver rmi_i2c_driver = {
    380	.driver = {
    381		.name	= "rmi4_i2c",
    382		.pm	= &rmi_i2c_pm,
    383		.of_match_table = of_match_ptr(rmi_i2c_of_match),
    384	},
    385	.id_table	= rmi_id,
    386	.probe		= rmi_i2c_probe,
    387};
    388
    389module_i2c_driver(rmi_i2c_driver);
    390
    391MODULE_AUTHOR("Christopher Heiny <cheiny@synaptics.com>");
    392MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com>");
    393MODULE_DESCRIPTION("RMI I2C driver");
    394MODULE_LICENSE("GPL");