0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/slab.h>
0014 #include <linux/module.h>
0015 #include <linux/dvb/frontend.h>
0016 #include <linux/types.h>
0017 #include "horus3a.h"
0018 #include <media/dvb_frontend.h>
0019
0020 #define MAX_WRITE_REGSIZE 5
0021
0022 enum horus3a_state {
0023 STATE_UNKNOWN,
0024 STATE_SLEEP,
0025 STATE_ACTIVE
0026 };
0027
0028 struct horus3a_priv {
0029 u32 frequency;
0030 u8 i2c_address;
0031 struct i2c_adapter *i2c;
0032 enum horus3a_state state;
0033 void *set_tuner_data;
0034 int (*set_tuner)(void *, int);
0035 };
0036
0037 static void horus3a_i2c_debug(struct horus3a_priv *priv,
0038 u8 reg, u8 write, const u8 *data, u32 len)
0039 {
0040 dev_dbg(&priv->i2c->dev, "horus3a: I2C %s reg 0x%02x size %d\n",
0041 (write == 0 ? "read" : "write"), reg, len);
0042 print_hex_dump_bytes("horus3a: I2C data: ",
0043 DUMP_PREFIX_OFFSET, data, len);
0044 }
0045
0046 static int horus3a_write_regs(struct horus3a_priv *priv,
0047 u8 reg, const u8 *data, u32 len)
0048 {
0049 int ret;
0050 u8 buf[MAX_WRITE_REGSIZE + 1];
0051 struct i2c_msg msg[1] = {
0052 {
0053 .addr = priv->i2c_address,
0054 .flags = 0,
0055 .len = len + 1,
0056 .buf = buf,
0057 }
0058 };
0059
0060 if (len + 1 > sizeof(buf)) {
0061 dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
0062 reg, len + 1);
0063 return -E2BIG;
0064 }
0065
0066 horus3a_i2c_debug(priv, reg, 1, data, len);
0067 buf[0] = reg;
0068 memcpy(&buf[1], data, len);
0069 ret = i2c_transfer(priv->i2c, msg, 1);
0070 if (ret >= 0 && ret != 1)
0071 ret = -EREMOTEIO;
0072 if (ret < 0) {
0073 dev_warn(&priv->i2c->dev,
0074 "%s: i2c wr failed=%d reg=%02x len=%d\n",
0075 KBUILD_MODNAME, ret, reg, len);
0076 return ret;
0077 }
0078 return 0;
0079 }
0080
0081 static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
0082 {
0083 u8 tmp = val;
0084
0085 return horus3a_write_regs(priv, reg, &tmp, 1);
0086 }
0087
0088 static int horus3a_enter_power_save(struct horus3a_priv *priv)
0089 {
0090 u8 data[2];
0091
0092 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0093 if (priv->state == STATE_SLEEP)
0094 return 0;
0095
0096 horus3a_write_reg(priv, 0x2a, 0x79);
0097
0098 horus3a_write_reg(priv, 0x29, 0x70);
0099
0100 horus3a_write_reg(priv, 0x28, 0x3e);
0101
0102 horus3a_write_reg(priv, 0x2a, 0x19);
0103
0104 horus3a_write_reg(priv, 0x1c, 0x00);
0105
0106 data[0] = 0xC0;
0107
0108 data[1] = 0xA7;
0109
0110 horus3a_write_regs(priv, 0x11, data, sizeof(data));
0111 priv->state = STATE_SLEEP;
0112 return 0;
0113 }
0114
0115 static int horus3a_leave_power_save(struct horus3a_priv *priv)
0116 {
0117 u8 data[2];
0118
0119 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0120 if (priv->state == STATE_ACTIVE)
0121 return 0;
0122
0123 data[0] = 0x00;
0124
0125 data[1] = 0xa7;
0126
0127 horus3a_write_regs(priv, 0x11, data, sizeof(data));
0128
0129 horus3a_write_reg(priv, 0x2a, 0x79);
0130
0131 horus3a_write_reg(priv, 0x1c, 0xc0);
0132
0133 horus3a_write_reg(priv, 0x29, 0x71);
0134 usleep_range(5000, 7000);
0135 priv->state = STATE_ACTIVE;
0136 return 0;
0137 }
0138
0139 static int horus3a_init(struct dvb_frontend *fe)
0140 {
0141 struct horus3a_priv *priv = fe->tuner_priv;
0142
0143 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0144 return 0;
0145 }
0146
0147 static void horus3a_release(struct dvb_frontend *fe)
0148 {
0149 struct horus3a_priv *priv = fe->tuner_priv;
0150
0151 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0152 kfree(fe->tuner_priv);
0153 fe->tuner_priv = NULL;
0154 }
0155
0156 static int horus3a_sleep(struct dvb_frontend *fe)
0157 {
0158 struct horus3a_priv *priv = fe->tuner_priv;
0159
0160 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0161 horus3a_enter_power_save(priv);
0162 return 0;
0163 }
0164
0165 static int horus3a_set_params(struct dvb_frontend *fe)
0166 {
0167 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0168 struct horus3a_priv *priv = fe->tuner_priv;
0169 u32 frequency = p->frequency;
0170 u32 symbol_rate = p->symbol_rate/1000;
0171 u8 mixdiv = 0;
0172 u8 mdiv = 0;
0173 u32 ms = 0;
0174 u8 f_ctl = 0;
0175 u8 g_ctl = 0;
0176 u8 fc_lpf = 0;
0177 u8 data[5];
0178
0179 dev_dbg(&priv->i2c->dev, "%s(): frequency %dkHz symbol_rate %dksps\n",
0180 __func__, frequency, symbol_rate);
0181 if (priv->set_tuner)
0182 priv->set_tuner(priv->set_tuner_data, 0);
0183 if (priv->state == STATE_SLEEP)
0184 horus3a_leave_power_save(priv);
0185
0186
0187 frequency = DIV_ROUND_CLOSEST(frequency, 1000) * 1000;
0188 if (frequency <= 1155000) {
0189 mixdiv = 4;
0190 mdiv = 1;
0191 } else {
0192 mixdiv = 2;
0193 mdiv = 0;
0194 }
0195
0196 ms = DIV_ROUND_CLOSEST((frequency * mixdiv) / 2, 1000);
0197 if (ms > 0x7FFF) {
0198 dev_err(&priv->i2c->dev, "horus3a: invalid frequency %d\n",
0199 frequency);
0200 return -EINVAL;
0201 }
0202 if (frequency < 975000) {
0203
0204 f_ctl = 0x1C;
0205 g_ctl = 0x01;
0206 } else if (frequency < 1050000) {
0207
0208 f_ctl = 0x18;
0209 g_ctl = 0x02;
0210 } else if (frequency < 1150000) {
0211
0212 f_ctl = 0x14;
0213 g_ctl = 0x02;
0214 } else if (frequency < 1250000) {
0215
0216 f_ctl = 0x10;
0217 g_ctl = 0x03;
0218 } else if (frequency < 1350000) {
0219
0220 f_ctl = 0x0C;
0221 g_ctl = 0x04;
0222 } else if (frequency < 1450000) {
0223
0224 f_ctl = 0x0A;
0225 g_ctl = 0x04;
0226 } else if (frequency < 1600000) {
0227
0228 f_ctl = 0x07;
0229 g_ctl = 0x05;
0230 } else if (frequency < 1800000) {
0231
0232 f_ctl = 0x04;
0233 g_ctl = 0x02;
0234 } else if (frequency < 2000000) {
0235
0236 f_ctl = 0x02;
0237 g_ctl = 0x01;
0238 } else {
0239
0240 f_ctl = 0x00;
0241 g_ctl = 0x00;
0242 }
0243
0244 if (p->delivery_system == SYS_DVBS) {
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 if (symbol_rate <= 4300)
0258 fc_lpf = 5;
0259 else if (symbol_rate <= 10000)
0260 fc_lpf = (u8)DIV_ROUND_UP(symbol_rate * 47, 40000);
0261 else
0262 fc_lpf = (u8)DIV_ROUND_UP(symbol_rate * 27, 40000) + 5;
0263
0264 if (fc_lpf > 36)
0265 fc_lpf = 36;
0266 } else if (p->delivery_system == SYS_DVBS2) {
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 if (symbol_rate <= 4500)
0277 fc_lpf = 5;
0278 else if (symbol_rate <= 10000)
0279 fc_lpf = (u8)((symbol_rate * 11 + (10000-1)) / 10000);
0280 else
0281 fc_lpf = (u8)((symbol_rate * 3 + (5000-1)) / 5000 + 5);
0282
0283 if (fc_lpf > 36)
0284 fc_lpf = 36;
0285 } else {
0286 dev_err(&priv->i2c->dev,
0287 "horus3a: invalid delivery system %d\n",
0288 p->delivery_system);
0289 return -EINVAL;
0290 }
0291
0292 data[0] = (u8)((ms >> 7) & 0xFF);
0293 data[1] = (u8)((ms << 1) & 0xFF);
0294 data[2] = 0x00;
0295 data[3] = 0x00;
0296 data[4] = (u8)(mdiv << 7);
0297 horus3a_write_regs(priv, 0x00, data, sizeof(data));
0298
0299 horus3a_write_reg(priv, 0x09, (u8)((g_ctl << 5) | f_ctl));
0300
0301 horus3a_write_reg(priv, 0x37, (u8)(0x80 | (fc_lpf << 1)));
0302
0303 horus3a_write_reg(priv, 0x05, 0x80);
0304
0305 horus3a_write_reg(priv, 0x2a, 0x7b);
0306
0307 msleep(60);
0308
0309 priv->frequency = ms * 2 * 1000 / mixdiv;
0310 return 0;
0311 }
0312
0313 static int horus3a_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0314 {
0315 struct horus3a_priv *priv = fe->tuner_priv;
0316
0317 *frequency = priv->frequency;
0318 return 0;
0319 }
0320
0321 static const struct dvb_tuner_ops horus3a_tuner_ops = {
0322 .info = {
0323 .name = "Sony Horus3a",
0324 .frequency_min_hz = 950 * MHz,
0325 .frequency_max_hz = 2150 * MHz,
0326 .frequency_step_hz = 1 * MHz,
0327 },
0328 .init = horus3a_init,
0329 .release = horus3a_release,
0330 .sleep = horus3a_sleep,
0331 .set_params = horus3a_set_params,
0332 .get_frequency = horus3a_get_frequency,
0333 };
0334
0335 struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
0336 const struct horus3a_config *config,
0337 struct i2c_adapter *i2c)
0338 {
0339 u8 buf[3], val;
0340 struct horus3a_priv *priv = NULL;
0341
0342 priv = kzalloc(sizeof(struct horus3a_priv), GFP_KERNEL);
0343 if (priv == NULL)
0344 return NULL;
0345 priv->i2c_address = (config->i2c_address >> 1);
0346 priv->i2c = i2c;
0347 priv->set_tuner_data = config->set_tuner_priv;
0348 priv->set_tuner = config->set_tuner_callback;
0349
0350 if (fe->ops.i2c_gate_ctrl)
0351 fe->ops.i2c_gate_ctrl(fe, 1);
0352
0353
0354 usleep_range(4000, 6000);
0355
0356 horus3a_write_reg(priv, 0x2a, 0x79);
0357
0358 buf[0] = config->xtal_freq_mhz;
0359 buf[1] = config->xtal_freq_mhz;
0360 buf[2] = 0;
0361
0362 horus3a_write_regs(priv, 0x6, buf, 3);
0363
0364 horus3a_write_reg(priv, 0x0a, 0x40);
0365 switch (config->xtal_freq_mhz) {
0366 case 27:
0367 val = 0x1f;
0368 break;
0369 case 24:
0370 val = 0x10;
0371 break;
0372 case 16:
0373 val = 0xc;
0374 break;
0375 default:
0376 val = 0;
0377 dev_warn(&priv->i2c->dev,
0378 "horus3a: invalid xtal frequency %dMHz\n",
0379 config->xtal_freq_mhz);
0380 break;
0381 }
0382 val <<= 2;
0383 horus3a_write_reg(priv, 0x0e, val);
0384 horus3a_enter_power_save(priv);
0385 usleep_range(3000, 5000);
0386
0387 if (fe->ops.i2c_gate_ctrl)
0388 fe->ops.i2c_gate_ctrl(fe, 0);
0389
0390 memcpy(&fe->ops.tuner_ops, &horus3a_tuner_ops,
0391 sizeof(struct dvb_tuner_ops));
0392 fe->tuner_priv = priv;
0393 dev_info(&priv->i2c->dev,
0394 "Sony HORUS3A attached on addr=%x at I2C adapter %p\n",
0395 priv->i2c_address, priv->i2c);
0396 return fe;
0397 }
0398 EXPORT_SYMBOL(horus3a_attach);
0399
0400 MODULE_DESCRIPTION("Sony HORUS3A satellite tuner driver");
0401 MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>");
0402 MODULE_LICENSE("GPL");