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