^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ZyDAS ZD1301 driver (demodulator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "zd1301_demod.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) static u8 zd1301_demod_gain = 0x38;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) module_param_named(gain, zd1301_demod_gain, byte, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) MODULE_PARM_DESC(gain, "gain (value: 0x00 - 0x70, default: 0x38)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct zd1301_demod_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct dvb_frontend frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct i2c_adapter adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) u8 gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int zd1301_demod_wreg(struct zd1301_demod_dev *dev, u16 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return pdata->reg_write(pdata->reg_priv, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int zd1301_demod_rreg(struct zd1301_demod_dev *dev, u16 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return pdata->reg_read(pdata->reg_priv, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int zd1301_demod_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct zd1301_demod_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 if_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u8 r6a50_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dev_dbg(&pdev->dev, "frequency=%u bandwidth_hz=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) c->frequency, c->bandwidth_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Program tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (fe->ops.tuner_ops.set_params &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) fe->ops.tuner_ops.get_if_frequency) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ret = fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_dbg(&pdev->dev, "if_frequency=%u\n", if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (if_frequency != 36150000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) switch (c->bandwidth_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) r6a50_val = 0x78;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case 7000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) r6a50_val = 0x68;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case 8000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) r6a50_val = 0x58;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ret = zd1301_demod_wreg(dev, 0x6a60, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ret = zd1301_demod_wreg(dev, 0x6a47, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ret = zd1301_demod_wreg(dev, 0x6a48, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ret = zd1301_demod_wreg(dev, 0x6a4a, 0x15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ret = zd1301_demod_wreg(dev, 0x6a4b, 0x63);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = zd1301_demod_wreg(dev, 0x6a5b, 0x99);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret = zd1301_demod_wreg(dev, 0x6a3b, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = zd1301_demod_wreg(dev, 0x6806, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ret = zd1301_demod_wreg(dev, 0x6a41, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = zd1301_demod_wreg(dev, 0x6a42, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ret = zd1301_demod_wreg(dev, 0x6a44, 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = zd1301_demod_wreg(dev, 0x6a45, 0x67);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = zd1301_demod_wreg(dev, 0x6a38, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = zd1301_demod_wreg(dev, 0x6a4c, 0x52);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = zd1301_demod_wreg(dev, 0x6a49, 0x2a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = zd1301_demod_wreg(dev, 0x6840, 0x2e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = zd1301_demod_wreg(dev, 0x6a50, r6a50_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) dev_dbg(&pdev->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int zd1301_demod_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct zd1301_demod_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ret = zd1301_demod_wreg(dev, 0x6a43, 0x70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ret = zd1301_demod_wreg(dev, 0x684e, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = zd1301_demod_wreg(dev, 0x6849, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = zd1301_demod_wreg(dev, 0x68e2, 0xd7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ret = zd1301_demod_wreg(dev, 0x68e0, 0x39);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev_dbg(&pdev->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int zd1301_demod_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct zd1301_demod_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = zd1301_demod_wreg(dev, 0x6840, 0x26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = zd1301_demod_wreg(dev, 0x68e0, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = zd1301_demod_wreg(dev, 0x68e2, 0xd8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ret = zd1301_demod_wreg(dev, 0x6849, 0x4e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = zd1301_demod_wreg(dev, 0x684e, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = zd1301_demod_wreg(dev, 0x6a43, zd1301_demod_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_dbg(&pdev->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int zd1301_demod_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct dvb_frontend_tune_settings *settings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct zd1301_demod_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* ~180ms seems to be enough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) settings->min_delay_ms = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int zd1301_demod_read_status(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct zd1301_demod_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u8 u8tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ret = zd1301_demod_rreg(dev, 0x6a24, &u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (u8tmp > 0x00 && u8tmp < 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dev_dbg(&pdev->dev, "lock byte=%02x\n", u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * Interesting registers here are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * 0x6a05: get some gain value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * 0x6a06: get about same gain value than set to 0x6a43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * 0x6a07: get some gain value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * 0x6a43: set gain value by driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * 0x6a24: get demod lock bits (FSM stage?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * Driver should implement some kind of algorithm to calculate suitable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * value for register 0x6a43, based likely values from register 0x6a05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * and 0x6a07. Looks like gain register 0x6a43 value could be from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * range 0x00 - 0x70.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (dev->gain != zd1301_demod_gain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev->gain = zd1301_demod_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ret = zd1301_demod_wreg(dev, 0x6a43, dev->gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) dev_dbg(&pdev->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static const struct dvb_frontend_ops zd1301_demod_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .delsys = {SYS_DVBT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .name = "ZyDAS ZD1301",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .caps = FE_CAN_FEC_1_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) FE_CAN_FEC_2_3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) FE_CAN_FEC_5_6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) FE_CAN_QAM_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) FE_CAN_QAM_64 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) FE_CAN_GUARD_INTERVAL_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) FE_CAN_HIERARCHY_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) FE_CAN_MUTE_TS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .sleep = zd1301_demod_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .init = zd1301_demod_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .set_frontend = zd1301_demod_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .get_tune_settings = zd1301_demod_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .read_status = zd1301_demod_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return &dev->frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) EXPORT_SYMBOL(zd1301_demod_get_dvb_frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static int zd1301_demod_i2c_master_xfer(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct i2c_msg msg[], int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct zd1301_demod_dev *dev = i2c_get_adapdata(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct platform_device *pdev = dev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u8 u8tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define I2C_XFER_TIMEOUT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #define ZD1301_IS_I2C_XFER_WRITE_READ(_msg, _num) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) (_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define ZD1301_IS_I2C_XFER_WRITE(_msg, _num) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) (_num == 1 && !(_msg[0].flags & I2C_M_RD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define ZD1301_IS_I2C_XFER_READ(_msg, _num) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) (_num == 1 && (_msg[0].flags & I2C_M_RD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (ZD1301_IS_I2C_XFER_WRITE_READ(msg, num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) dev_dbg(&pdev->dev, "write&read msg[0].len=%u msg[1].len=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) msg[0].len, msg[1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (msg[0].len > 1 || msg[1].len > 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ret = zd1301_demod_wreg(dev, 0x6811, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = zd1301_demod_wreg(dev, 0x6812, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret = zd1301_demod_wreg(dev, 0x6813, msg[1].addr << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret = zd1301_demod_wreg(dev, 0x6801, msg[0].buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = zd1301_demod_wreg(dev, 0x6805, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = zd1301_demod_wreg(dev, 0x6804, msg[1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* Poll xfer ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) usleep_range(500, 800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) for (i = 0; i < msg[1].len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = zd1301_demod_rreg(dev, 0x0600 + i, &msg[1].buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) } else if (ZD1301_IS_I2C_XFER_WRITE(msg, num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dev_dbg(&pdev->dev, "write msg[0].len=%u\n", msg[0].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (msg[0].len > 1 + 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = zd1301_demod_wreg(dev, 0x6811, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret = zd1301_demod_wreg(dev, 0x6812, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = zd1301_demod_wreg(dev, 0x6813, msg[0].addr << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ret = zd1301_demod_wreg(dev, 0x6800, msg[0].buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) for (i = 0; i < msg[0].len - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = zd1301_demod_wreg(dev, 0x0600 + i, msg[0].buf[1 + i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ret = zd1301_demod_wreg(dev, 0x6805, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = zd1301_demod_wreg(dev, 0x6804, msg[0].len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Poll xfer ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) usleep_range(500, 800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_dbg(&pdev->dev, "unknown msg[0].len=%u\n", msg[0].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dev_dbg(&pdev->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static u32 zd1301_demod_i2c_functionality(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return I2C_FUNC_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static const struct i2c_algorithm zd1301_demod_i2c_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .master_xfer = zd1301_demod_i2c_master_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .functionality = zd1301_demod_i2c_functionality,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return &dev->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) EXPORT_SYMBOL(zd1301_demod_get_i2c_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* Platform driver interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int zd1301_demod_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct zd1301_demod_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev_err(&pdev->dev, "cannot proceed without platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!pdev->dev.parent->driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev_dbg(&pdev->dev, "no parent device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Setup the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dev->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dev->gain = zd1301_demod_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* Sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Create I2C adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) strscpy(dev->adapter.name, "ZyDAS ZD1301 demod",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) sizeof(dev->adapter.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev->adapter.algo = &zd1301_demod_i2c_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev->adapter.algo_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dev->adapter.dev.parent = pdev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) i2c_set_adapdata(&dev->adapter, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ret = i2c_add_adapter(&dev->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) dev_err(&pdev->dev, "I2C adapter add failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Create dvb frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) memcpy(&dev->frontend.ops, &zd1301_demod_ops, sizeof(dev->frontend.ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) dev->frontend.demodulator_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) platform_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) dev_info(&pdev->dev, "ZyDAS ZD1301 demod attached\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_dbg(&pdev->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int zd1301_demod_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) dev_dbg(&pdev->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) i2c_del_adapter(&dev->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static struct platform_driver zd1301_demod_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .name = "zd1301_demod",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .probe = zd1301_demod_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .remove = zd1301_demod_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) module_platform_driver(zd1301_demod_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) MODULE_DESCRIPTION("ZyDAS ZD1301 demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) MODULE_LICENSE("GPL");