2 * Allegro A8293 SEC driver
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "dvb_frontend.h"
26 struct i2c_adapter *i2c;
27 struct i2c_client *client;
31 static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
34 struct i2c_msg msg[1] = {
36 .addr = priv->i2c_addr,
43 msg[0].flags = I2C_M_RD;
47 ret = i2c_transfer(priv->i2c, msg, 1);
51 dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
52 KBUILD_MODNAME, ret, rd);
59 static int a8293_wr(struct a8293_priv *priv, u8 *val, int len)
61 return a8293_i2c(priv, val, len, 0);
64 static int a8293_rd(struct a8293_priv *priv, u8 *val, int len)
66 return a8293_i2c(priv, val, len, 1);
69 static int a8293_set_voltage(struct dvb_frontend *fe,
70 enum fe_sec_voltage fe_sec_voltage)
72 struct a8293_priv *priv = fe->sec_priv;
75 dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
78 switch (fe_sec_voltage) {
84 /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
88 /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
96 ret = a8293_wr(priv, &priv->reg[0], 1);
100 usleep_range(1500, 50000);
104 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
108 static void a8293_release_sec(struct dvb_frontend *fe)
110 a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
116 struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
117 struct i2c_adapter *i2c, const struct a8293_config *cfg)
120 struct a8293_priv *priv = NULL;
123 /* allocate memory for the internal priv */
124 priv = kzalloc(sizeof(struct a8293_priv), GFP_KERNEL);
132 priv->i2c_addr = cfg->i2c_addr;
135 /* check if the SEC is there */
136 ret = a8293_rd(priv, buf, 2);
142 ret = a8293_wr(priv, &priv->reg[0], 1);
146 /* TMODE=0, TGATE=1 */
148 ret = a8293_wr(priv, &priv->reg[1], 1);
152 fe->ops.release_sec = a8293_release_sec;
154 /* override frontend ops */
155 fe->ops.set_voltage = a8293_set_voltage;
157 dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
162 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
166 EXPORT_SYMBOL(a8293_attach);
168 static int a8293_probe(struct i2c_client *client,
169 const struct i2c_device_id *id)
171 struct a8293_priv *dev;
172 struct a8293_platform_data *pdata = client->dev.platform_data;
173 struct dvb_frontend *fe = pdata->dvb_frontend;
177 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
183 dev->client = client;
184 dev->i2c = client->adapter;
185 dev->i2c_addr = client->addr;
187 /* check if the SEC is there */
188 ret = a8293_rd(dev, buf, 2);
194 ret = a8293_wr(dev, &dev->reg[0], 1);
198 /* TMODE=0, TGATE=1 */
200 ret = a8293_wr(dev, &dev->reg[1], 1);
204 /* override frontend ops */
205 fe->ops.set_voltage = a8293_set_voltage;
208 i2c_set_clientdata(client, dev);
210 dev_info(&client->dev, "Allegro A8293 SEC successfully attached\n");
215 dev_dbg(&client->dev, "failed=%d\n", ret);
219 static int a8293_remove(struct i2c_client *client)
221 struct a8293_dev *dev = i2c_get_clientdata(client);
223 dev_dbg(&client->dev, "\n");
229 static const struct i2c_device_id a8293_id_table[] = {
233 MODULE_DEVICE_TABLE(i2c, a8293_id_table);
235 static struct i2c_driver a8293_driver = {
237 .owner = THIS_MODULE,
239 .suppress_bind_attrs = true,
241 .probe = a8293_probe,
242 .remove = a8293_remove,
243 .id_table = a8293_id_table,
246 module_i2c_driver(a8293_driver);
248 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
249 MODULE_DESCRIPTION("Allegro A8293 SEC driver");
250 MODULE_LICENSE("GPL");