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

tda9950.c (11615B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  TDA9950 Consumer Electronics Control driver
      4 *
      5 * The NXP TDA9950 implements the HDMI Consumer Electronics Control
      6 * interface.  The host interface is similar to a mailbox: the data
      7 * registers starting at REG_CDR0 are written to send a command to the
      8 * internal CPU, and replies are read from these registers.
      9 *
     10 * As the data registers represent a mailbox, they must be accessed
     11 * as a single I2C transaction.  See the TDA9950 data sheet for details.
     12 */
     13#include <linux/delay.h>
     14#include <linux/i2c.h>
     15#include <linux/interrupt.h>
     16#include <linux/module.h>
     17#include <linux/platform_data/tda9950.h>
     18#include <linux/slab.h>
     19#include <drm/drm_edid.h>
     20#include <media/cec.h>
     21#include <media/cec-notifier.h>
     22
     23enum {
     24	REG_CSR = 0x00,
     25	CSR_BUSY = BIT(7),
     26	CSR_INT  = BIT(6),
     27	CSR_ERR  = BIT(5),
     28
     29	REG_CER = 0x01,
     30
     31	REG_CVR = 0x02,
     32
     33	REG_CCR = 0x03,
     34	CCR_RESET = BIT(7),
     35	CCR_ON    = BIT(6),
     36
     37	REG_ACKH = 0x04,
     38	REG_ACKL = 0x05,
     39
     40	REG_CCONR = 0x06,
     41	CCONR_ENABLE_ERROR = BIT(4),
     42	CCONR_RETRY_MASK = 7,
     43
     44	REG_CDR0 = 0x07,
     45
     46	CDR1_REQ = 0x00,
     47	CDR1_CNF = 0x01,
     48	CDR1_IND = 0x81,
     49	CDR1_ERR = 0x82,
     50	CDR1_IER = 0x83,
     51
     52	CDR2_CNF_SUCCESS    = 0x00,
     53	CDR2_CNF_OFF_STATE  = 0x80,
     54	CDR2_CNF_BAD_REQ    = 0x81,
     55	CDR2_CNF_CEC_ACCESS = 0x82,
     56	CDR2_CNF_ARB_ERROR  = 0x83,
     57	CDR2_CNF_BAD_TIMING = 0x84,
     58	CDR2_CNF_NACK_ADDR  = 0x85,
     59	CDR2_CNF_NACK_DATA  = 0x86,
     60};
     61
     62struct tda9950_priv {
     63	struct i2c_client *client;
     64	struct device *hdmi;
     65	struct cec_adapter *adap;
     66	struct tda9950_glue *glue;
     67	u16 addresses;
     68	struct cec_msg rx_msg;
     69	struct cec_notifier *notify;
     70	bool open;
     71};
     72
     73static int tda9950_write_range(struct i2c_client *client, u8 addr, u8 *p, int cnt)
     74{
     75	struct i2c_msg msg;
     76	u8 buf[CEC_MAX_MSG_SIZE + 3];
     77	int ret;
     78
     79	if (WARN_ON(cnt > sizeof(buf) - 1))
     80		return -EINVAL;
     81
     82	buf[0] = addr;
     83	memcpy(buf + 1, p, cnt);
     84
     85	msg.addr = client->addr;
     86	msg.flags = 0;
     87	msg.len = cnt + 1;
     88	msg.buf = buf;
     89
     90	dev_dbg(&client->dev, "wr 0x%02x: %*ph\n", addr, cnt, p);
     91
     92	ret = i2c_transfer(client->adapter, &msg, 1);
     93	if (ret < 0)
     94		dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr);
     95	return ret < 0 ? ret : 0;
     96}
     97
     98static void tda9950_write(struct i2c_client *client, u8 addr, u8 val)
     99{
    100	tda9950_write_range(client, addr, &val, 1);
    101}
    102
    103static int tda9950_read_range(struct i2c_client *client, u8 addr, u8 *p, int cnt)
    104{
    105	struct i2c_msg msg[2];
    106	int ret;
    107
    108	msg[0].addr = client->addr;
    109	msg[0].flags = 0;
    110	msg[0].len = 1;
    111	msg[0].buf = &addr;
    112	msg[1].addr = client->addr;
    113	msg[1].flags = I2C_M_RD;
    114	msg[1].len = cnt;
    115	msg[1].buf = p;
    116
    117	ret = i2c_transfer(client->adapter, msg, 2);
    118	if (ret < 0)
    119		dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr);
    120
    121	dev_dbg(&client->dev, "rd 0x%02x: %*ph\n", addr, cnt, p);
    122
    123	return ret;
    124}
    125
    126static u8 tda9950_read(struct i2c_client *client, u8 addr)
    127{
    128	int ret;
    129	u8 val;
    130
    131	ret = tda9950_read_range(client, addr, &val, 1);
    132	if (ret < 0)
    133		val = 0;
    134
    135	return val;
    136}
    137
    138static irqreturn_t tda9950_irq(int irq, void *data)
    139{
    140	struct tda9950_priv *priv = data;
    141	unsigned int tx_status;
    142	u8 csr, cconr, buf[19];
    143	u8 arb_lost_cnt, nack_cnt, err_cnt;
    144
    145	if (!priv->open)
    146		return IRQ_NONE;
    147
    148	csr = tda9950_read(priv->client, REG_CSR);
    149	if (!(csr & CSR_INT))
    150		return IRQ_NONE;
    151
    152	cconr = tda9950_read(priv->client, REG_CCONR) & CCONR_RETRY_MASK;
    153
    154	tda9950_read_range(priv->client, REG_CDR0, buf, sizeof(buf));
    155
    156	/*
    157	 * This should never happen: the data sheet says that there will
    158	 * always be a valid message if the interrupt line is asserted.
    159	 */
    160	if (buf[0] == 0) {
    161		dev_warn(&priv->client->dev, "interrupt pending, but no message?\n");
    162		return IRQ_NONE;
    163	}
    164
    165	switch (buf[1]) {
    166	case CDR1_CNF: /* transmit result */
    167		arb_lost_cnt = nack_cnt = err_cnt = 0;
    168		switch (buf[2]) {
    169		case CDR2_CNF_SUCCESS:
    170			tx_status = CEC_TX_STATUS_OK;
    171			break;
    172
    173		case CDR2_CNF_ARB_ERROR:
    174			tx_status = CEC_TX_STATUS_ARB_LOST;
    175			arb_lost_cnt = cconr;
    176			break;
    177
    178		case CDR2_CNF_NACK_ADDR:
    179			tx_status = CEC_TX_STATUS_NACK;
    180			nack_cnt = cconr;
    181			break;
    182
    183		default: /* some other error, refer to TDA9950 docs */
    184			dev_err(&priv->client->dev, "CNF reply error 0x%02x\n",
    185				buf[2]);
    186			tx_status = CEC_TX_STATUS_ERROR;
    187			err_cnt = cconr;
    188			break;
    189		}
    190		/* TDA9950 executes all retries for us */
    191		if (tx_status != CEC_TX_STATUS_OK)
    192			tx_status |= CEC_TX_STATUS_MAX_RETRIES;
    193		cec_transmit_done(priv->adap, tx_status, arb_lost_cnt,
    194				  nack_cnt, 0, err_cnt);
    195		break;
    196
    197	case CDR1_IND:
    198		priv->rx_msg.len = buf[0] - 2;
    199		if (priv->rx_msg.len > CEC_MAX_MSG_SIZE)
    200			priv->rx_msg.len = CEC_MAX_MSG_SIZE;
    201
    202		memcpy(priv->rx_msg.msg, buf + 2, priv->rx_msg.len);
    203		cec_received_msg(priv->adap, &priv->rx_msg);
    204		break;
    205
    206	default: /* unknown */
    207		dev_err(&priv->client->dev, "unknown service id 0x%02x\n",
    208			buf[1]);
    209		break;
    210	}
    211
    212	return IRQ_HANDLED;
    213}
    214
    215static int tda9950_cec_transmit(struct cec_adapter *adap, u8 attempts,
    216				u32 signal_free_time, struct cec_msg *msg)
    217{
    218	struct tda9950_priv *priv = adap->priv;
    219	u8 buf[CEC_MAX_MSG_SIZE + 2];
    220
    221	buf[0] = 2 + msg->len;
    222	buf[1] = CDR1_REQ;
    223	memcpy(buf + 2, msg->msg, msg->len);
    224
    225	if (attempts > 5)
    226		attempts = 5;
    227
    228	tda9950_write(priv->client, REG_CCONR, attempts);
    229
    230	return tda9950_write_range(priv->client, REG_CDR0, buf, 2 + msg->len);
    231}
    232
    233static int tda9950_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
    234{
    235	struct tda9950_priv *priv = adap->priv;
    236	u16 addresses;
    237	u8 buf[2];
    238
    239	if (addr == CEC_LOG_ADDR_INVALID)
    240		addresses = priv->addresses = 0;
    241	else
    242		addresses = priv->addresses |= BIT(addr);
    243
    244	/* TDA9950 doesn't want address 15 set */
    245	addresses &= 0x7fff;
    246	buf[0] = addresses >> 8;
    247	buf[1] = addresses;
    248
    249	return tda9950_write_range(priv->client, REG_ACKH, buf, 2);
    250}
    251
    252/*
    253 * When operating as part of the TDA998x, we need additional handling
    254 * to initialise and shut down the TDA9950 part of the device.  These
    255 * two hooks are provided to allow the TDA998x code to perform those
    256 * activities.
    257 */
    258static int tda9950_glue_open(struct tda9950_priv *priv)
    259{
    260	int ret = 0;
    261
    262	if (priv->glue && priv->glue->open)
    263		ret = priv->glue->open(priv->glue->data);
    264
    265	priv->open = true;
    266
    267	return ret;
    268}
    269
    270static void tda9950_glue_release(struct tda9950_priv *priv)
    271{
    272	priv->open = false;
    273
    274	if (priv->glue && priv->glue->release)
    275		priv->glue->release(priv->glue->data);
    276}
    277
    278static int tda9950_open(struct tda9950_priv *priv)
    279{
    280	struct i2c_client *client = priv->client;
    281	int ret;
    282
    283	ret = tda9950_glue_open(priv);
    284	if (ret)
    285		return ret;
    286
    287	/* Reset the TDA9950, and wait 250ms for it to recover */
    288	tda9950_write(client, REG_CCR, CCR_RESET);
    289	msleep(250);
    290
    291	tda9950_cec_adap_log_addr(priv->adap, CEC_LOG_ADDR_INVALID);
    292
    293	/* Start the command processor */
    294	tda9950_write(client, REG_CCR, CCR_ON);
    295
    296	return 0;
    297}
    298
    299static void tda9950_release(struct tda9950_priv *priv)
    300{
    301	struct i2c_client *client = priv->client;
    302	int timeout = 50;
    303	u8 csr;
    304
    305	/* Stop the command processor */
    306	tda9950_write(client, REG_CCR, 0);
    307
    308	/* Wait up to .5s for it to signal non-busy */
    309	do {
    310		csr = tda9950_read(client, REG_CSR);
    311		if (!(csr & CSR_BUSY) || !--timeout)
    312			break;
    313		msleep(10);
    314	} while (1);
    315
    316	/* Warn the user that their IRQ may die if it's shared. */
    317	if (csr & CSR_BUSY)
    318		dev_warn(&client->dev, "command processor failed to stop, irq%d may die (csr=0x%02x)\n",
    319			 client->irq, csr);
    320
    321	tda9950_glue_release(priv);
    322}
    323
    324static int tda9950_cec_adap_enable(struct cec_adapter *adap, bool enable)
    325{
    326	struct tda9950_priv *priv = adap->priv;
    327
    328	if (!enable) {
    329		tda9950_release(priv);
    330		return 0;
    331	} else {
    332		return tda9950_open(priv);
    333	}
    334}
    335
    336static const struct cec_adap_ops tda9950_cec_ops = {
    337	.adap_enable = tda9950_cec_adap_enable,
    338	.adap_log_addr = tda9950_cec_adap_log_addr,
    339	.adap_transmit = tda9950_cec_transmit,
    340};
    341
    342/*
    343 * When operating as part of the TDA998x, we need to claim additional
    344 * resources.  These two hooks permit the management of those resources.
    345 */
    346static void tda9950_devm_glue_exit(void *data)
    347{
    348	struct tda9950_glue *glue = data;
    349
    350	if (glue && glue->exit)
    351		glue->exit(glue->data);
    352}
    353
    354static int tda9950_devm_glue_init(struct device *dev, struct tda9950_glue *glue)
    355{
    356	int ret;
    357
    358	if (glue && glue->init) {
    359		ret = glue->init(glue->data);
    360		if (ret)
    361			return ret;
    362	}
    363
    364	ret = devm_add_action(dev, tda9950_devm_glue_exit, glue);
    365	if (ret)
    366		tda9950_devm_glue_exit(glue);
    367
    368	return ret;
    369}
    370
    371static void tda9950_cec_del(void *data)
    372{
    373	struct tda9950_priv *priv = data;
    374
    375	cec_delete_adapter(priv->adap);
    376}
    377
    378static int tda9950_probe(struct i2c_client *client,
    379			 const struct i2c_device_id *id)
    380{
    381	struct tda9950_glue *glue = client->dev.platform_data;
    382	struct device *dev = &client->dev;
    383	struct tda9950_priv *priv;
    384	unsigned long irqflags;
    385	int ret;
    386	u8 cvr;
    387
    388	/*
    389	 * We must have I2C functionality: our multi-byte accesses
    390	 * must be performed as a single contiguous transaction.
    391	 */
    392	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
    393		dev_err(&client->dev,
    394			"adapter does not support I2C functionality\n");
    395		return -ENXIO;
    396	}
    397
    398	/* We must have an interrupt to be functional. */
    399	if (client->irq <= 0) {
    400		dev_err(&client->dev, "driver requires an interrupt\n");
    401		return -ENXIO;
    402	}
    403
    404	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    405	if (!priv)
    406		return -ENOMEM;
    407
    408	priv->client = client;
    409	priv->glue = glue;
    410
    411	i2c_set_clientdata(client, priv);
    412
    413	/*
    414	 * If we're part of a TDA998x, we want the class devices to be
    415	 * associated with the HDMI Tx so we have a tight relationship
    416	 * between the HDMI interface and the CEC interface.
    417	 */
    418	priv->hdmi = dev;
    419	if (glue && glue->parent)
    420		priv->hdmi = glue->parent;
    421
    422	priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950",
    423					  CEC_CAP_DEFAULTS |
    424					  CEC_CAP_CONNECTOR_INFO,
    425					  CEC_MAX_LOG_ADDRS);
    426	if (IS_ERR(priv->adap))
    427		return PTR_ERR(priv->adap);
    428
    429	ret = devm_add_action(dev, tda9950_cec_del, priv);
    430	if (ret) {
    431		cec_delete_adapter(priv->adap);
    432		return ret;
    433	}
    434
    435	ret = tda9950_devm_glue_init(dev, glue);
    436	if (ret)
    437		return ret;
    438
    439	ret = tda9950_glue_open(priv);
    440	if (ret)
    441		return ret;
    442
    443	cvr = tda9950_read(client, REG_CVR);
    444
    445	dev_info(&client->dev,
    446		 "TDA9950 CEC interface, hardware version %u.%u\n",
    447		 cvr >> 4, cvr & 15);
    448
    449	tda9950_glue_release(priv);
    450
    451	irqflags = IRQF_TRIGGER_FALLING;
    452	if (glue)
    453		irqflags = glue->irq_flags;
    454
    455	ret = devm_request_threaded_irq(dev, client->irq, NULL, tda9950_irq,
    456					irqflags | IRQF_SHARED | IRQF_ONESHOT,
    457					dev_name(&client->dev), priv);
    458	if (ret < 0)
    459		return ret;
    460
    461	priv->notify = cec_notifier_cec_adap_register(priv->hdmi, NULL,
    462						      priv->adap);
    463	if (!priv->notify)
    464		return -ENOMEM;
    465
    466	ret = cec_register_adapter(priv->adap, priv->hdmi);
    467	if (ret < 0) {
    468		cec_notifier_cec_adap_unregister(priv->notify, priv->adap);
    469		return ret;
    470	}
    471
    472	/*
    473	 * CEC documentation says we must not call cec_delete_adapter
    474	 * after a successful call to cec_register_adapter().
    475	 */
    476	devm_remove_action(dev, tda9950_cec_del, priv);
    477
    478	return 0;
    479}
    480
    481static int tda9950_remove(struct i2c_client *client)
    482{
    483	struct tda9950_priv *priv = i2c_get_clientdata(client);
    484
    485	cec_notifier_cec_adap_unregister(priv->notify, priv->adap);
    486	cec_unregister_adapter(priv->adap);
    487
    488	return 0;
    489}
    490
    491static struct i2c_device_id tda9950_ids[] = {
    492	{ "tda9950", 0 },
    493	{ },
    494};
    495MODULE_DEVICE_TABLE(i2c, tda9950_ids);
    496
    497static struct i2c_driver tda9950_driver = {
    498	.probe = tda9950_probe,
    499	.remove = tda9950_remove,
    500	.driver = {
    501		.name = "tda9950",
    502	},
    503	.id_table = tda9950_ids,
    504};
    505
    506module_i2c_driver(tda9950_driver);
    507
    508MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
    509MODULE_DESCRIPTION("TDA9950/TDA998x Consumer Electronics Control Driver");
    510MODULE_LICENSE("GPL v2");