aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/frontends/rtl2830.c67
-rw-r--r--drivers/media/dvb/frontends/rtl2830_priv.h2
2 files changed, 52 insertions, 17 deletions
diff --git a/drivers/media/dvb/frontends/rtl2830.c b/drivers/media/dvb/frontends/rtl2830.c
index 37a9fa29874e..f036701c12ee 100644
--- a/drivers/media/dvb/frontends/rtl2830.c
+++ b/drivers/media/dvb/frontends/rtl2830.c
@@ -31,45 +31,43 @@ int rtl2830_debug;
31module_param_named(debug, rtl2830_debug, int, 0644); 31module_param_named(debug, rtl2830_debug, int, 0644);
32MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 32MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
33 33
34/* write multiple registers */ 34/* write multiple hardware registers */
35static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) 35static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
36{ 36{
37 int ret; 37 int ret;
38 u8 buf[2+len]; 38 u8 buf[1+len];
39 struct i2c_msg msg[1] = { 39 struct i2c_msg msg[1] = {
40 { 40 {
41 .addr = priv->cfg.i2c_addr, 41 .addr = priv->cfg.i2c_addr,
42 .flags = 0, 42 .flags = 0,
43 .len = sizeof(buf), 43 .len = 1+len,
44 .buf = buf, 44 .buf = buf,
45 } 45 }
46 }; 46 };
47 47
48 buf[0] = (reg >> 8) & 0xff; 48 buf[0] = reg;
49 buf[1] = (reg >> 0) & 0xff; 49 memcpy(&buf[1], val, len);
50 memcpy(&buf[2], val, len);
51 50
52 ret = i2c_transfer(priv->i2c, msg, 1); 51 ret = i2c_transfer(priv->i2c, msg, 1);
53 if (ret == 1) { 52 if (ret == 1) {
54 ret = 0; 53 ret = 0;
55 } else { 54 } else {
56 warn("i2c wr failed=%d reg=%04x len=%d", ret, reg, len); 55 warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
57 ret = -EREMOTEIO; 56 ret = -EREMOTEIO;
58 } 57 }
59 return ret; 58 return ret;
60} 59}
61 60
62/* read multiple registers */ 61/* read multiple hardware registers */
63static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) 62static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
64{ 63{
65 int ret; 64 int ret;
66 u8 buf[2];
67 struct i2c_msg msg[2] = { 65 struct i2c_msg msg[2] = {
68 { 66 {
69 .addr = priv->cfg.i2c_addr, 67 .addr = priv->cfg.i2c_addr,
70 .flags = 0, 68 .flags = 0,
71 .len = sizeof(buf), 69 .len = 1,
72 .buf = buf, 70 .buf = &reg,
73 }, { 71 }, {
74 .addr = priv->cfg.i2c_addr, 72 .addr = priv->cfg.i2c_addr,
75 .flags = I2C_M_RD, 73 .flags = I2C_M_RD,
@@ -78,19 +76,54 @@ static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
78 } 76 }
79 }; 77 };
80 78
81 buf[0] = (reg >> 8) & 0xff;
82 buf[1] = (reg >> 0) & 0xff;
83
84 ret = i2c_transfer(priv->i2c, msg, 2); 79 ret = i2c_transfer(priv->i2c, msg, 2);
85 if (ret == 2) { 80 if (ret == 2) {
86 ret = 0; 81 ret = 0;
87 } else { 82 } else {
88 warn("i2c rd failed=%d reg=%04x len=%d", ret, reg, len); 83 warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
89 ret = -EREMOTEIO; 84 ret = -EREMOTEIO;
90 } 85 }
91 return ret; 86 return ret;
92} 87}
93 88
89/* write multiple registers */
90static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
91{
92 int ret;
93 u8 reg2 = (reg >> 0) & 0xff;
94 u8 page = (reg >> 8) & 0xff;
95
96 /* switch bank if needed */
97 if (page != priv->page) {
98 ret = rtl2830_wr(priv, 0x00, &page, 1);
99 if (ret)
100 return ret;
101
102 priv->page = page;
103 }
104
105 return rtl2830_wr(priv, reg2, val, len);
106}
107
108/* read multiple registers */
109static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
110{
111 int ret;
112 u8 reg2 = (reg >> 0) & 0xff;
113 u8 page = (reg >> 8) & 0xff;
114
115 /* switch bank if needed */
116 if (page != priv->page) {
117 ret = rtl2830_wr(priv, 0x00, &page, 1);
118 if (ret)
119 return ret;
120
121 priv->page = page;
122 }
123
124 return rtl2830_rd(priv, reg2, val, len);
125}
126
94#if 0 /* currently not used */ 127#if 0 /* currently not used */
95/* write single register */ 128/* write single register */
96static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val) 129static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val)
diff --git a/drivers/media/dvb/frontends/rtl2830_priv.h b/drivers/media/dvb/frontends/rtl2830_priv.h
index 2bc662ee87a0..49de01dd5e83 100644
--- a/drivers/media/dvb/frontends/rtl2830_priv.h
+++ b/drivers/media/dvb/frontends/rtl2830_priv.h
@@ -42,6 +42,8 @@ struct rtl2830_priv {
42 struct dvb_frontend fe; 42 struct dvb_frontend fe;
43 struct rtl2830_config cfg; 43 struct rtl2830_config cfg;
44 struct i2c_adapter tuner_i2c_adapter; 44 struct i2c_adapter tuner_i2c_adapter;
45
46 u8 page; /* active register page */
45}; 47};
46 48
47struct rtl2830_reg_val_mask { 49struct rtl2830_reg_val_mask {