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

a8293.c (2602B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Allegro A8293 SEC driver
      4 *
      5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
      6 */
      7
      8#include "a8293.h"
      9
     10struct a8293_dev {
     11	struct i2c_client *client;
     12	u8 reg[2];
     13};
     14
     15static int a8293_set_voltage(struct dvb_frontend *fe,
     16			     enum fe_sec_voltage fe_sec_voltage)
     17{
     18	struct a8293_dev *dev = fe->sec_priv;
     19	struct i2c_client *client = dev->client;
     20	int ret;
     21	u8 reg0, reg1;
     22
     23	dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage);
     24
     25	switch (fe_sec_voltage) {
     26	case SEC_VOLTAGE_OFF:
     27		/* ENB=0 */
     28		reg0 = 0x10;
     29		break;
     30	case SEC_VOLTAGE_13:
     31		/* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
     32		reg0 = 0x31;
     33		break;
     34	case SEC_VOLTAGE_18:
     35		/* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
     36		reg0 = 0x38;
     37		break;
     38	default:
     39		ret = -EINVAL;
     40		goto err;
     41	}
     42	if (reg0 != dev->reg[0]) {
     43		ret = i2c_master_send(client, &reg0, 1);
     44		if (ret < 0)
     45			goto err;
     46		dev->reg[0] = reg0;
     47	}
     48
     49	/* TMODE=0, TGATE=1 */
     50	reg1 = 0x82;
     51	if (reg1 != dev->reg[1]) {
     52		ret = i2c_master_send(client, &reg1, 1);
     53		if (ret < 0)
     54			goto err;
     55		dev->reg[1] = reg1;
     56	}
     57
     58	usleep_range(1500, 50000);
     59	return 0;
     60err:
     61	dev_dbg(&client->dev, "failed=%d\n", ret);
     62	return ret;
     63}
     64
     65static int a8293_probe(struct i2c_client *client,
     66		       const struct i2c_device_id *id)
     67{
     68	struct a8293_dev *dev;
     69	struct a8293_platform_data *pdata = client->dev.platform_data;
     70	struct dvb_frontend *fe = pdata->dvb_frontend;
     71	int ret;
     72	u8 buf[2];
     73
     74	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
     75	if (!dev) {
     76		ret = -ENOMEM;
     77		goto err;
     78	}
     79
     80	dev->client = client;
     81
     82	/* check if the SEC is there */
     83	ret = i2c_master_recv(client, buf, 2);
     84	if (ret < 0)
     85		goto err_kfree;
     86
     87	/* override frontend ops */
     88	fe->ops.set_voltage = a8293_set_voltage;
     89	fe->sec_priv = dev;
     90	i2c_set_clientdata(client, dev);
     91
     92	dev_info(&client->dev, "Allegro A8293 SEC successfully attached\n");
     93	return 0;
     94err_kfree:
     95	kfree(dev);
     96err:
     97	dev_dbg(&client->dev, "failed=%d\n", ret);
     98	return ret;
     99}
    100
    101static int a8293_remove(struct i2c_client *client)
    102{
    103	struct a8293_dev *dev = i2c_get_clientdata(client);
    104
    105	dev_dbg(&client->dev, "\n");
    106
    107	kfree(dev);
    108	return 0;
    109}
    110
    111static const struct i2c_device_id a8293_id_table[] = {
    112	{"a8293", 0},
    113	{}
    114};
    115MODULE_DEVICE_TABLE(i2c, a8293_id_table);
    116
    117static struct i2c_driver a8293_driver = {
    118	.driver = {
    119		.name	= "a8293",
    120		.suppress_bind_attrs = true,
    121	},
    122	.probe		= a8293_probe,
    123	.remove		= a8293_remove,
    124	.id_table	= a8293_id_table,
    125};
    126
    127module_i2c_driver(a8293_driver);
    128
    129MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
    130MODULE_DESCRIPTION("Allegro A8293 SEC driver");
    131MODULE_LICENSE("GPL");