diff options
-rw-r--r-- | drivers/media/dvb/frontends/rtl2830.c | 67 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/rtl2830_priv.h | 2 |
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; | |||
31 | module_param_named(debug, rtl2830_debug, int, 0644); | 31 | module_param_named(debug, rtl2830_debug, int, 0644); |
32 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 32 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
33 | 33 | ||
34 | /* write multiple registers */ | 34 | /* write multiple hardware registers */ |
35 | static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) | 35 | static 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 */ |
63 | static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) | 62 | static 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 = ®, |
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 */ | ||
90 | static 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 */ | ||
109 | static 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 */ |
96 | static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val) | 129 | static 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 | ||
47 | struct rtl2830_reg_val_mask { | 49 | struct rtl2830_reg_val_mask { |