// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Afatech AF9033 demodulator driver
*
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
* Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
*/
#include "af9033_priv.h"
struct af9033_dev {
struct i2c_client *client;
struct regmap *regmap;
struct dvb_frontend fe;
struct af9033_config cfg;
bool is_af9035;
bool is_it9135;
u32 bandwidth_hz;
bool ts_mode_parallel;
bool ts_mode_serial;
enum fe_status fe_status;
u64 post_bit_error_prev; /* for old read_ber we return (curr - prev) */
u64 post_bit_error;
u64 post_bit_count;
u64 error_block_count;
u64 total_block_count;
};
/* Write reg val table using reg addr auto increment */
static int af9033_wr_reg_val_tab(struct af9033_dev *dev,
const struct reg_val *tab, int tab_len)
{
struct i2c_client *client = dev->client;
#define MAX_TAB_LEN 212
int ret, i, j;
u8 buf[1 + MAX_TAB_LEN];
dev_dbg(&client->dev, "tab_len=%d\n", tab_len);
if (tab_len > sizeof(buf)) {
dev_warn(&client->dev, "tab len %d is too big\n", tab_len);
return -EINVAL;
}
for (i = 0, j = 0; i < tab_len; i++) {
buf[j] = tab[i].val;
if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
ret = regmap_bulk_write(dev->regmap, tab[i].reg - j,
buf, j + 1);
if (ret)
goto err;
j = 0;
} else {
j++;
}
}
return 0;
err:
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
}
static int af9033_init(struct dvb_frontend *fe)
{
struct af9033_dev *dev = fe->demodulator_priv;
struct i2c_client *client = dev->client;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i, len;
unsigned int utmp;
const struct reg_val *init;
u8 buf[4];
struct reg_val_mask tab[] = {
{ 0x80fb24, 0x00, 0x08 },
{ 0x80004c, 0x00, 0xff },
{ 0x00f641, dev->cfg.tuner, 0xff },
{ 0x80f5ca, 0x01, 0x01 },
{ 0x80f715, 0x01, 0x01 },
{ 0x00f41f, 0x04, 0x04 },
{ 0x00f41a, 0x01, 0x01 },
{ 0x80f731, 0x00, 0x01 },
{ 0x00d91e, 0x00, 0x01 },
{ 0x00d919, 0x00, 0x01 },
{ 0x80f732, 0x00, 0x01 },
{ 0x00d91f, 0x00, 0x01 },
{ 0x00d91a, 0x00, 0x01 },
{ 0x80f730, 0x00, 0x01 },
{ 0x80f778, 0x00, 0xff },
{ 0x80f73c, 0x01, 0x01 },
{ 0x80f776, 0x00, 0x01 },
{ 0x00d8fd, 0x01, 0xff },
{ 0x00d830, 0x01, 0xff },
{ 0x00d831, 0x00, 0xff },
{ 0x00d832, 0x00, 0xff },
{ 0x80f985, dev->ts_mode_serial, 0x01 },
{ 0x80f986, dev->ts_mode_parallel, 0x01 },
{ 0x00d827, 0x00, 0xff },
{ 0x00d829, 0x00, 0xff },
{ 0x800045, dev->cfg.adc_multiplier, 0xff },
};
dev_dbg(&client->dev, "\n");
/* Main clk control */