xref: /linux/drivers/media/dvb-frontends/a8293.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
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  
10  struct a8293_dev {
11  	struct i2c_client *client;
12  	u8 reg[2];
13  };
14  
15  static 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;
60  err:
61  	dev_dbg(&client->dev, "failed=%d\n", ret);
62  	return ret;
63  }
64  
65  static 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;
94  err_kfree:
95  	kfree(dev);
96  err:
97  	dev_dbg(&client->dev, "failed=%d\n", ret);
98  	return ret;
99  }
100  
101  static 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  
111  static const struct i2c_device_id a8293_id_table[] = {
112  	{"a8293", 0},
113  	{}
114  };
115  MODULE_DEVICE_TABLE(i2c, a8293_id_table);
116  
117  static 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  
127  module_i2c_driver(a8293_driver);
128  
129  MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
130  MODULE_DESCRIPTION("Allegro A8293 SEC driver");
131  MODULE_LICENSE("GPL");
132