^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) * Realtek RTL2830 DVB-T demodulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 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 "rtl2830_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* Our regmap is bypassing I2C adapter lock, thus we do it! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static int rtl2830_bulk_write(struct i2c_client *client, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) const void *val, size_t val_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ret = regmap_bulk_write(dev->regmap, reg, val, val_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int rtl2830_update_bits(struct i2c_client *client, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned int mask, unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ret = regmap_update_bits(dev->regmap, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int rtl2830_bulk_read(struct i2c_client *client, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) void *val, size_t val_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ret = regmap_bulk_read(dev->regmap, reg, val, val_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int rtl2830_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct rtl2830_reg_val_mask tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {0x00d, 0x01, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {0x00d, 0x10, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {0x104, 0x00, 0x1e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {0x105, 0x80, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {0x110, 0x02, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {0x110, 0x08, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {0x17b, 0x00, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {0x17d, 0x05, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {0x17d, 0x50, 0xf0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {0x18c, 0x08, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {0x18d, 0x00, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {0x188, 0x05, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {0x189, 0x00, 0xfc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {0x2d5, 0x02, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {0x2f1, 0x02, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {0x2f1, 0x20, 0xf8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {0x16d, 0x00, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {0x1a6, 0x00, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {0x106, dev->pdata->vtop, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {0x107, dev->pdata->krf, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {0x112, 0x28, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {0x103, dev->pdata->agc_targ_val, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {0x00a, 0x02, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {0x140, 0x0c, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {0x140, 0x40, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {0x15b, 0x05, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {0x15b, 0x28, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {0x15c, 0x05, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {0x15c, 0x28, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {0x115, dev->pdata->spec_inv, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {0x16f, 0x01, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {0x170, 0x18, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {0x172, 0x0f, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {0x173, 0x08, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {0x175, 0x01, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {0x176, 0x00, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) for (i = 0; i < ARRAY_SIZE(tab); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ret = rtl2830_update_bits(client, tab[i].reg, tab[i].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) tab[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = rtl2830_bulk_write(client, 0x18f, "\x28\x00", 2);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ret = rtl2830_bulk_write(client, 0x195,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* TODO: spec init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* soft reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = rtl2830_update_bits(client, 0x101, 0x04, 0x04);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = rtl2830_update_bits(client, 0x101, 0x04, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* init stats here in order signal app which stats are supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) c->post_bit_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev->sleeping = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int rtl2830_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) dev->sleeping = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev->fe_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int rtl2830_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) s->min_delay_ms = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) s->step_size = fe->ops.info.frequency_stepsize_hz * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) s->max_drift = (fe->ops.info.frequency_stepsize_hz * 2) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int rtl2830_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u64 num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u8 buf[3], u8tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u32 if_ctl, if_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static const u8 bw_params1[3][34] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static const u8 bw_params2[3][6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30}, /* 6 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98}, /* 7 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64}, /* 8 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev_dbg(&client->dev, "frequency=%u bandwidth_hz=%u inversion=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) c->frequency, c->bandwidth_hz, c->inversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* program tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (fe->ops.tuner_ops.set_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) switch (c->bandwidth_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case 7000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case 8000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) i = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_err(&client->dev, "invalid bandwidth_hz %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) c->bandwidth_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = rtl2830_update_bits(client, 0x008, 0x06, i << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* program if frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (fe->ops.tuner_ops.get_if_frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) num = if_frequency % dev->pdata->clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) num *= 0x400000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) num = div_u64(num, dev->pdata->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) num = -num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if_ctl = num & 0x3fffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_dbg(&client->dev, "if_frequency=%d if_ctl=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if_frequency, if_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) buf[0] = (if_ctl >> 16) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) buf[1] = (if_ctl >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) buf[2] = (if_ctl >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ret = rtl2830_bulk_read(client, 0x119, &u8tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) buf[0] |= u8tmp & 0xc0; /* [7:6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = rtl2830_bulk_write(client, 0x119, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* 1/2 split I2C write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = rtl2830_bulk_write(client, 0x11c, &bw_params1[i][0], 17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* 2/2 split I2C write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = rtl2830_bulk_write(client, 0x12d, &bw_params1[i][17], 17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ret = rtl2830_bulk_write(client, 0x19d, bw_params2[i], 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static int rtl2830_get_frontend(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (dev->sleeping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ret = rtl2830_bulk_read(client, 0x33c, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ret = rtl2830_bulk_read(client, 0x351, &buf[2], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_dbg(&client->dev, "TPS=%*ph\n", 3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) switch ((buf[0] >> 2) & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) c->modulation = QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) c->modulation = QAM_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) c->modulation = QAM_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) switch ((buf[2] >> 2) & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) c->transmission_mode = TRANSMISSION_MODE_2K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) c->transmission_mode = TRANSMISSION_MODE_8K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) switch ((buf[2] >> 0) & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) c->guard_interval = GUARD_INTERVAL_1_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) c->guard_interval = GUARD_INTERVAL_1_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) c->guard_interval = GUARD_INTERVAL_1_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) c->guard_interval = GUARD_INTERVAL_1_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) switch ((buf[0] >> 4) & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) c->hierarchy = HIERARCHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) c->hierarchy = HIERARCHY_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) c->hierarchy = HIERARCHY_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) c->hierarchy = HIERARCHY_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) switch ((buf[1] >> 3) & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) c->code_rate_HP = FEC_1_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) c->code_rate_HP = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) c->code_rate_HP = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) c->code_rate_HP = FEC_5_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) c->code_rate_HP = FEC_7_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) switch ((buf[1] >> 0) & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) c->code_rate_LP = FEC_1_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) c->code_rate_LP = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) c->code_rate_LP = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) c->code_rate_LP = FEC_5_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) c->code_rate_LP = FEC_7_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int rtl2830_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int ret, stmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u8 u8tmp, buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (dev->sleeping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = rtl2830_bulk_read(client, 0x351, &u8tmp, 1);
^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) u8tmp = (u8tmp >> 3) & 0x0f; /* [6:3] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (u8tmp == 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) } else if (u8tmp == 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev->fe_status = *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* Signal strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (dev->fe_status & FE_HAS_SIGNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Read IF AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ret = rtl2830_bulk_read(client, 0x359, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) stmp = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) stmp = sign_extend32(stmp, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) utmp = clamp_val(-4 * stmp + 32767, 0x0000, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dev_dbg(&client->dev, "IF AGC=%d\n", stmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) c->strength.stat[0].scale = FE_SCALE_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) c->strength.stat[0].uvalue = utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (dev->fe_status & FE_HAS_VITERBI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned int hierarchy, constellation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #define CONSTELLATION_NUM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #define HIERARCHY_NUM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static const u32 constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {70705899, 70705899, 70705899, 70705899},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {82433173, 82433173, 87483115, 94445660},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {92888734, 92888734, 95487525, 99770748},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = rtl2830_bulk_read(client, 0x33c, &u8tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) constellation = (u8tmp >> 2) & 0x03; /* [3:2] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (constellation > CONSTELLATION_NUM - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) hierarchy = (u8tmp >> 4) & 0x07; /* [6:4] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (hierarchy > HIERARCHY_NUM - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = rtl2830_bulk_read(client, 0x40c, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) utmp = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (utmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) stmp = (constant[constellation][hierarchy] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) intlog10(utmp)) / ((1 << 24) / 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) stmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_dbg(&client->dev, "CNR raw=%u\n", utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) c->cnr.stat[0].svalue = stmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* BER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (dev->fe_status & FE_HAS_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ret = rtl2830_bulk_read(client, 0x34e, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) utmp = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) dev->post_bit_error += utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dev->post_bit_count += 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dev_dbg(&client->dev, "BER errors=%u total=1000000\n", utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) *snr = div_s64(c->cnr.stat[0].svalue, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) *ber = (dev->post_bit_error - dev->post_bit_error_prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) dev->post_bit_error_prev = dev->post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) *ucblocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (c->strength.stat[0].scale == FE_SCALE_RELATIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *strength = c->strength.stat[0].uvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) *strength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static const struct dvb_frontend_ops rtl2830_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .delsys = {SYS_DVBT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .name = "Realtek RTL2830 (DVB-T)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .caps = FE_CAN_FEC_1_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) FE_CAN_FEC_2_3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) FE_CAN_FEC_5_6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) FE_CAN_QAM_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) FE_CAN_QAM_64 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) FE_CAN_GUARD_INTERVAL_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) FE_CAN_HIERARCHY_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) FE_CAN_RECOVER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) FE_CAN_MUTE_TS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .init = rtl2830_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .sleep = rtl2830_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .get_tune_settings = rtl2830_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .set_frontend = rtl2830_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .get_frontend = rtl2830_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .read_status = rtl2830_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .read_snr = rtl2830_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .read_ber = rtl2830_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .read_ucblocks = rtl2830_read_ucblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .read_signal_strength = rtl2830_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static int rtl2830_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) u8 u8tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dev_dbg(&client->dev, "onoff=%d\n", onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* enable / disable PID filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) u8tmp = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) u8tmp = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = rtl2830_update_bits(client, 0x061, 0x80, u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int rtl2830_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u8 buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dev_dbg(&client->dev, "index=%d pid=%04x onoff=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) index, pid, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* skip invalid PIDs (0x2000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (pid > 0x1fff || index > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) set_bit(index, &dev->filters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) clear_bit(index, &dev->filters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* enable / disable PIDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) buf[0] = (dev->filters >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) buf[1] = (dev->filters >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) buf[2] = (dev->filters >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) buf[3] = (dev->filters >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ret = rtl2830_bulk_write(client, 0x062, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* add PID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) buf[0] = (pid >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) buf[1] = (pid >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ret = rtl2830_bulk_write(client, 0x066 + 2 * index, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * I2C gate/mux/repeater logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * We must use unlocked __i2c_transfer() here (through regmap) because of I2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * adapter lock is already taken by tuner driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * Gate is closed automatically after single I2C transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static int rtl2830_select(struct i2c_mux_core *muxc, u32 chan_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct i2c_client *client = i2c_mux_priv(muxc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* open I2C repeater for 1 transfer, closes automatically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* XXX: regmap_update_bits() does not lock I2C adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ret = regmap_update_bits(dev->regmap, 0x101, 0x08, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static struct dvb_frontend *rtl2830_get_dvb_frontend(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return &dev->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static struct i2c_adapter *rtl2830_get_i2c_adapter(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return dev->muxc->adapter[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * We implement own I2C access routines for regmap in order to get manual access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * to I2C adapter lock, which is needed for I2C mux adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int rtl2830_regmap_read(void *context, const void *reg_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) size_t reg_size, void *val_buf, size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct i2c_client *client = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct i2c_msg msg[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) .len = reg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) .buf = (u8 *)reg_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) .len = val_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) .buf = val_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) ret = __i2c_transfer(client->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (ret != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_warn(&client->dev, "i2c reg read failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static int rtl2830_regmap_write(void *context, const void *data, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct i2c_client *client = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct i2c_msg msg[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) .len = count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) .buf = (u8 *)data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ret = __i2c_transfer(client->adapter, msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dev_warn(&client->dev, "i2c reg write failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static int rtl2830_regmap_gather_write(void *context, const void *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) size_t reg_len, const void *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) size_t val_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct i2c_client *client = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) u8 buf[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct i2c_msg msg[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .len = 1 + val_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) buf[0] = *(u8 const *)reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) memcpy(&buf[1], val, val_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ret = __i2c_transfer(client->adapter, msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) dev_warn(&client->dev, "i2c reg write failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static int rtl2830_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct rtl2830_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct rtl2830_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) u8 u8tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static const struct regmap_bus regmap_bus = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .read = rtl2830_regmap_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) .write = rtl2830_regmap_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .gather_write = rtl2830_regmap_gather_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static const struct regmap_range_cfg regmap_range_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .selector_reg = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .selector_mask = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .selector_shift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .window_start = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .window_len = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .range_min = 0 * 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .range_max = 5 * 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static const struct regmap_config regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .max_register = 5 * 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .ranges = regmap_range_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .num_ranges = ARRAY_SIZE(regmap_range_cfg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* allocate memory for the internal state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* setup the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) i2c_set_clientdata(client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dev->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dev->pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev->sleeping = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev->regmap = regmap_init(&client->dev, ®map_bus, client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (IS_ERR(dev->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ret = PTR_ERR(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* check if the demod is there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = rtl2830_bulk_read(client, 0x000, &u8tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) goto err_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /* create muxed i2c adapter for tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) rtl2830_select, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!dev->muxc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) goto err_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) dev->muxc->priv = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) goto err_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* create dvb frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) memcpy(&dev->fe.ops, &rtl2830_ops, sizeof(dev->fe.ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dev->fe.demodulator_priv = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* setup callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) pdata->get_dvb_frontend = rtl2830_get_dvb_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) pdata->get_i2c_adapter = rtl2830_get_i2c_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) pdata->pid_filter = rtl2830_pid_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) pdata->pid_filter_ctrl = rtl2830_pid_filter_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dev_info(&client->dev, "Realtek RTL2830 successfully attached\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) err_regmap_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) regmap_exit(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static int rtl2830_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct rtl2830_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) i2c_mux_del_adapters(dev->muxc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) regmap_exit(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static const struct i2c_device_id rtl2830_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {"rtl2830", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) MODULE_DEVICE_TABLE(i2c, rtl2830_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static struct i2c_driver rtl2830_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .name = "rtl2830",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .probe = rtl2830_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .remove = rtl2830_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .id_table = rtl2830_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) module_i2c_driver(rtl2830_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) MODULE_LICENSE("GPL");