Files
linux/drivers/media/dvb-frontends/ix2505v.c
Linus Torvalds bf4afc53b7 Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
This was done entirely with mindless brute force, using

    git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
        xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'

to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.

Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.

For the same reason the 'flex' versions will be done as a separate
conversion.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21 17:09:51 -08:00

312 lines
7.1 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
*
* Copyright (C) 2010 Malcolm Priestley
*/
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "ix2505v.h"
static int ix2505v_debug;
#define dprintk(level, args...) do { \
if (ix2505v_debug & level) \
printk(KERN_DEBUG "ix2505v: " args); \
} while (0)
#define deb_info(args...) dprintk(0x01, args)
#define deb_i2c(args...) dprintk(0x02, args)
struct ix2505v_state {
struct i2c_adapter *i2c;
const struct ix2505v_config *config;
u32 frequency;
};
/*
* Data read format of the Sharp IX2505V B0017
*
* byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1
* byte2: POR | FL | RD2 | RD1 | RD0 | X | X | X
*
* byte1 = address
* byte2;
* POR = Power on Reset (VCC H=<2.2v L=>2.2v)
* FL = Phase Lock (H=lock L=unlock)
* RD0-2 = Reserved internal operations
*
* Only POR can be used to check the tuner is present
*
* Caution: after byte2 the I2C reverts to write mode continuing to read
* may corrupt tuning data.
*
*/
static int ix2505v_read_status_reg(struct ix2505v_state *state)
{
u8 addr = state->config->tuner_address;
u8 b2[] = {0};
int ret;
struct i2c_msg msg[1] = {
{ .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 }
};
ret = i2c_transfer(state->i2c, msg, 1);
deb_i2c("Read %s ", __func__);
return (ret == 1) ? (int) b2[0] : -1;
}
static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
{
struct i2c_msg msg[1] = {
{ .addr = state->config->tuner_address, .flags = 0,
.buf = buf, .len = count },
};
int ret;
ret = i2c_transfer(state->i2c, msg, 1);
if (ret != 1) {
deb_i2c("%s: i2c error, ret=%d\n", __func__, ret);
return -EIO;
}
return 0;
}
static void ix2505v_release(struct dvb_frontend *fe)
{
struct ix2505v_state *state = fe->tuner_priv;
fe->tuner_priv = NULL;
kfree(state);
}
/*
* Data write format of the Sharp IX2505V B0017
*
* byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0
* byte2: 0 | BG1 | BG2 | N8 | N7 | N6 | N5 | N4
* byte3: N3 | N2 | N1 | A5 | A4 | A3 | A2 | A1
* byte4: 1 | 1(C1) | 1(C0) | PD5 | PD4 | TM | 0(RTS)| 1(REF)
* byte5: BA2 | BA1 | BA0 | PSC | PD3 |PD2/TS2|DIV/TS1|PD0/TS0
*
* byte1 = address
*
* Write order
* 1) byte1 -> byte2 -> byte3 -> byte4 -> byte5
* 2) byte1 -> byte4 -> byte5 -> byte2 -> byte3
* 3) byte1 -> byte2 -> byte3 -> byte4
* 4) byte1 -> byte4 -> byte5 -> byte2
* 5) byte1 -> byte2 -> byte3
* 6) byte1 -> byte4 -> byte5
* 7) byte1 -> byte2
* 8) byte1 -> byte4
*
* Recommended Setup
* 1 -> 8 -> 6
*/
static int ix2505v_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct ix2505v_state *state = fe->tuner_priv;
u32 frequency = c->frequency;
u32 b_w = (c->symbol_rate * 27) / 32000;
u32 div_factor, N , A, x;
int ret = 0, len;
u8 gain, cc, ref, psc, local_osc, lpf;
u8 data[4] = {0};
if ((frequency < fe->ops.info.frequency_min_hz / kHz)
|| (frequency > fe->ops.info.frequency_max_hz / kHz))
return -EINVAL;
if (state->config->tuner_gain)
gain = (state->config->tuner_gain < 4)
? state->config->tuner_gain : 0;
else
gain = 0x0;
if (state->config->tuner_chargepump)
cc = state->config->tuner_chargepump;
else
cc = 0x3;
ref = 8; /* REF =1 */
psc = 32; /* PSC = 0 */
div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */
x = div_factor / psc;
N = x/100;
A = ((x - (N * 100)) * psc) / 100;
data[0] = ((gain & 0x3) << 5) | (N >> 3);
data[1] = (N << 5) | (A & 0x1f);
data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/
deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A);
if (frequency <= 1065000)
local_osc = (6 << 5) | 2;
else if (frequency <= 1170000)
local_osc = (7 << 5) | 2;
else if (frequency <= 1300000)
local_osc = (1 << 5);
else if (frequency <= 1445000)
local_osc = (2 << 5);
else if (frequency <= 1607000)
local_osc = (3 << 5);
else if (frequency <= 1778000)
local_osc = (4 << 5);
else if (frequency <= 1942000)
local_osc = (5 << 5);
else /*frequency up to 2150000*/
local_osc = (6 << 5);
data[3] = local_osc; /* all other bits set 0 */
if (b_w <= 10000)
lpf = 0xc;
else if (b_w <= 12000)
lpf = 0x2;
else if (b_w <= 14000)
lpf = 0xa;
else if (b_w <= 16000)
lpf = 0x6;
else if (b_w <= 18000)
lpf = 0xe;
else if (b_w <= 20000)
lpf = 0x1;
else if (b_w <= 22000)
lpf = 0x9;
else if (b_w <= 24000)
lpf = 0x5;
else if (b_w <= 26000)
lpf = 0xd;
else if (b_w <= 28000)
lpf = 0x3;
else
lpf = 0xb;
deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf);
deb_info("Data 0=[%4phN]\n", data);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
len = sizeof(data);
ret |= ix2505v_write(state, data, len);
data[2] |= 0x4; /* set TM = 1 other bits same */
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
len = 1;
ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
msleep(10);
data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */
data[3] |= (lpf & 0x3) << 2;
deb_info("Data 2=[%x%x]\n", data[2], data[3]);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
len = 2;
ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
if (state->config->min_delay_ms)
msleep(state->config->min_delay_ms);
state->frequency = frequency;
return ret;
}
static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct ix2505v_state *state = fe->tuner_priv;
*frequency = state->frequency;
return 0;
}
static const struct dvb_tuner_ops ix2505v_tuner_ops = {
.info = {
.name = "Sharp IX2505V (B0017)",
.frequency_min_hz = 950 * MHz,
.frequency_max_hz = 2175 * MHz
},
.release = ix2505v_release,
.set_params = ix2505v_set_params,
.get_frequency = ix2505v_get_frequency,
};
struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
const struct ix2505v_config *config,
struct i2c_adapter *i2c)
{
struct ix2505v_state *state = NULL;
int ret;
if (NULL == config) {
deb_i2c("%s: no config ", __func__);
goto error;
}
state = kzalloc_obj(struct ix2505v_state);
if (NULL == state)
return NULL;
state->config = config;
state->i2c = i2c;
if (state->config->tuner_write_only) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
ret = ix2505v_read_status_reg(state);
if (ret & 0x80) {
deb_i2c("%s: No IX2505V found\n", __func__);
goto error;
}
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
fe->tuner_priv = state;
memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops,
sizeof(struct dvb_tuner_ops));
deb_i2c("%s: initialization (%s addr=0x%02x) ok\n",
__func__, fe->ops.tuner_ops.info.name, config->tuner_address);
return fe;
error:
kfree(state);
return NULL;
}
EXPORT_SYMBOL_GPL(ix2505v_attach);
module_param_named(debug, ix2505v_debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
MODULE_DESCRIPTION("DVB IX2505V tuner driver");
MODULE_AUTHOR("Malcolm Priestley");
MODULE_LICENSE("GPL");