// SPDX-License-Identifier: GPL-2.0
/*
* Driver for the MaxLinear MxL69x family of combo tuners/demods
*
* Copyright (C) 2020 Brad Love <brad@nextdimension.cc>
*
* based on code:
* Copyright (c) 2016 MaxLinear, Inc. All rights reserved
* which was released under GPL V2
*/
#include <linux/mutex.h>
#include <linux/i2c-mux.h>
#include <linux/string.h>
#include <linux/firmware.h>
#include "mxl692.h"
#include "mxl692_defs.h"
static const struct dvb_frontend_ops mxl692_ops;
struct mxl692_dev {
struct dvb_frontend fe;
struct i2c_client *i2c_client;
struct mutex i2c_lock; /* i2c command mutex */
enum MXL_EAGLE_DEMOD_TYPE_E demod_type;
enum MXL_EAGLE_POWER_MODE_E power_mode;
u32 current_frequency;
int device_type;
int seqnum;
int init_done;
};
static int mxl692_i2c_write(struct mxl692_dev *dev, u8 *buffer, u16 buf_len)
{
int ret = 0;
struct i2c_msg msg = {
.addr = dev->i2c_client->addr,
.flags = 0,
.buf = buffer,
.len = buf_len
};
ret = i2c_transfer(dev->i2c_client->adapter, &msg, 1);
if (ret != 1)
dev_dbg(&dev->i2c_client->dev, "i2c write error!\n");
return ret;
}
static int mxl692_i2c_read(struct mxl692_dev *dev, u8 *buffer, u16 buf_len)
{
int ret = 0;
struct i2c_msg msg = {
.addr = dev->i2c_client->addr,
.flags = I2C_M_RD,
.buf = buffer,
.len = buf_len
};
ret = i2c_transfer(dev->i2c_client->adapter, &msg, 1);
if (ret != 1)
dev_dbg(&dev->i2c_client->dev, "i2c read error!\n");
return ret;
}
static int convert_endian(u32 size, u8 *d)
{
u32 i;
for (i = 0; i < (size & ~3); i += 4) {
d[i + 0] ^= d[i + 3];
d[i + 3] ^= d[i + 0];
d[i + 0] ^= d[i + 3];
d[i + 1