aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMalcolm Priestley <tvboxspy@gmail.com>2013-12-24 11:17:12 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 06:35:58 -0500
commit06af15d1b6f45c60358feab88004472e5428f01c (patch)
tree57ec8127c9cb1a898951179a75d9ac7a0b8729b8 /drivers/media
parent58f087c9b670ea7001d640fadbf7e4e91e739d6b (diff)
[media] m88rs2000: add m88rs2000_set_carrieroffset
Set the carrier offset correctly using the default mclk values. Add function m88rs2000_get_mclk to calculate the mclk value against crystal frequency which will later be used for other functions. Add function m88rs2000_set_carrieroffset to calculate and set the offset value. variable offset becomes a signed value. Register 0x86 is set the appropriate value according to remainder value of frequency % 192857 calculation as shown. Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> Cc: stable@vger.kernel.org # v3.9+ Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.c77
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.h2
2 files changed, 59 insertions, 20 deletions
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index 4da5272075cb..8091653e8864 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -110,6 +110,52 @@ static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 reg)
110 return b1[0]; 110 return b1[0];
111} 111}
112 112
113static u32 m88rs2000_get_mclk(struct dvb_frontend *fe)
114{
115 struct m88rs2000_state *state = fe->demodulator_priv;
116 u32 mclk;
117 u8 reg;
118 /* Must not be 0x00 or 0xff */
119 reg = m88rs2000_readreg(state, 0x86);
120 if (!reg || reg == 0xff)
121 return 0;
122
123 reg /= 2;
124 reg += 1;
125
126 mclk = (u32)(reg * RS2000_FE_CRYSTAL_KHZ + 28 / 2) / 28;
127
128 return mclk;
129}
130
131static int m88rs2000_set_carrieroffset(struct dvb_frontend *fe, s16 offset)
132{
133 struct m88rs2000_state *state = fe->demodulator_priv;
134 u32 mclk;
135 s32 tmp;
136 u8 reg;
137 int ret;
138
139 mclk = m88rs2000_get_mclk(fe);
140 if (!mclk)
141 return -EINVAL;
142
143 tmp = (offset * 4096 + (s32)mclk / 2) / (s32)mclk;
144 if (tmp < 0)
145 tmp += 4096;
146
147 /* Carrier Offset */
148 ret = m88rs2000_writereg(state, 0x9c, (u8)(tmp >> 4));
149
150 reg = m88rs2000_readreg(state, 0x9d);
151 reg &= 0xf;
152 reg |= (u8)(tmp & 0xf) << 4;
153
154 ret |= m88rs2000_writereg(state, 0x9d, reg);
155
156 return ret;
157}
158
113static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate) 159static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
114{ 160{
115 struct m88rs2000_state *state = fe->demodulator_priv; 161 struct m88rs2000_state *state = fe->demodulator_priv;
@@ -540,9 +586,8 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
540 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 586 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
541 fe_status_t status; 587 fe_status_t status;
542 int i, ret = 0; 588 int i, ret = 0;
543 s32 tmp;
544 u32 tuner_freq; 589 u32 tuner_freq;
545 u16 offset = 0; 590 s16 offset = 0;
546 u8 reg; 591 u8 reg;
547 592
548 state->no_lock_count = 0; 593 state->no_lock_count = 0;
@@ -567,26 +612,18 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
567 if (ret < 0) 612 if (ret < 0)
568 return -ENODEV; 613 return -ENODEV;
569 614
570 offset = tuner_freq - c->frequency; 615 offset = (s16)((s32)tuner_freq - c->frequency);
571 616
572 /* calculate offset assuming 96000kHz*/ 617 /* default mclk value 96.4285 * 2 * 1000 = 192857 */
573 tmp = offset; 618 if (((c->frequency % 192857) >= (192857 - 3000)) ||
574 tmp *= 65536; 619 (c->frequency % 192857) <= 3000)
575 620 ret = m88rs2000_writereg(state, 0x86, 0xc2);
576 tmp = (2 * tmp + 96000) / (2 * 96000); 621 else
577 if (tmp < 0) 622 ret = m88rs2000_writereg(state, 0x86, 0xc6);
578 tmp += 65536;
579
580 offset = tmp & 0xffff;
581
582 ret = m88rs2000_writereg(state, 0x9a, 0x30);
583 /* Unknown usually 0xc6 sometimes 0xc1 */
584 reg = m88rs2000_readreg(state, 0x86);
585 ret |= m88rs2000_writereg(state, 0x86, reg);
586 /* Offset lower nibble always 0 */
587 ret |= m88rs2000_writereg(state, 0x9c, (offset >> 8));
588 ret |= m88rs2000_writereg(state, 0x9d, offset & 0xf0);
589 623
624 ret |= m88rs2000_set_carrieroffset(fe, offset);
625 if (ret < 0)
626 return -ENODEV;
590 627
591 /* Reset Demod */ 628 /* Reset Demod */
592 ret = m88rs2000_tab_set(state, fe_reset); 629 ret = m88rs2000_tab_set(state, fe_reset);
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
index 14ce31e76ae6..0a50ea90736b 100644
--- a/drivers/media/dvb-frontends/m88rs2000.h
+++ b/drivers/media/dvb-frontends/m88rs2000.h
@@ -53,6 +53,8 @@ static inline struct dvb_frontend *m88rs2000_attach(
53} 53}
54#endif /* CONFIG_DVB_M88RS2000 */ 54#endif /* CONFIG_DVB_M88RS2000 */
55 55
56#define RS2000_FE_CRYSTAL_KHZ 27000
57
56enum { 58enum {
57 DEMOD_WRITE = 0x1, 59 DEMOD_WRITE = 0x1,
58 WRITE_DELAY = 0x10, 60 WRITE_DELAY = 0x10,