22 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/slab.h>
51 #define dprintk(arg...) do { \
57 static struct init_tab {
145 static struct vsb_snr_tab {
190 static struct qam64_snr_tab {
193 } qam64_snr_tab[] = {
263 static struct qam256_snr_tab {
266 } qam256_snr_tab[] = {
346 u8 buf[] = {
reg, data >> 8, data & 0xff };
354 "ret == %i)\n", __func__, addr, reg, data, ret);
356 return (ret != 1) ? -1 : 0;
366 { .
addr =
addr, .flags = 0, .buf = b0, .len = 1 },
374 return (b1[0] << 8) | b1[1];
392 dprintk(
"%s(%d KHz)\n", __func__, KHz);
411 dprintk(
"%s(%d KHz) Invalid, defaulting to 5380\n",
432 dprintk(
"%s(%d)\n", __func__, mode);
440 dprintk(
"%s(%d) Mode1 or Defaulting\n", __func__, mode);
462 dprintk(
"%s(%d)\n", __func__, inversion);
477 dprintk(
"%s(%d)\n", __func__, serial);
486 static int s5h1411_enable_modulation(
struct dvb_frontend *fe,
491 dprintk(
"%s(0x%08x)\n", __func__, m);
494 dprintk(
"%s() Already at desired modulation. Skipping...\n",
501 dprintk(
"%s() VSB_8\n", __func__);
502 s5h1411_set_if_freq(fe, state->
config->vsb_if);
510 dprintk(
"%s() QAM_AUTO (64/256)\n", __func__);
511 s5h1411_set_if_freq(fe, state->
config->qam_if);
518 dprintk(
"%s() Invalid modulation\n", __func__);
524 s5h1411_softreset(fe);
533 dprintk(
"%s(%d)\n", __func__, enable);
541 static int s5h1411_set_gpio(
struct dvb_frontend *fe,
int enable)
546 dprintk(
"%s(%d)\n", __func__, enable);
557 static int s5h1411_set_powerstate(
struct dvb_frontend *fe,
int enable)
561 dprintk(
"%s(%d)\n", __func__, enable);
567 s5h1411_softreset(fe);
575 return s5h1411_set_powerstate(fe, 1);
578 static int s5h1411_register_reset(
struct dvb_frontend *fe)
588 static int s5h1411_set_frontend(
struct dvb_frontend *fe)
595 s5h1411_softreset(fe);
601 if (fe->
ops.tuner_ops.set_params) {
602 if (fe->
ops.i2c_gate_ctrl)
603 fe->
ops.i2c_gate_ctrl(fe, 1);
605 fe->
ops.tuner_ops.set_params(fe);
607 if (fe->
ops.i2c_gate_ctrl)
608 fe->
ops.i2c_gate_ctrl(fe, 0);
613 s5h1411_softreset(fe);
627 s5h1411_set_powerstate(fe, 0);
628 s5h1411_register_reset(fe);
631 s5h1411_writereg(state, init_tab[i].addr,
645 s5h1411_set_serialmode(fe, 1);
648 s5h1411_set_serialmode(fe, 0);
650 s5h1411_set_spectralinversion(fe, state->
config->inversion);
651 s5h1411_set_if_freq(fe, state->
config->vsb_if);
652 s5h1411_set_gpio(fe, state->
config->gpio);
653 s5h1411_set_mpeg_timing(fe, state->
config->mpeg_timing);
654 s5h1411_softreset(fe);
657 s5h1411_i2c_gate_ctrl(fe, 0);
698 switch (state->
config->status_mode) {
705 if (fe->
ops.tuner_ops.get_status) {
706 if (fe->
ops.i2c_gate_ctrl)
707 fe->
ops.i2c_gate_ctrl(fe, 1);
709 fe->
ops.tuner_ops.get_status(fe, &tuner_status);
711 if (fe->
ops.i2c_gate_ctrl)
712 fe->
ops.i2c_gate_ctrl(fe, 0);
719 dprintk(
"%s() status 0x%08x\n", __func__, *status);
729 for (i = 0; i <
ARRAY_SIZE(qam256_snr_tab); i++) {
730 if (v < qam256_snr_tab[i].val) {
731 *snr = qam256_snr_tab[
i].data;
744 for (i = 0; i <
ARRAY_SIZE(qam64_snr_tab); i++) {
745 if (v < qam64_snr_tab[i].val) {
746 *snr = qam64_snr_tab[
i].data;
759 for (i = 0; i <
ARRAY_SIZE(vsb_snr_tab); i++) {
760 if (v > vsb_snr_tab[i].val) {
761 *snr = vsb_snr_tab[
i].data;
766 dprintk(
"%s() snr=%d\n", __func__, *snr);
779 return s5h1411_qam64_lookup_snr(fe, snr, reg);
782 return s5h1411_qam256_lookup_snr(fe, snr, reg);
786 return s5h1411_vsb_lookup_snr(fe, snr, reg);
794 static int s5h1411_read_signal_strength(
struct dvb_frontend *fe,
795 u16 *signal_strength)
806 int ret = s5h1411_read_snr(fe, &snr);
808 *signal_strength = 0;
816 tmp = (snr * ((1 << 24) / 10));
820 if (tmp >= 8960 * 0x10000)
821 *signal_strength = 0xffff;
823 *signal_strength = tmp / 8960;
829 static int s5h1411_read_ucblocks(
struct dvb_frontend *fe,
u32 *ucblocks)
840 return s5h1411_read_ucblocks(fe, ber);
843 static int s5h1411_get_frontend(
struct dvb_frontend *fe)
854 static int s5h1411_get_tune_settings(
struct dvb_frontend *fe,
897 if (s5h1411_init(&state->
frontend) != 0) {
907 s5h1411_set_powerstate(&state->
frontend, 1);
920 .name =
"Samsung S5H1411 QAM/8VSB Frontend",
921 .frequency_min = 54000000,
922 .frequency_max = 858000000,
923 .frequency_stepsize = 62500,
927 .init = s5h1411_init,
928 .sleep = s5h1411_sleep,
929 .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl,
930 .set_frontend = s5h1411_set_frontend,
931 .get_frontend = s5h1411_get_frontend,
932 .get_tune_settings = s5h1411_get_tune_settings,
933 .read_status = s5h1411_read_status,
934 .read_ber = s5h1411_read_ber,
935 .read_signal_strength = s5h1411_read_signal_strength,
936 .read_snr = s5h1411_read_snr,
937 .read_ucblocks = s5h1411_read_ucblocks,
938 .release = s5h1411_release,