162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci	Mantis PCI bridge driver
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci*/
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <linux/i2c.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/signal.h>
1362306a36Sopenharmony_ci#include <linux/sched.h>
1462306a36Sopenharmony_ci#include <linux/interrupt.h>
1562306a36Sopenharmony_ci#include <asm/io.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <media/dmxdev.h>
1862306a36Sopenharmony_ci#include <media/dvbdev.h>
1962306a36Sopenharmony_ci#include <media/dvb_demux.h>
2062306a36Sopenharmony_ci#include <media/dvb_frontend.h>
2162306a36Sopenharmony_ci#include <media/dvb_net.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include "mantis_common.h"
2462306a36Sopenharmony_ci#include "mantis_reg.h"
2562306a36Sopenharmony_ci#include "mantis_ioc.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	struct i2c_adapter *adapter = &mantis->adapter;
3062306a36Sopenharmony_ci	int err;
3162306a36Sopenharmony_ci	u8 buf = reg;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	struct i2c_msg msg[] = {
3462306a36Sopenharmony_ci		{ .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
3562306a36Sopenharmony_ci		{ .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
3662306a36Sopenharmony_ci	};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	err = i2c_transfer(adapter, msg, 2);
3962306a36Sopenharmony_ci	if (err < 0) {
4062306a36Sopenharmony_ci		dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
4162306a36Sopenharmony_ci			err, data[0], data[1]);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci		return err;
4462306a36Sopenharmony_ci	}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	return 0;
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ciint mantis_get_mac(struct mantis_pci *mantis)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	int err;
5162306a36Sopenharmony_ci	u8 mac_addr[6] = {0};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
5462306a36Sopenharmony_ci	if (err < 0) {
5562306a36Sopenharmony_ci		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci		return err;
5862306a36Sopenharmony_ci	}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	dprintk(MANTIS_ERROR, 0, "    MAC Address=[%pM]\n", mac_addr);
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	return 0;
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mantis_get_mac);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* Turn the given bit on or off. */
6762306a36Sopenharmony_civoid mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	u32 cur;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
7262306a36Sopenharmony_ci	cur = mmread(MANTIS_GPIF_ADDR);
7362306a36Sopenharmony_ci	if (value)
7462306a36Sopenharmony_ci		mantis->gpio_status = cur | (1 << bitpos);
7562306a36Sopenharmony_ci	else
7662306a36Sopenharmony_ci		mantis->gpio_status = cur & (~(1 << bitpos));
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
7962306a36Sopenharmony_ci	mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
8062306a36Sopenharmony_ci	mmwrite(0x00, MANTIS_GPIF_DOUT);
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mantis_gpio_set_bits);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciint mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	u32 reg;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	reg = mmread(MANTIS_CONTROL);
8962306a36Sopenharmony_ci	switch (stream_ctl) {
9062306a36Sopenharmony_ci	case STREAM_TO_HIF:
9162306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Set stream to HIF");
9262306a36Sopenharmony_ci		reg &= 0xff - MANTIS_BYPASS;
9362306a36Sopenharmony_ci		mmwrite(reg, MANTIS_CONTROL);
9462306a36Sopenharmony_ci		reg |= MANTIS_BYPASS;
9562306a36Sopenharmony_ci		mmwrite(reg, MANTIS_CONTROL);
9662306a36Sopenharmony_ci		break;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	case STREAM_TO_CAM:
9962306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Set stream to CAM");
10062306a36Sopenharmony_ci		reg |= MANTIS_BYPASS;
10162306a36Sopenharmony_ci		mmwrite(reg, MANTIS_CONTROL);
10262306a36Sopenharmony_ci		reg &= 0xff - MANTIS_BYPASS;
10362306a36Sopenharmony_ci		mmwrite(reg, MANTIS_CONTROL);
10462306a36Sopenharmony_ci		break;
10562306a36Sopenharmony_ci	default:
10662306a36Sopenharmony_ci		dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl);
10762306a36Sopenharmony_ci		return -1;
10862306a36Sopenharmony_ci	}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	return 0;
11162306a36Sopenharmony_ci}
11262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mantis_stream_control);
113