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

cxd2099.c (14230B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * cxd2099.c: Driver for the Sony CXD2099AR Common Interface Controller
      4 *
      5 * Copyright (C) 2010-2013 Digital Devices GmbH
      6 */
      7
      8#include <linux/slab.h>
      9#include <linux/kernel.h>
     10#include <linux/module.h>
     11#include <linux/i2c.h>
     12#include <linux/regmap.h>
     13#include <linux/wait.h>
     14#include <linux/delay.h>
     15#include <linux/mutex.h>
     16#include <linux/io.h>
     17
     18#include "cxd2099.h"
     19
     20static int buffermode;
     21module_param(buffermode, int, 0444);
     22MODULE_PARM_DESC(buffermode, "Enable CXD2099AR buffer mode (default: disabled)");
     23
     24static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount);
     25
     26struct cxd {
     27	struct dvb_ca_en50221 en;
     28
     29	struct cxd2099_cfg cfg;
     30	struct i2c_client *client;
     31	struct regmap *regmap;
     32
     33	u8     regs[0x23];
     34	u8     lastaddress;
     35	u8     clk_reg_f;
     36	u8     clk_reg_b;
     37	int    mode;
     38	int    ready;
     39	int    dr;
     40	int    write_busy;
     41	int    slot_stat;
     42
     43	u8     amem[1024];
     44	int    amem_read;
     45
     46	int    cammode;
     47	struct mutex lock; /* device access lock */
     48
     49	u8     rbuf[1028];
     50	u8     wbuf[1028];
     51};
     52
     53static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
     54{
     55	int status = 0;
     56
     57	if (ci->lastaddress != adr)
     58		status = regmap_write(ci->regmap, 0, adr);
     59	if (!status) {
     60		ci->lastaddress = adr;
     61
     62		while (n) {
     63			int len = n;
     64
     65			if (ci->cfg.max_i2c && len > ci->cfg.max_i2c)
     66				len = ci->cfg.max_i2c;
     67			status = regmap_raw_read(ci->regmap, 1, data, len);
     68			if (status)
     69				return status;
     70			data += len;
     71			n -= len;
     72		}
     73	}
     74	return status;
     75}
     76
     77static int read_reg(struct cxd *ci, u8 reg, u8 *val)
     78{
     79	return read_block(ci, reg, val, 1);
     80}
     81
     82static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
     83{
     84	int status;
     85	u8 addr[2] = {address & 0xff, address >> 8};
     86
     87	status = regmap_raw_write(ci->regmap, 2, addr, 2);
     88	if (!status)
     89		status = regmap_raw_read(ci->regmap, 3, data, n);
     90	return status;
     91}
     92
     93static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
     94{
     95	int status;
     96	u8 addr[2] = {address & 0xff, address >> 8};
     97
     98	status = regmap_raw_write(ci->regmap, 2, addr, 2);
     99	if (!status) {
    100		u8 buf[256];
    101
    102		memcpy(buf, data, n);
    103		status = regmap_raw_write(ci->regmap, 3, buf, n);
    104	}
    105	return status;
    106}
    107
    108static int read_io(struct cxd *ci, u16 address, unsigned int *val)
    109{
    110	int status;
    111	u8 addr[2] = {address & 0xff, address >> 8};
    112
    113	status = regmap_raw_write(ci->regmap, 2, addr, 2);
    114	if (!status)
    115		status = regmap_read(ci->regmap, 3, val);
    116	return status;
    117}
    118
    119static int write_io(struct cxd *ci, u16 address, u8 val)
    120{
    121	int status;
    122	u8 addr[2] = {address & 0xff, address >> 8};
    123
    124	status = regmap_raw_write(ci->regmap, 2, addr, 2);
    125	if (!status)
    126		status = regmap_write(ci->regmap, 3, val);
    127	return status;
    128}
    129
    130static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
    131{
    132	int status = 0;
    133	unsigned int regval;
    134
    135	if (ci->lastaddress != reg)
    136		status = regmap_write(ci->regmap, 0, reg);
    137	if (!status && reg >= 6 && reg <= 8 && mask != 0xff) {
    138		status = regmap_read(ci->regmap, 1, &regval);
    139		ci->regs[reg] = regval;
    140	}
    141	ci->lastaddress = reg;
    142	ci->regs[reg] = (ci->regs[reg] & (~mask)) | val;
    143	if (!status)
    144		status = regmap_write(ci->regmap, 1, ci->regs[reg]);
    145	if (reg == 0x20)
    146		ci->regs[reg] &= 0x7f;
    147	return status;
    148}
    149
    150static int write_reg(struct cxd *ci, u8 reg, u8 val)
    151{
    152	return write_regm(ci, reg, val, 0xff);
    153}
    154
    155static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
    156{
    157	int status = 0;
    158	u8 *buf = ci->wbuf;
    159
    160	if (ci->lastaddress != adr)
    161		status = regmap_write(ci->regmap, 0, adr);
    162	if (status)
    163		return status;
    164
    165	ci->lastaddress = adr;
    166	while (n) {
    167		int len = n;
    168
    169		if (ci->cfg.max_i2c && (len + 1 > ci->cfg.max_i2c))
    170			len = ci->cfg.max_i2c - 1;
    171		memcpy(buf, data, len);
    172		status = regmap_raw_write(ci->regmap, 1, buf, len);
    173		if (status)
    174			return status;
    175		n -= len;
    176		data += len;
    177	}
    178	return status;
    179}
    180
    181static void set_mode(struct cxd *ci, int mode)
    182{
    183	if (mode == ci->mode)
    184		return;
    185
    186	switch (mode) {
    187	case 0x00: /* IO mem */
    188		write_regm(ci, 0x06, 0x00, 0x07);
    189		break;
    190	case 0x01: /* ATT mem */
    191		write_regm(ci, 0x06, 0x02, 0x07);
    192		break;
    193	default:
    194		break;
    195	}
    196	ci->mode = mode;
    197}
    198
    199static void cam_mode(struct cxd *ci, int mode)
    200{
    201	u8 dummy;
    202
    203	if (mode == ci->cammode)
    204		return;
    205
    206	switch (mode) {
    207	case 0x00:
    208		write_regm(ci, 0x20, 0x80, 0x80);
    209		break;
    210	case 0x01:
    211		if (!ci->en.read_data)
    212			return;
    213		ci->write_busy = 0;
    214		dev_info(&ci->client->dev, "enable cam buffer mode\n");
    215		write_reg(ci, 0x0d, 0x00);
    216		write_reg(ci, 0x0e, 0x01);
    217		write_regm(ci, 0x08, 0x40, 0x40);
    218		read_reg(ci, 0x12, &dummy);
    219		write_regm(ci, 0x08, 0x80, 0x80);
    220		break;
    221	default:
    222		break;
    223	}
    224	ci->cammode = mode;
    225}
    226
    227static int init(struct cxd *ci)
    228{
    229	int status;
    230
    231	mutex_lock(&ci->lock);
    232	ci->mode = -1;
    233	do {
    234		status = write_reg(ci, 0x00, 0x00);
    235		if (status < 0)
    236			break;
    237		status = write_reg(ci, 0x01, 0x00);
    238		if (status < 0)
    239			break;
    240		status = write_reg(ci, 0x02, 0x10);
    241		if (status < 0)
    242			break;
    243		status = write_reg(ci, 0x03, 0x00);
    244		if (status < 0)
    245			break;
    246		status = write_reg(ci, 0x05, 0xFF);
    247		if (status < 0)
    248			break;
    249		status = write_reg(ci, 0x06, 0x1F);
    250		if (status < 0)
    251			break;
    252		status = write_reg(ci, 0x07, 0x1F);
    253		if (status < 0)
    254			break;
    255		status = write_reg(ci, 0x08, 0x28);
    256		if (status < 0)
    257			break;
    258		status = write_reg(ci, 0x14, 0x20);
    259		if (status < 0)
    260			break;
    261
    262		/* TOSTRT = 8, Mode B (gated clock), falling Edge,
    263		 * Serial, POL=HIGH, MSB
    264		 */
    265		status = write_reg(ci, 0x0A, 0xA7);
    266		if (status < 0)
    267			break;
    268
    269		status = write_reg(ci, 0x0B, 0x33);
    270		if (status < 0)
    271			break;
    272		status = write_reg(ci, 0x0C, 0x33);
    273		if (status < 0)
    274			break;
    275
    276		status = write_regm(ci, 0x14, 0x00, 0x0F);
    277		if (status < 0)
    278			break;
    279		status = write_reg(ci, 0x15, ci->clk_reg_b);
    280		if (status < 0)
    281			break;
    282		status = write_regm(ci, 0x16, 0x00, 0x0F);
    283		if (status < 0)
    284			break;
    285		status = write_reg(ci, 0x17, ci->clk_reg_f);
    286		if (status < 0)
    287			break;
    288
    289		if (ci->cfg.clock_mode == 2) {
    290			/* bitrate*2^13/ 72000 */
    291			u32 reg = ((ci->cfg.bitrate << 13) + 71999) / 72000;
    292
    293			if (ci->cfg.polarity) {
    294				status = write_reg(ci, 0x09, 0x6f);
    295				if (status < 0)
    296					break;
    297			} else {
    298				status = write_reg(ci, 0x09, 0x6d);
    299				if (status < 0)
    300					break;
    301			}
    302			status = write_reg(ci, 0x20, 0x08);
    303			if (status < 0)
    304				break;
    305			status = write_reg(ci, 0x21, (reg >> 8) & 0xff);
    306			if (status < 0)
    307				break;
    308			status = write_reg(ci, 0x22, reg & 0xff);
    309			if (status < 0)
    310				break;
    311		} else if (ci->cfg.clock_mode == 1) {
    312			if (ci->cfg.polarity) {
    313				status = write_reg(ci, 0x09, 0x6f); /* D */
    314				if (status < 0)
    315					break;
    316			} else {
    317				status = write_reg(ci, 0x09, 0x6d);
    318				if (status < 0)
    319					break;
    320			}
    321			status = write_reg(ci, 0x20, 0x68);
    322			if (status < 0)
    323				break;
    324			status = write_reg(ci, 0x21, 0x00);
    325			if (status < 0)
    326				break;
    327			status = write_reg(ci, 0x22, 0x02);
    328			if (status < 0)
    329				break;
    330		} else {
    331			if (ci->cfg.polarity) {
    332				status = write_reg(ci, 0x09, 0x4f); /* C */
    333				if (status < 0)
    334					break;
    335			} else {
    336				status = write_reg(ci, 0x09, 0x4d);
    337				if (status < 0)
    338					break;
    339			}
    340			status = write_reg(ci, 0x20, 0x28);
    341			if (status < 0)
    342				break;
    343			status = write_reg(ci, 0x21, 0x00);
    344			if (status < 0)
    345				break;
    346			status = write_reg(ci, 0x22, 0x07);
    347			if (status < 0)
    348				break;
    349		}
    350
    351		status = write_regm(ci, 0x20, 0x80, 0x80);
    352		if (status < 0)
    353			break;
    354		status = write_regm(ci, 0x03, 0x02, 0x02);
    355		if (status < 0)
    356			break;
    357		status = write_reg(ci, 0x01, 0x04);
    358		if (status < 0)
    359			break;
    360		status = write_reg(ci, 0x00, 0x31);
    361		if (status < 0)
    362			break;
    363
    364		/* Put TS in bypass */
    365		status = write_regm(ci, 0x09, 0x08, 0x08);
    366		if (status < 0)
    367			break;
    368		ci->cammode = -1;
    369		cam_mode(ci, 0);
    370	} while (0);
    371	mutex_unlock(&ci->lock);
    372
    373	return 0;
    374}
    375
    376static int read_attribute_mem(struct dvb_ca_en50221 *ca,
    377			      int slot, int address)
    378{
    379	struct cxd *ci = ca->data;
    380	u8 val;
    381
    382	mutex_lock(&ci->lock);
    383	set_mode(ci, 1);
    384	read_pccard(ci, address, &val, 1);
    385	mutex_unlock(&ci->lock);
    386	return val;
    387}
    388
    389static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
    390			       int address, u8 value)
    391{
    392	struct cxd *ci = ca->data;
    393
    394	mutex_lock(&ci->lock);
    395	set_mode(ci, 1);
    396	write_pccard(ci, address, &value, 1);
    397	mutex_unlock(&ci->lock);
    398	return 0;
    399}
    400
    401static int read_cam_control(struct dvb_ca_en50221 *ca,
    402			    int slot, u8 address)
    403{
    404	struct cxd *ci = ca->data;
    405	unsigned int val;
    406
    407	mutex_lock(&ci->lock);
    408	set_mode(ci, 0);
    409	read_io(ci, address, &val);
    410	mutex_unlock(&ci->lock);
    411	return val;
    412}
    413
    414static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
    415			     u8 address, u8 value)
    416{
    417	struct cxd *ci = ca->data;
    418
    419	mutex_lock(&ci->lock);
    420	set_mode(ci, 0);
    421	write_io(ci, address, value);
    422	mutex_unlock(&ci->lock);
    423	return 0;
    424}
    425
    426static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
    427{
    428	struct cxd *ci = ca->data;
    429
    430	if (ci->cammode)
    431		read_data(ca, slot, ci->rbuf, 0);
    432
    433	mutex_lock(&ci->lock);
    434	cam_mode(ci, 0);
    435	write_reg(ci, 0x00, 0x21);
    436	write_reg(ci, 0x06, 0x1F);
    437	write_reg(ci, 0x00, 0x31);
    438	write_regm(ci, 0x20, 0x80, 0x80);
    439	write_reg(ci, 0x03, 0x02);
    440	ci->ready = 0;
    441	ci->mode = -1;
    442	{
    443		int i;
    444
    445		for (i = 0; i < 100; i++) {
    446			usleep_range(10000, 11000);
    447			if (ci->ready)
    448				break;
    449		}
    450	}
    451	mutex_unlock(&ci->lock);
    452	return 0;
    453}
    454
    455static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
    456{
    457	struct cxd *ci = ca->data;
    458
    459	dev_dbg(&ci->client->dev, "%s\n", __func__);
    460	if (ci->cammode)
    461		read_data(ca, slot, ci->rbuf, 0);
    462	mutex_lock(&ci->lock);
    463	write_reg(ci, 0x00, 0x21);
    464	write_reg(ci, 0x06, 0x1F);
    465	msleep(300);
    466
    467	write_regm(ci, 0x09, 0x08, 0x08);
    468	write_regm(ci, 0x20, 0x80, 0x80); /* Reset CAM Mode */
    469	write_regm(ci, 0x06, 0x07, 0x07); /* Clear IO Mode */
    470
    471	ci->mode = -1;
    472	ci->write_busy = 0;
    473	mutex_unlock(&ci->lock);
    474	return 0;
    475}
    476
    477static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
    478{
    479	struct cxd *ci = ca->data;
    480
    481	mutex_lock(&ci->lock);
    482	write_regm(ci, 0x09, 0x00, 0x08);
    483	set_mode(ci, 0);
    484	cam_mode(ci, 1);
    485	mutex_unlock(&ci->lock);
    486	return 0;
    487}
    488
    489static int campoll(struct cxd *ci)
    490{
    491	u8 istat;
    492
    493	read_reg(ci, 0x04, &istat);
    494	if (!istat)
    495		return 0;
    496	write_reg(ci, 0x05, istat);
    497
    498	if (istat & 0x40)
    499		ci->dr = 1;
    500	if (istat & 0x20)
    501		ci->write_busy = 0;
    502
    503	if (istat & 2) {
    504		u8 slotstat;
    505
    506		read_reg(ci, 0x01, &slotstat);
    507		if (!(2 & slotstat)) {
    508			if (!ci->slot_stat) {
    509				ci->slot_stat |=
    510					      DVB_CA_EN50221_POLL_CAM_PRESENT;
    511				write_regm(ci, 0x03, 0x08, 0x08);
    512			}
    513
    514		} else {
    515			if (ci->slot_stat) {
    516				ci->slot_stat = 0;
    517				write_regm(ci, 0x03, 0x00, 0x08);
    518				dev_info(&ci->client->dev, "NO CAM\n");
    519				ci->ready = 0;
    520			}
    521		}
    522		if ((istat & 8) &&
    523		    ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
    524			ci->ready = 1;
    525			ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
    526		}
    527	}
    528	return 0;
    529}
    530
    531static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
    532{
    533	struct cxd *ci = ca->data;
    534	u8 slotstat;
    535
    536	mutex_lock(&ci->lock);
    537	campoll(ci);
    538	read_reg(ci, 0x01, &slotstat);
    539	mutex_unlock(&ci->lock);
    540
    541	return ci->slot_stat;
    542}
    543
    544static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
    545{
    546	struct cxd *ci = ca->data;
    547	u8 msb, lsb;
    548	u16 len;
    549
    550	mutex_lock(&ci->lock);
    551	campoll(ci);
    552	mutex_unlock(&ci->lock);
    553
    554	if (!ci->dr)
    555		return 0;
    556
    557	mutex_lock(&ci->lock);
    558	read_reg(ci, 0x0f, &msb);
    559	read_reg(ci, 0x10, &lsb);
    560	len = ((u16)msb << 8) | lsb;
    561	if (len > ecount || len < 2) {
    562		/* read it anyway or cxd may hang */
    563		read_block(ci, 0x12, ci->rbuf, len);
    564		mutex_unlock(&ci->lock);
    565		return -EIO;
    566	}
    567	read_block(ci, 0x12, ebuf, len);
    568	ci->dr = 0;
    569	mutex_unlock(&ci->lock);
    570	return len;
    571}
    572
    573static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
    574{
    575	struct cxd *ci = ca->data;
    576
    577	if (ci->write_busy)
    578		return -EAGAIN;
    579	mutex_lock(&ci->lock);
    580	write_reg(ci, 0x0d, ecount >> 8);
    581	write_reg(ci, 0x0e, ecount & 0xff);
    582	write_block(ci, 0x11, ebuf, ecount);
    583	ci->write_busy = 1;
    584	mutex_unlock(&ci->lock);
    585	return ecount;
    586}
    587
    588static const struct dvb_ca_en50221 en_templ = {
    589	.read_attribute_mem  = read_attribute_mem,
    590	.write_attribute_mem = write_attribute_mem,
    591	.read_cam_control    = read_cam_control,
    592	.write_cam_control   = write_cam_control,
    593	.slot_reset          = slot_reset,
    594	.slot_shutdown       = slot_shutdown,
    595	.slot_ts_enable      = slot_ts_enable,
    596	.poll_slot_status    = poll_slot_status,
    597	.read_data           = read_data,
    598	.write_data          = write_data,
    599};
    600
    601static int cxd2099_probe(struct i2c_client *client,
    602			 const struct i2c_device_id *id)
    603{
    604	struct cxd *ci;
    605	struct cxd2099_cfg *cfg = client->dev.platform_data;
    606	static const struct regmap_config rm_cfg = {
    607		.reg_bits = 8,
    608		.val_bits = 8,
    609	};
    610	unsigned int val;
    611	int ret;
    612
    613	ci = kzalloc(sizeof(*ci), GFP_KERNEL);
    614	if (!ci) {
    615		ret = -ENOMEM;
    616		goto err;
    617	}
    618
    619	ci->client = client;
    620	memcpy(&ci->cfg, cfg, sizeof(ci->cfg));
    621
    622	ci->regmap = regmap_init_i2c(client, &rm_cfg);
    623	if (IS_ERR(ci->regmap)) {
    624		ret = PTR_ERR(ci->regmap);
    625		goto err_kfree;
    626	}
    627
    628	ret = regmap_read(ci->regmap, 0x00, &val);
    629	if (ret < 0) {
    630		dev_info(&client->dev, "No CXD2099AR detected at 0x%02x\n",
    631			 client->addr);
    632		goto err_rmexit;
    633	}
    634
    635	mutex_init(&ci->lock);
    636	ci->lastaddress = 0xff;
    637	ci->clk_reg_b = 0x4a;
    638	ci->clk_reg_f = 0x1b;
    639
    640	ci->en = en_templ;
    641	ci->en.data = ci;
    642	init(ci);
    643	dev_info(&client->dev, "Attached CXD2099AR at 0x%02x\n", client->addr);
    644
    645	*cfg->en = &ci->en;
    646
    647	if (!buffermode) {
    648		ci->en.read_data = NULL;
    649		ci->en.write_data = NULL;
    650	} else {
    651		dev_info(&client->dev, "Using CXD2099AR buffer mode");
    652	}
    653
    654	i2c_set_clientdata(client, ci);
    655
    656	return 0;
    657
    658err_rmexit:
    659	regmap_exit(ci->regmap);
    660err_kfree:
    661	kfree(ci);
    662err:
    663
    664	return ret;
    665}
    666
    667static int cxd2099_remove(struct i2c_client *client)
    668{
    669	struct cxd *ci = i2c_get_clientdata(client);
    670
    671	regmap_exit(ci->regmap);
    672	kfree(ci);
    673
    674	return 0;
    675}
    676
    677static const struct i2c_device_id cxd2099_id[] = {
    678	{"cxd2099", 0},
    679	{}
    680};
    681MODULE_DEVICE_TABLE(i2c, cxd2099_id);
    682
    683static struct i2c_driver cxd2099_driver = {
    684	.driver = {
    685		.name	= "cxd2099",
    686	},
    687	.probe		= cxd2099_probe,
    688	.remove		= cxd2099_remove,
    689	.id_table	= cxd2099_id,
    690};
    691
    692module_i2c_driver(cxd2099_driver);
    693
    694MODULE_DESCRIPTION("Sony CXD2099AR Common Interface controller driver");
    695MODULE_AUTHOR("Ralph Metzler");
    696MODULE_LICENSE("GPL v2");