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

i2c.c (6881B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * I2C Link Layer for ST NCI NFC controller familly based Driver
      4 * Copyright (C) 2014-2015 STMicroelectronics SAS. All rights reserved.
      5 */
      6
      7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      8
      9#include <linux/module.h>
     10#include <linux/i2c.h>
     11#include <linux/gpio/consumer.h>
     12#include <linux/acpi.h>
     13#include <linux/interrupt.h>
     14#include <linux/delay.h>
     15#include <linux/nfc.h>
     16#include <linux/of.h>
     17
     18#include "st-nci.h"
     19
     20#define DRIVER_DESC "NCI NFC driver for ST_NCI"
     21
     22/* ndlc header */
     23#define ST_NCI_FRAME_HEADROOM 1
     24#define ST_NCI_FRAME_TAILROOM 0
     25
     26#define ST_NCI_I2C_MIN_SIZE 4   /* PCB(1) + NCI Packet header(3) */
     27#define ST_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */
     28
     29#define ST_NCI_DRIVER_NAME "st_nci"
     30#define ST_NCI_I2C_DRIVER_NAME "st_nci_i2c"
     31
     32struct st_nci_i2c_phy {
     33	struct i2c_client *i2c_dev;
     34	struct llt_ndlc *ndlc;
     35
     36	bool irq_active;
     37
     38	struct gpio_desc *gpiod_reset;
     39
     40	struct st_nci_se_status se_status;
     41};
     42
     43static int st_nci_i2c_enable(void *phy_id)
     44{
     45	struct st_nci_i2c_phy *phy = phy_id;
     46
     47	gpiod_set_value(phy->gpiod_reset, 0);
     48	usleep_range(10000, 15000);
     49	gpiod_set_value(phy->gpiod_reset, 1);
     50	usleep_range(80000, 85000);
     51
     52	if (phy->ndlc->powered == 0 && phy->irq_active == 0) {
     53		enable_irq(phy->i2c_dev->irq);
     54		phy->irq_active = true;
     55	}
     56
     57	return 0;
     58}
     59
     60static void st_nci_i2c_disable(void *phy_id)
     61{
     62	struct st_nci_i2c_phy *phy = phy_id;
     63
     64	disable_irq_nosync(phy->i2c_dev->irq);
     65	phy->irq_active = false;
     66}
     67
     68/*
     69 * Writing a frame must not return the number of written bytes.
     70 * It must return either zero for success, or <0 for error.
     71 * In addition, it must not alter the skb
     72 */
     73static int st_nci_i2c_write(void *phy_id, struct sk_buff *skb)
     74{
     75	int r;
     76	struct st_nci_i2c_phy *phy = phy_id;
     77	struct i2c_client *client = phy->i2c_dev;
     78
     79	if (phy->ndlc->hard_fault != 0)
     80		return phy->ndlc->hard_fault;
     81
     82	r = i2c_master_send(client, skb->data, skb->len);
     83	if (r < 0) {  /* Retry, chip was in standby */
     84		usleep_range(1000, 4000);
     85		r = i2c_master_send(client, skb->data, skb->len);
     86	}
     87
     88	if (r >= 0) {
     89		if (r != skb->len)
     90			r = -EREMOTEIO;
     91		else
     92			r = 0;
     93	}
     94
     95	return r;
     96}
     97
     98/*
     99 * Reads an ndlc frame and returns it in a newly allocated sk_buff.
    100 * returns:
    101 * 0 : if received frame is complete
    102 * -EREMOTEIO : i2c read error (fatal)
    103 * -EBADMSG : frame was incorrect and discarded
    104 * -ENOMEM : cannot allocate skb, frame dropped
    105 */
    106static int st_nci_i2c_read(struct st_nci_i2c_phy *phy,
    107				 struct sk_buff **skb)
    108{
    109	int r;
    110	u8 len;
    111	u8 buf[ST_NCI_I2C_MAX_SIZE];
    112	struct i2c_client *client = phy->i2c_dev;
    113
    114	r = i2c_master_recv(client, buf, ST_NCI_I2C_MIN_SIZE);
    115	if (r < 0) {  /* Retry, chip was in standby */
    116		usleep_range(1000, 4000);
    117		r = i2c_master_recv(client, buf, ST_NCI_I2C_MIN_SIZE);
    118	}
    119
    120	if (r != ST_NCI_I2C_MIN_SIZE)
    121		return -EREMOTEIO;
    122
    123	len = be16_to_cpu(*(__be16 *) (buf + 2));
    124	if (len > ST_NCI_I2C_MAX_SIZE) {
    125		nfc_err(&client->dev, "invalid frame len\n");
    126		return -EBADMSG;
    127	}
    128
    129	*skb = alloc_skb(ST_NCI_I2C_MIN_SIZE + len, GFP_KERNEL);
    130	if (*skb == NULL)
    131		return -ENOMEM;
    132
    133	skb_reserve(*skb, ST_NCI_I2C_MIN_SIZE);
    134	skb_put(*skb, ST_NCI_I2C_MIN_SIZE);
    135	memcpy((*skb)->data, buf, ST_NCI_I2C_MIN_SIZE);
    136
    137	if (!len)
    138		return 0;
    139
    140	r = i2c_master_recv(client, buf, len);
    141	if (r != len) {
    142		kfree_skb(*skb);
    143		return -EREMOTEIO;
    144	}
    145
    146	skb_put(*skb, len);
    147	memcpy((*skb)->data + ST_NCI_I2C_MIN_SIZE, buf, len);
    148
    149	return 0;
    150}
    151
    152/*
    153 * Reads an ndlc frame from the chip.
    154 *
    155 * On ST_NCI, IRQ goes in idle state when read starts.
    156 */
    157static irqreturn_t st_nci_irq_thread_fn(int irq, void *phy_id)
    158{
    159	struct st_nci_i2c_phy *phy = phy_id;
    160	struct sk_buff *skb = NULL;
    161	int r;
    162
    163	if (!phy || !phy->ndlc || irq != phy->i2c_dev->irq) {
    164		WARN_ON_ONCE(1);
    165		return IRQ_NONE;
    166	}
    167
    168	if (phy->ndlc->hard_fault)
    169		return IRQ_HANDLED;
    170
    171	if (!phy->ndlc->powered) {
    172		st_nci_i2c_disable(phy);
    173		return IRQ_HANDLED;
    174	}
    175
    176	r = st_nci_i2c_read(phy, &skb);
    177	if (r == -EREMOTEIO || r == -ENOMEM || r == -EBADMSG)
    178		return IRQ_HANDLED;
    179
    180	ndlc_recv(phy->ndlc, skb);
    181
    182	return IRQ_HANDLED;
    183}
    184
    185static const struct nfc_phy_ops i2c_phy_ops = {
    186	.write = st_nci_i2c_write,
    187	.enable = st_nci_i2c_enable,
    188	.disable = st_nci_i2c_disable,
    189};
    190
    191static const struct acpi_gpio_params reset_gpios = { 1, 0, false };
    192
    193static const struct acpi_gpio_mapping acpi_st_nci_gpios[] = {
    194	{ "reset-gpios", &reset_gpios, 1 },
    195	{},
    196};
    197
    198static int st_nci_i2c_probe(struct i2c_client *client,
    199				  const struct i2c_device_id *id)
    200{
    201	struct device *dev = &client->dev;
    202	struct st_nci_i2c_phy *phy;
    203	int r;
    204
    205	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
    206		nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
    207		return -ENODEV;
    208	}
    209
    210	phy = devm_kzalloc(dev, sizeof(struct st_nci_i2c_phy), GFP_KERNEL);
    211	if (!phy)
    212		return -ENOMEM;
    213
    214	phy->i2c_dev = client;
    215
    216	i2c_set_clientdata(client, phy);
    217
    218	r = devm_acpi_dev_add_driver_gpios(dev, acpi_st_nci_gpios);
    219	if (r)
    220		dev_dbg(dev, "Unable to add GPIO mapping table\n");
    221
    222	/* Get RESET GPIO */
    223	phy->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
    224	if (IS_ERR(phy->gpiod_reset)) {
    225		nfc_err(dev, "Unable to get RESET GPIO\n");
    226		return -ENODEV;
    227	}
    228
    229	phy->se_status.is_ese_present =
    230				device_property_read_bool(dev, "ese-present");
    231	phy->se_status.is_uicc_present =
    232				device_property_read_bool(dev, "uicc-present");
    233
    234	r = ndlc_probe(phy, &i2c_phy_ops, &client->dev,
    235			ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM,
    236			&phy->ndlc, &phy->se_status);
    237	if (r < 0) {
    238		nfc_err(&client->dev, "Unable to register ndlc layer\n");
    239		return r;
    240	}
    241
    242	phy->irq_active = true;
    243	r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
    244				st_nci_irq_thread_fn,
    245				IRQF_ONESHOT,
    246				ST_NCI_DRIVER_NAME, phy);
    247	if (r < 0)
    248		nfc_err(&client->dev, "Unable to register IRQ handler\n");
    249
    250	return r;
    251}
    252
    253static int st_nci_i2c_remove(struct i2c_client *client)
    254{
    255	struct st_nci_i2c_phy *phy = i2c_get_clientdata(client);
    256
    257	ndlc_remove(phy->ndlc);
    258
    259	return 0;
    260}
    261
    262static const struct i2c_device_id st_nci_i2c_id_table[] = {
    263	{ST_NCI_DRIVER_NAME, 0},
    264	{}
    265};
    266MODULE_DEVICE_TABLE(i2c, st_nci_i2c_id_table);
    267
    268static const struct acpi_device_id st_nci_i2c_acpi_match[] __maybe_unused = {
    269	{"SMO2101"},
    270	{"SMO2102"},
    271	{}
    272};
    273MODULE_DEVICE_TABLE(acpi, st_nci_i2c_acpi_match);
    274
    275static const struct of_device_id of_st_nci_i2c_match[] __maybe_unused = {
    276	{ .compatible = "st,st21nfcb-i2c", },
    277	{ .compatible = "st,st21nfcb_i2c", },
    278	{ .compatible = "st,st21nfcc-i2c", },
    279	{}
    280};
    281MODULE_DEVICE_TABLE(of, of_st_nci_i2c_match);
    282
    283static struct i2c_driver st_nci_i2c_driver = {
    284	.driver = {
    285		.name = ST_NCI_I2C_DRIVER_NAME,
    286		.of_match_table = of_match_ptr(of_st_nci_i2c_match),
    287		.acpi_match_table = ACPI_PTR(st_nci_i2c_acpi_match),
    288	},
    289	.probe = st_nci_i2c_probe,
    290	.id_table = st_nci_i2c_id_table,
    291	.remove = st_nci_i2c_remove,
    292};
    293module_i2c_driver(st_nci_i2c_driver);
    294
    295MODULE_LICENSE("GPL");
    296MODULE_DESCRIPTION(DRIVER_DESC);