Jump to content


Photo

Broadcom drivers


  • Please log in to reply
15 replies to this topic

#1 redblue

  • Member
  • 7 posts

0
Neutral

Posted 3 December 2020 - 06:01

Maybe someone would be willing to take a closer look at these drivers? https://github.com/m....broadcom.refsw So far, I wrote a primitive pilot service for fun :)

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <media/rc-core.h>

#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>

#include <asm/io.h>
#include <linux/io.h>

#include "rc.h"

#include <linux/ktime.h>
#include <linux/delay.h>

#define MODULE_NAME "bcmrc"

#define BASE_REG_ADDR 0x08000000

/* com0 (ttyS0) registers */
#define UARTA_REG_START	0x0040c000
#define UARTA_REG_END	0x0040c01c
#define UARTA_IRQ 128

/* com1 (ttyS1) registers */
#define UARTB_REG_START	0x0040d000
#define UARTB_REG_END	0x0040d01c
#define UARTB_IRQ 129

/* com2 (ttyS2) registers */
#define UARTC_REG_START	0x0040e000
#define UARTC_REG_END	0x0040e01c
#define UARTC_IRQ 130

#define UART_ADDRSIZE 0x1000

enum {
	COM0 = 0,
	COM1 = 1,
	COM2 = 2,
};

#define COM_PORT COM2
#define COM_ADDRSIZE UART_ADDRSIZE
#define COM_IRQ UARTC_IRQ

#define bcmrc_debug(fmt, arg...) printk(KERN_DEBUG "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_info(fmt, arg...) printk(KERN_INFO "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_error(fmt, arg...) printk(KERN_ERR "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_warning(fmt, arg...) printk(KERN_WARNING "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_alert(fmt, arg...) printk(KERN_ALERT "%s: %s " fmt, MODULE_NAME, __func__, ##arg)

static const unsigned short vuduo4k_remote_key_table[] = {
	KEY_POWER,
	KEY_TEXT,
	KEY_SUBTITLE,
	KEY_HELP,
	KEY_0,
	KEY_1,
	KEY_2,
	KEY_3,
	KEY_4,
	KEY_5,
	KEY_6,
	KEY_7,
	KEY_8,
	KEY_9,
	KEY_PREVIOUS,
	KEY_NEXT,
	KEY_RED,
	KEY_GREEN,
	KEY_YELLOW,
	KEY_BLUE,
	KEY_VIDEO,
	KEY_MENU,
	KEY_EXIT,
	KEY_INFO,
	KEY_OK,
	KEY_UP,
	KEY_DOWN,
	KEY_RIGHT,
	KEY_LEFT,
	KEY_VOLUMEUP,
	KEY_VOLUMEDOWN,
	KEY_CHANNELUP,
	KEY_CHANNELDOWN,
	KEY_AUDIO,
	KEY_MUTE,
	KEY_EDIT,
	KEY_REWIND,
	KEY_PLAY,
	KEY_PLAYPAUSE,
	KEY_FASTFORWARD,
	KEY_TV,
	KEY_RECORD,
	KEY_STOP,
	KEY_RADIO,
};

struct bcmrc_par {
	struct input_dev *input;
	struct uart_8250_port uart;
	void __iomem *iomem_base;
	spinlock_t hardware_lock;
	int i;
	unsigned char buffer[16];
	int irq;
	unsigned short keymap[ARRAY_SIZE(vuduo4k_remote_key_table)];
};

static struct bcmrc_par bcmrc;

static unsigned int get_com_membase_reg(int com_nr)
{
	unsigned int result;
	switch (com_nr) {
		case COM0:
			result = UARTA_REG_START + BASE_REG_ADDR;
			break;
		case COM1:
			result = UARTB_REG_START + BASE_REG_ADDR;
			break;
		case COM2:
			result = UARTC_REG_START + BASE_REG_ADDR;
			break;
	}
	return result;
}

static unsigned int get_com_irq(int com_nr)
{
	unsigned int result;
	switch (com_nr) {
		case COM0:
			result = UARTA_IRQ;
			break;
		case COM1:
			result = UARTB_IRQ;
			break;
		case COM2:
			result = UARTC_IRQ;
			break;
	}
	return result;
}

static inline unsigned int serial_in(struct uart_8250_port *up, unsigned int offset)
{
	unsigned int result;
	offset = offset << up->port.regshift;

	switch (up->port.iotype) {
		case UPIO_HUB6:
			outb(up->port.hub6 - 1 + offset, up->port.iobase);
			result = inb(up->port.iobase + 1);
			//bcmrc_info("UPIO_HUB6, iobase 0x%.4x, offset: 0x%.4x, result: %d\n", up->port.iobase, offset, result);
			break;

		case UPIO_MEM:
			result = readb(up->port.membase + offset);
			//bcmrc_info("UPIO_MEM, membase 0x%.4x, offset: 0x%.4x, reg: 0x%.4x, result: %d\n", up->port.membase, offset, up->port.membase + offset, result);
			break;

		case UPIO_MEM32:
			result = readl(up->port.membase + offset);
			//bcmrc_info("UPIO_MEM32, membase 0x%.4x, offset: 0x%.4x, result: %d\n", up->port.membase, offset, result);
			break;

		default:
			//return ioread32(up->port.membase + offset);
			result = inb(up->port.iobase + offset);
			//bcmrc_info("default, membase 0x%.4x, offset: 0x%.4x, result: %d\n", up->port.iobase, offset, result);
			break;
	}
	return result;
}

static inline void serial_out(struct uart_8250_port *up, unsigned int offset, unsigned int value)
{
	offset = offset << up->port.regshift;

	switch (up->port.iotype) {
		case UPIO_HUB6:
			//bcmrc_info("UPIO_HUB6, iobase 0x%.4x, offset: 0x%.4x, value: %d\n", up->port.iobase, offset, value);
			outb(up->port.hub6 - 1 + offset, up->port.iobase);
			outb(value, up->port.iobase + 1);
			break;

		case UPIO_MEM:
			//bcmrc_info("UPIO_MEM, membase 0x%.4x, offset: 0x%.4x, reg: 0x%.4x, value: %d\n", up->port.membase, offset, up->port.membase + offset, value);
			writeb(value, up->port.membase + offset);
			break;

		case UPIO_MEM32:
			//bcmrc_info("UPIO_MEM32, membase 0x%.4x, offset: 0x%.4x, value: %d\n", up->port.membase, offset, value);
			writel(value, up->port.membase + offset);
			break;

		default:
			//bcmrc_info("default, membase 0x%.4x, offset: 0x%.4x, value %d\n", up->port.iobase, offset, value);
			//iowrite32(value, up->port.membase + offset);
			outb(value, up->port.iobase + offset);
			break;
	}
}

static int bcmrc_open(struct input_dev *dev)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned long flags;
#if 0
	/* initialize timestamp */
	//par->lastkt = ktime_get();

	spin_lock_irqsave(&par->hardware_lock, flags);

	/* Set DLAB 0. */
	serial_out(&par->uart, UART_LCR, serial_in(&par->uart, (UART_LCR) & (~UART_LCR_DLAB)));

	serial_out(&par->uart, UART_IER, serial_in(&par->uart, (UART_IER) | UART_IER_MSI));

	spin_unlock_irqrestore(&par->hardware_lock, flags);
#endif
	return 0;
}

static void bcmrc_close(struct input_dev *dev)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned long flags;
#if 0
	spin_lock_irqsave(&par->hardware_lock, flags);

	/* Set DLAB 0. */
	serial_out(&par->uart, UART_LCR, serial_in(&par->uart, (UART_LCR) & (~UART_LCR_DLAB)));

	/* First of all, disable all interrupts */
	serial_out(&par->uart, UART_IER, serial_in(&par->uart, (UART_IER) & (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))));

	spin_unlock_irqrestore(&par->hardware_lock, flags);
#endif
}

static long bcmrc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	struct bcmrc_par *par = (struct bcmrc_par*) filep->private_data;
	int result;

	switch (cmd) {

	}

	return result;
}

static int bcmrc_frontpanel_key_mapping(struct input_dev *dev, unsigned int key)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned int result;

	switch (key) {
		case 0x01:
			result = KEY_POWER;
			break;
		case 0x02:
			result = KEY_VOLUMEUP;
			break;
		case 0x04:
			result = KEY_VOLUMEDOWN;
			break;
		case 0x08:
			result = KEY_CHANNELUP;
			break;
		case 0x80:
			result = KEY_CHANNELDOWN;
			break;
		default:
			bcmrc_info("Unhandled key: 0x%.2x\n", key);
			result = 0;
			break;
	}
	return result;
}

static int bcmrc_remote_key_mapping(struct input_dev *dev, unsigned int key)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned int result;

	switch (key) {
		case 0x0c:
			result = KEY_POWER;
			break;
		case 0x3c:
			result = KEY_TEXT;
			break;
		case 0x4b:
			result = KEY_SUBTITLE;
			break;
		case 0x81:
			result = KEY_HELP;
			break;
		case 0x00:
			result = KEY_0;
			break;
		case 0x01:
			result = KEY_1;
			break;
		case 0x02:
			result = KEY_2;
			break;
		case 0x03:
			result = KEY_3;
			break;
		case 0x04:
			result = KEY_4;
			break;
		case 0x05:
			result = KEY_5;
			break;
		case 0x06:
			result = KEY_6;
			break;
		case 0x07:
			result = KEY_7;
			break;
		case 0x08:
			result = KEY_8;
			break;
		case 0x09:
			result = KEY_9;
			break;
		case 0xbb:
			result = KEY_PREVIOUS;
			break;
		case 0xbc:
			result = KEY_NEXT;
			break;
		case 0x6d:
			result = KEY_RED;
			break;
		case 0x6e:
			result = KEY_GREEN;
			break;
		case 0x6f:
			result = KEY_YELLOW;
			break;
		case 0x70:
			result = KEY_BLUE;
			break;
		case 0x49:
			result = KEY_VIDEO;
			break;
		case 0x54:
			result = KEY_MENU;
			break;
		case 0xcc:
			result = KEY_EXIT;
			break;
		case 0x55:
			result = KEY_INFO;
			break;
		case 0x5c:
			result = KEY_OK;
			break;
		case 0x58:
			result = KEY_UP;
			break;
		case 0x59:
			result = KEY_DOWN;
			break;
		case 0x5b:
			result = KEY_RIGHT;
			break;
		case 0x5a:
			result = KEY_LEFT;
			break;
		case 0x10:
			result = KEY_VOLUMEUP;
			break;
		case 0x11:
			result = KEY_VOLUMEDOWN;
			break;
		case 0x20:
			result = KEY_CHANNELUP;
			break;
		case 0x21:
			result = KEY_CHANNELDOWN;
			break;
		case 0xe5:
			result = KEY_AUDIO;
			break;
		case 0x0d:
			result = KEY_MUTE;
			break;
		case 0xe6:
			result = KEY_EDIT;
			break;
		case 0x29:
			result = KEY_REWIND;
			break;
		case 0x2c:
			result = KEY_PLAY;
			break;
		case 0x30:
			result = KEY_PLAYPAUSE;
			break;
		case 0x28:
			result = KEY_FASTFORWARD;
			break;
		case 0xe4:
			result = KEY_TV;
			break;
		case 0x37:
			result = KEY_RECORD;
			break;
		case 0x31:
			result = KEY_STOP;
			break;
		case 0xf2:
			result = KEY_RADIO;
			break;
		default:
			bcmrc_info("Unhandled key: 0x%.2x\n", key);
			result = 0;
			break;
	}
	return result;
}

static irqreturn_t bcmrc_irq_handler(int irq, void *dev_id)
{
	struct bcmrc_par *par = (struct bcmrc_par *)dev_id;
	struct input_dev *input = par->input;
	unsigned long flags;
	unsigned int iir, lsr, i = 0;
	int counter = 0, max_count = 8;

	while ((iir = serial_in(&par->uart, UART_IIR & UART_IIR_ID))) {
		if (++counter > 256) {
			//bcmrc_error("Trapped in interrupt, counter %d\n", counter);
			break;
		}

		switch (iir & UART_IIR_ID) {
			case UART_IIR_MSI:
				(void) serial_in(&par->uart, UART_MSR);
				break;
			case UART_IIR_RLSI:
			case UART_IIR_THRI:
				(void) serial_in(&par->uart, UART_LSR);
				break;
			case UART_IIR_RDI:
				spin_lock_irqsave(&par->hardware_lock, flags);
				do {
					par->buffer[par->i++] = serial_in(&par->uart, UART_RX);
					if (par->i == 7) {
						//bcmrc_info("first packet 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x\n", par->buffer[0], par->buffer[1], par->buffer[2], par->buffer[3], par->buffer[4], par->buffer[5], par->buffer[6], par->buffer[7]);
						if (par->buffer[0] == 0xd1)
							input_report_key(par->input, bcmrc_frontpanel_key_mapping(par->input, par->buffer[1]), 1);
						else if (par->buffer[0] == 0xd2)
							input_report_key(par->input, bcmrc_remote_key_mapping(par->input, par->buffer[1]), 1);
						input_sync(par->input);
					}
					if (par->i == 15) {
						//bcmrc_info("second packet 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x\n", par->buffer[8], par->buffer[9], par->buffer[10], par->buffer[11], par->buffer[12], par->buffer[13], par->buffer[14], par->buffer[15]);
						if (par->buffer[0] == 0xd1)
							input_report_key(par->input, bcmrc_frontpanel_key_mapping(par->input, par->buffer[1]), 0);
						else if (par->buffer[0] == 0xd2)
							input_report_key(par->input, bcmrc_remote_key_mapping(par->input, par->buffer[1]), 0);
						input_sync(par->input);
						par->i = 0;
					}
					lsr = serial_in(&par->uart, UART_LSR);
				} while (lsr & UART_LSR_DR);
				spin_unlock_irqrestore(&par->hardware_lock, flags);
				break;
			default:
				break;
		}
	}

	return IRQ_RETVAL(1);
}

int init_bcmrcdev(void)
{
	int result, i;
	struct bcmrc_par *par;
	struct input_dev *input_dev;
	struct uart_8250_port uart;

	unsigned long flags;

	par = kzalloc(sizeof(struct bcmrc_par), GFP_KERNEL);
	if (!par) {
		bcmrc_error("Error allocate primary structure!");
		return -ENOMEM;
		goto err_free_mem;
	}

	par->uart = uart;

	par->irq = get_com_irq(COM2);

	par->iomem_base = ioremap(get_com_membase_reg(COM2), COM_ADDRSIZE);
	if (!par->iomem_base) {
		bcmrc_error("Error remap memory!");
		goto err_iounmap;
	}

	result = request_threaded_irq(par->irq, bcmrc_irq_handler, 0, 0, "serial", par);
	if (result < 0) {
		if (result == -EBUSY)
			bcmrc_error("IRQ %d busy\n", par->irq);
		else if (result == -EINVAL)
			bcmrc_error("Bad irq number\n");
		return -EBUSY;
		goto err_free_input;
	}

	memset(&par->uart, 0, sizeof(par->uart));

	par->uart.port.type = PORT_16550A;
	par->uart.port.irq = par->irq;
	par->uart.port.uartclk = 5062500; /* 3686400 */
	par->uart.port.flags = UPF_SHARE_IRQ;
	par->uart.port.iotype = UPIO_MEM;
	par->uart.port.membase = par->iomem_base;
	par->uart.port.regshift = 2;

	spin_lock_irqsave(&par->hardware_lock, flags);

	serial_out(&par->uart, UART_IER, 0);

	/* Set DLAB 0. */
	serial_out(&par->uart, UART_LCR, serial_in(&par->uart, (UART_LCR) & (~UART_LCR_DLAB)));

	/* First of all, disable all interrupts */
	serial_out(&par->uart, UART_IER, serial_in(&par->uart, (UART_IER) & (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))));

	/* Clear registers. */
	serial_in(&par->uart, UART_LSR);
	serial_in(&par->uart, UART_RX);
	serial_in(&par->uart, UART_IIR);
	serial_in(&par->uart, UART_MSR);

	serial_out(&par->uart, UART_IER, 1);

	/* Clear registers again to be sure. */
	serial_in(&par->uart, UART_LSR);
	serial_in(&par->uart, UART_RX);
	serial_in(&par->uart, UART_IIR);
	serial_in(&par->uart, UART_MSR);

	spin_unlock_irqrestore(&par->hardware_lock, flags);

	input_dev = input_allocate_device();
	if (!input_dev) {
		bcmrc_error("Error alocate input device structure!");
		return -ENOMEM;
		goto err_free_input;
	}

	memcpy(par->keymap, vuduo4k_remote_key_table, sizeof(par->keymap));

	input_dev->keycode = par->keymap;
	input_dev->keycodesize = sizeof(unsigned short);
	input_dev->keycodemax = ARRAY_SIZE(par->keymap);

	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
	__set_bit(EV_KEY, input_dev->evbit);
	for (i = 0; i < ARRAY_SIZE(vuduo4k_remote_key_table); i++)
		__set_bit(vuduo4k_remote_key_table[i], input_dev->keybit);
	__clear_bit(KEY_RESERVED, input_dev->keybit);

	input_dev->name = "dreambox advanced remote control (native)";
	input_dev->phys = "event0";

	input_dev->id.bustype = BUS_HOST;

	input_dev->open = bcmrc_open;
	input_dev->close = bcmrc_close;

	par->input = input_dev;

	input_set_drvdata(par->input, par);

	result = input_register_device(par->input);
	if (result) {
		return -1;
	}

	return 0;

err_free_input:
	input_free_device(input_dev);
err_iounmap:
	iounmap(par->iomem_base);
err_free_mem_region:
	release_mem_region(get_com_membase_reg(COM2), COM_ADDRSIZE);
err_free_mem:
	input_free_device(input_dev);
	kfree(par);
	return result;
}

void exit_bcmrcdev(void)
{
	struct input_dev *input_dev;
	input_unregister_device(input_dev);
	input_free_device(input_dev);
}

 



Re: Broadcom drivers #2 Erik Slagter

  • PLi® Core member
  • 46,951 posts

+541
Excellent

Posted 4 December 2020 - 13:09

What is it and why should we care?

 

It would be interesting if it were the broadcom DVB drivers, but it's definitely not (and very improbably too).


Edited by Erik Slagter, 4 December 2020 - 20:31.

* Wavefrontier T90 with 28E/23E/19E/13E via SCR switches 2 x 2 x 6 user bands
I don't read PM -> if you have something to ask or to report, do it in the forum so others can benefit. I don't take freelance jobs.
Ik lees geen PM -> als je iets te vragen of te melden hebt, doe het op het forum, zodat anderen er ook wat aan hebben.


Re: Broadcom drivers #3 Pr2

  • PLi® Contributor
  • 6,046 posts

+256
Excellent

Posted 4 December 2020 - 18:41

Looks old an inactive anyway.


NO SUPPORT by PM, it is a forum make your question public so everybody can benefit from the question/answer.
If you think that my answer helps you, you can press the up arrow in bottom right of the answer.

Wanna help with OpenPLi Translation? Please read our Wiki Information for translators

Sat: Hotbird 13.0E, Astra 19.2E, Eutelsat5A 5.0W
VU+ Solo 4K: 2*DVB-S2 + 2*DVB-C/T/T2 (used in DVB-C) & Duo 4K: 2*DVB-S2X + DVB-C (FBC)

AB-Com: PULSe 4K 1*DVB-S2X (+ DVB-C/T/T2)
Edision OS Mio 4K: 1*DVB-S2X + 1*DVB-C/T/T2
 


Re: Broadcom drivers #4 redblue

  • Member
  • 7 posts

0
Neutral

Posted 5 December 2020 - 03:45

Broadcom DVBS2 drivers:

https://github.com/m...b/src/leapsatfe

Broadcom C/T drivers:

https://github.com/m...ab/src/leapctfe

Log1:

[46807.829256] nexus: module license 'Proprietary' taints kernel.
[46807.829266] Disabling lock debugging due to kernel taint
[46807.859858] nexus driver initialized
[46807.884443] wakeup_drv: Initializing wakeup driver
[46807.884667] wakeup_drv: Initialization complete
[46812.030517] usb 1-2.4: USB disconnect, device number 4
[46812.136536] usb 1-2.3: USB disconnect, device number 5
[46817.029453] DVB: registering new adapter (_vuplus_duo4k_)
[46817.030242] (NULL device *): DVB: registering adapter 0 frontend 0 (Vuplus FE)...
[46817.035843] DVB: registering new adapter (_vuplus_duo4k_)
[46817.036799] (NULL device *): DVB: registering adapter 1 frontend 0 (Vuplus FE)...
[46817.037265] DVB: registering new adapter (_vuplus_duo4k_)
[46817.038542] (NULL device *): DVB: registering adapter 2 frontend 0 (Vuplus FE)...
[46817.039755] DVB: registering new adapter (_vuplus_duo4k_)
[46817.041612] (NULL device *): DVB: registering adapter 3 frontend 0 (Vuplus FE)...
[46817.042065] DVB: registering new adapter (_vuplus_duo4k_)
[46817.042818] (NULL device *): DVB: registering adapter 4 frontend 0 (Vuplus FE)...
[46817.043259] DVB: registering new adapter (_vuplus_duo4k_)
[46817.044195] (NULL device *): DVB: registering adapter 5 frontend 0 (Vuplus FE)...
[46817.046309] DVB: registering new adapter (_vuplus_duo4k_)
[46817.047272] (NULL device *): DVB: registering adapter 6 frontend 0 (Vuplus FE)...
[46817.048103] DVB: registering new adapter (_vuplus_duo4k_)
[46817.048910] (NULL device *): DVB: registering adapter 7 frontend 0 (Vuplus FE)...
[46817.049463] Nexus doesn't support full LinuxDVB DMX section filter size. Restrict filters to 16 bytesnexus fe dvbs module loaded 8 adaptersUsing preferred video format: 31
[46817.049680] Overriding preferred video format: 31 -> 36
[46817.251940] bcmfb:bcmfb_open framebuffer 0, width 1280, height 720, virtual width 1280, virtual height 720, screen base 12101000, screen size 3686400, line lenght 5120, mem len 3686400, buffer size 3686400
[46817.252091] Console: switching 
[46817.252094] to colour frame buffer device 160x45
[46817.253094] fb0: imageblit
[46817.254145] fb0: imageblit
[46817.255177] fb0: imageblit
[46817.256167] fb0: imageblit
[46817.257151] fb0: imageblit
[46817.258138] fb0: imageblit
[46817.259110] fb0: imageblit
[46817.260066] fb0: imageblit
[46817.261068] fb0: imageblit
[46817.262098] fb0: imageblit
[46817.263072] fb0: imageblit
[46817.264034] fb0: imageblit
[46817.264994] fb0: imageblit
[46817.265950] fb0: imageblit
[46817.266910] fb0: imageblit
[46817.267868] fb0: imageblit
[46817.268826] fb0: imageblit
[46817.269787] fb0: imageblit
[46817.270762] fb0: imageblit
[46817.271714] fb0: imageblit
[46817.272670] fb0: imageblit
[46817.273633] fb0: imageblit
[46817.274590] fb0: imageblit
[46817.275551] fb0: imageblit
[46817.276510] fb0: imageblit
[46817.277470] fb0: imageblit
[46817.278441] fb0: imageblit
[46817.279396] fb0: imageblit
[46817.280356] fb0: imageblit
[46817.281308] fb0: imageblit
[46817.282270] fb0: imageblit
[46817.283223] fb0: imageblit
[46817.284182] fb0: imageblit
[46817.285141] fb0: imageblit
[46817.286118] fb0: imageblit
[46817.287074] fb0: imageblit
[46817.288030] fb0: imageblit
[46817.288986] fb0: imageblit
[46817.289938] fb0: imageblit
[46817.290899] fb0: imageblit
[46817.291850] fb0: imageblit
[46817.292810] fb0: imageblit
[46817.293786] fb0: imageblit
[46817.294743] fb0: imageblit
[46817.295697] fb0: imageblit
[46817.296657] fb0: imageblit
[46817.296726] fb0: bcmfb framebuffer device
[46817.296992] input: dreambox advanced remote control (native) as /devices/virtual/input/input0

Log2:

### 00:00:00.142 nexus_platform_cma: MEMC0 BMEM 618MBytes(648019968) at 0x059400000 intersects with lowmem 625MBytes(655360000) at 0x040000000
    00:00:00.142 nexus_platform_cma: reserved region:2 MEMC0 'BFW' 0x047000000...0x047040000
    00:00:00.142 nexus_platform_cma: reserved region:5 MEMC1 'MON' 0x0fff00000...0x100000000
    00:00:00.142 nexus_platform_cma: current Linux boot parameters: 'bmem=618m@1428m bmem=795m@3300m'
    00:00:00.061 nexus_environment: proxy: B_REFSW_BOXMODE='1', SAGEBIN_PATH='/usr/bin'
    00:00:00.164 nexus_platform_os: virtual irq: enabled (271)
*** 00:00:00.164 nexus_platform_os: virtual l2 enabled
    00:00:00.164 nexus_platform_os: shared gpio banks: enabled
*** 00:00:00.164 nexus_platform_os: shared gpio enabled
*** 00:00:00.172 BCHP_PWR: BCHP_PWR POWER MANAGEMENT ENABLED
    00:00:00.174 BCHP_PWR: skipping initial reset to extend splash across SAGE boot
*** 00:00:00.176 nexus_platform: 97278 B1 18.2, boxmode 1, pmap 2, product 7278 B1
    00:00:00.176 nexus_platform: NEXUS_SCM_ID_STRING:UNKNOWN
    00:00:00.176 nexus_environment: B_REFSW_BOXMODE='1', SAGEBIN_PATH='/usr/bin'
    00:00:00.176 nexus_platform_97278: Initializing HB platform in 32 bit compatibility mode using v7-32 global address map.
*** 00:00:00.177 nexus_platform_pinmux: DVB_CI and 656 out share the same pinmux control registers 14 and 15. 656 output will be blocked.
    00:00:00.177 BHSM: KeySlot types: IvPerSlot128[21+3] IvPerBlock128[21] IvPerBlock256[11] IvPerEntry256[11]
    00:00:00.177 BHSMa: SECURITY VERSION: Zeus[5.1.0] BFW[2.1.3] 
    00:00:00.188 nexus_security: CHIPID: XXXXXXXXXXXXXXXXX
    00:00:00.191 BSAGElib: BSAGElib_P_GetChipsetType - Chip Type: ZB
    00:00:00.450 BSAGElib_boot_4x: SAGE Bootloader Version [RELEASE=4.0.7.0, Signing Tool=4.0.4.0]
    00:00:00.450 BSAGElib_boot_4x: SAGE Framework  Version [RELEASE=4.0.4.0, Signing Tool=4.0.4.0]
    00:00:00.466 BSAGElib_boot_4x: [BSAGElib_P_Boot_ResetSage] SAGE BL region status = 0x000005C3
    00:00:00.467 BSAGElib_boot_4x:  LEAVING -----------------  [BSAGElib_P_Boot_ResetSage]
    00:00:00.467 BSAGElib_boot_4x: BSAGElib_P_Boot_Framework:679 BSAGElib_P_Boot_SetBootParam(SageVklMask,0x00000003)
    00:00:01.576 BSAGElib: BSAGElib_Boot_Post TBD BHSM_API_VERSION=2 post boot actions
    00:00:01.582 BSAGElib: SAGE TA: ANTIROLLBACK [Version=4.0.2.0, Signing Tool=4.0.4.0]
    00:00:01.658 nexus_sage_ar: NEXUS_Sage_P_ARInit - Skipping AR Database load, file does not exist...
    00:00:01.674 nexus_sage_ar: Sage AR TA running with Builtin database version 9
    00:00:01.699 BSAGElib: SAGE TA: SECURE_VIDEO [Version=4.0.3.0, Signing Tool=4.0.4.0]
*** 00:00:01.794 nexus_sage_svp: NEWER SAGE SVP API VERSION SET DETECTED! But it is compatible
    00:00:01.803 BSAGElib: SAGE TA: BP3 [Version=4.2.5.40, Signing Tool=4.0.4.0]
    00:00:01.941 nexus_sage_bp3: Sage BP3 TA running
    00:00:01.941 nexus_sage_bp3: bond option 0
    4487:37:14.946 nexus_sage_bp3: Processed bp3.bin rc=0
    4487:37:14.946 nexus_sage_bp3: Names of Features that are BP3 provisioned:
    4487:37:14.946 nexus_sage_bp3: Dolby Decode Digital
    4487:37:14.947 nexus_sage_bp3: Dolby Decode Digital Plus
    4487:37:14.947 nexus_sage_bp3: Broadcom H265(HEVC)
    4487:37:14.971 nexus_hdmi_input_hdcp: NEXUS_HdmiInput_LoadHdcpTA_priv: allocate 74028 bytes for HDCP_TA buffer
*** 4487:37:14.971 nexus_audio_module: (DSP) FW download used
*** 4487:37:15.642 BXVD_PRIV: BXVD_P_OpenPartTwo() - Hardware revision: T, Firmware revision: 21a0a00 SHA: 0963b65f
*** 4487:37:15.648 BXVD_PRIV: BXVD_P_OpenPartTwo() - Hardware revision: T, Firmware revision: 21a0a00 SHA: 0963b65f
### 4487:37:15.648 nexus_base_mmap: duplicated map: (0x02ff00000,  (null),e8000000):1048576 and (0x06de00000,f1301000,00001000):155185152   
*** 4487:37:15.649 nexus_video_encoder: FW download used
*** 4487:37:15.698 BVCE: FW v4.21.0.0 (0x04150000) [API v9.0.0.0 (0x09000000)][0]
*** 4487:37:15.698 b_objdb_class: Class:'NEXUS_AudioOutput' count:9 live:9
    4487:37:15.698 BHDM_EDID: Initializing/Reading EDID Information   (BHDM URSR 18.2 7278)
*** 4487:37:15.729 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1360 x 768 ( 768p)
*** 4487:37:15.729 BHDM_EDID:  
*** 4487:37:15.729 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1152 x 864 ( 864p)
*** 4487:37:15.729 BHDM_EDID:  
*** 4487:37:15.729 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1400 x 1050 (1050p)
*** 4487:37:15.729 BHDM_EDID:  
*** 4487:37:15.729 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1440 x 900 ( 900p)
*** 4487:37:15.729 BHDM_EDID:  
    4487:37:15.729 nexus_hdmi_output_hotplug: disconnected -> rxsense_check
*** 4487:37:15.730 nexus_platform_frontend: Opening 45308...
*** 4487:37:15.731 nexus_frontend_45308: Initializing 45308 Frontend core...
*** 4487:37:15.732 nexus_platform: initialized
Open failed /sys/class/i2c-adapter/i2c-0/0-0040/iio:device0/in_power2_raw
*** 4487:37:15.644 thermal_config: Thermal config file nxclient/thermal.cfg not found. Using defaults
!!!Error BERR_NOT_AVAILABLE(0xa) at nxserverlib_thermal.c:494 
*** 4487:37:15.644 nxserverlib_thermal: Started Thermal Monitor
nxserver is running.
    4487:37:15.779 nexus_hdmi_output_hotplug: rxsense_check -> powered_on
*** 4487:37:17.077 nexus_frontend_45308: Initializing 45308 core... Done
*** 4487:37:21.952 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.958 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.963 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.968 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.971 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.974 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.976 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.978 nexus_recpump: data.dataReadyThreshold is very large. Overflow likely.
*** 4487:37:21.996 nexus_display_vbi: No VBI resource available for VBI path 0 on display 0.
    4487:37:21.996 BHDM_EDID: Initializing/Reading EDID Information   (BHDM URSR 18.2 7278)
*** 4487:37:22.028 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1360 x 768 ( 768p)
*** 4487:37:22.028 BHDM_EDID:  
*** 4487:37:22.028 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1152 x 864 ( 864p)
*** 4487:37:22.028 BHDM_EDID:  
*** 4487:37:22.028 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1400 x 1050 (1050p)
*** 4487:37:22.028 BHDM_EDID:  
*** 4487:37:22.028 BHDM_EDID: Unknown/Unsupported Detailed Timing Format 1440 x 900 ( 900p)
*** 4487:37:22.028 BHDM_EDID:  
    4487:37:22.028 BHDM: Tx0 Output: 1080i    (RGB (Default) 24 bpp) 1920 [+] x 540/540 [+], PxlClk: 74MHz (TMDS 74 Mcsc)
    4487:37:22.028 BHDM: Tx0: Output Mode: DVI (Video Only)
*** 4487:37:22.129 nexus_hdmi_output_format_validation: 12 bit Color Depth is not supported by <GRUNDIG WUXGA> Rx... checking lower color depths
*** 4487:37:22.129 nexus_hdmi_output_format_validation: 10 bit Color Depth is not supported by <GRUNDIG WUXGA>... will use standard 8 bit Color
    4487:37:22.163 BHDM: Tx0 Output: 720p     (YCbCr 4:4:4 24 bpp) 1280 [+] x 720/720 [+], PxlClk: 74MHz (TMDS 74 Mcsc)
*** 4487:37:22.198 nexus_statistics_api: NEXUS_Display_AddOutput[display:Default] 202 msec


Re: Broadcom drivers #5 Erik Slagter

  • PLi® Core member
  • 46,951 posts

+541
Excellent

Posted 5 December 2020 - 11:21

These are:

- for Android

- no chipsets that are used by OpenPLi compatible receivers

- the code is only the glue, the real code is still in binary blobs


* Wavefrontier T90 with 28E/23E/19E/13E via SCR switches 2 x 2 x 6 user bands
I don't read PM -> if you have something to ask or to report, do it in the forum so others can benefit. I don't take freelance jobs.
Ik lees geen PM -> als je iets te vragen of te melden hebt, doe het op het forum, zodat anderen er ook wat aan hebben.


Re: Broadcom drivers #6 WanWizard

  • PLi® Core member
  • 68,311 posts

+1,719
Excellent

Posted 5 December 2020 - 22:56

I think in theory it could run on boxes with a BCM chip, the problem is that it needs the Nexus SDK, which isn't included, all it does is refer to nexus.ko and expects it to be there.


Currently in use: VU+ Duo 4K (2xFBC S2), VU+ Solo 4K (1xFBC S2), uClan Usytm 4K Pro (S2+T2), Octagon SF8008 (S2+T2), Zgemma H9.2H (S2+T2)

Due to my bad health, I will not be very active at times and may be slow to respond. I will not read the forum or PM on a regular basis.

Many answers to your question can be found in our new and improved wiki.


Re: Broadcom drivers #7 redblue

  • Member
  • 7 posts

0
Neutral

Posted 6 December 2020 - 01:54

What is included in the nexus SDK? After loading the nexus.ko module, it plays video files, which is what the BCM7278 chip in vuduo4k allows. The original drivers are android too. Only for unrecognization the files have been renamed to dvb_server, dvb_core etc.



Re: Broadcom drivers #8 Erik Slagter

  • PLi® Core member
  • 46,951 posts

+541
Excellent

Posted 6 December 2020 - 10:26

Included in the Nexus SDK is "everything". SoC's don't work like "here is a file or a tuner, just start playing it".


* Wavefrontier T90 with 28E/23E/19E/13E via SCR switches 2 x 2 x 6 user bands
I don't read PM -> if you have something to ask or to report, do it in the forum so others can benefit. I don't take freelance jobs.
Ik lees geen PM -> als je iets te vragen of te melden hebt, doe het op het forum, zodat anderen er ook wat aan hebben.


Re: Broadcom drivers #9 dpeddi

  • Senior Member
  • 41 posts

+4
Neutral

Posted 14 December 2020 - 10:41

That repo seems a leak of the base reference design that broadcom give to system integrators. It seems good to me but is for android boxes. It can be an extension to the one that bcm send to oem for enigma2 boxes.

 

Probably if you know your hardware platform you can replicate the driver of your box, but it should be quite difficult. The frontpanel of the boxes is custom made and the more difficult part, is the enigma2 compatibility layer...

About the tuner driver i have to check but i doubt that are compatible with linux-media .



Re: Broadcom drivers #10 Erik Slagter

  • PLi® Core member
  • 46,951 posts

+541
Excellent

Posted 14 December 2020 - 20:09

Just like I said before, it's only a small fraction of what you actually need to drive a complete Broadcom SoC.


* Wavefrontier T90 with 28E/23E/19E/13E via SCR switches 2 x 2 x 6 user bands
I don't read PM -> if you have something to ask or to report, do it in the forum so others can benefit. I don't take freelance jobs.
Ik lees geen PM -> als je iets te vragen of te melden hebt, doe het op het forum, zodat anderen er ook wat aan hebben.


Re: Broadcom drivers #11 redblue

  • Member
  • 7 posts

0
Neutral

Posted 28 December 2020 - 02:00

https://github.com/d...phics!brcmfb.c~

https://github.com/d...serverinfo.org~

Unbelievable that garbage can be found on github. The first is I see an incomplete framebuffer driver, it gives an idea of how the drivers are built.



Re: Broadcom drivers #12 dpeddi

  • Senior Member
  • 41 posts

+4
Neutral

Posted 6 January 2021 - 01:43

 

Maybe someone would be willing to take a closer look at these drivers? https://github.com/m....broadcom.refsw So far, I wrote a primitive pilot service for fun :)

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <media/rc-core.h>

#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>

#include <asm/io.h>
#include <linux/io.h>

#include "rc.h"

#include <linux/ktime.h>
#include <linux/delay.h>

#define MODULE_NAME "bcmrc"

#define BASE_REG_ADDR 0x08000000

/* com0 (ttyS0) registers */
#define UARTA_REG_START	0x0040c000
#define UARTA_REG_END	0x0040c01c
#define UARTA_IRQ 128

/* com1 (ttyS1) registers */
#define UARTB_REG_START	0x0040d000
#define UARTB_REG_END	0x0040d01c
#define UARTB_IRQ 129

/* com2 (ttyS2) registers */
#define UARTC_REG_START	0x0040e000
#define UARTC_REG_END	0x0040e01c
#define UARTC_IRQ 130

#define UART_ADDRSIZE 0x1000

enum {
	COM0 = 0,
	COM1 = 1,
	COM2 = 2,
};

#define COM_PORT COM2
#define COM_ADDRSIZE UART_ADDRSIZE
#define COM_IRQ UARTC_IRQ

#define bcmrc_debug(fmt, arg...) printk(KERN_DEBUG "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_info(fmt, arg...) printk(KERN_INFO "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_error(fmt, arg...) printk(KERN_ERR "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_warning(fmt, arg...) printk(KERN_WARNING "%s: %s " fmt, MODULE_NAME, __func__, ##arg)
#define bcmrc_alert(fmt, arg...) printk(KERN_ALERT "%s: %s " fmt, MODULE_NAME, __func__, ##arg)

static const unsigned short vuduo4k_remote_key_table[] = {
	KEY_POWER,
	KEY_TEXT,
	KEY_SUBTITLE,
	KEY_HELP,
	KEY_0,
	KEY_1,
	KEY_2,
	KEY_3,
	KEY_4,
	KEY_5,
	KEY_6,
	KEY_7,
	KEY_8,
	KEY_9,
	KEY_PREVIOUS,
	KEY_NEXT,
	KEY_RED,
	KEY_GREEN,
	KEY_YELLOW,
	KEY_BLUE,
	KEY_VIDEO,
	KEY_MENU,
	KEY_EXIT,
	KEY_INFO,
	KEY_OK,
	KEY_UP,
	KEY_DOWN,
	KEY_RIGHT,
	KEY_LEFT,
	KEY_VOLUMEUP,
	KEY_VOLUMEDOWN,
	KEY_CHANNELUP,
	KEY_CHANNELDOWN,
	KEY_AUDIO,
	KEY_MUTE,
	KEY_EDIT,
	KEY_REWIND,
	KEY_PLAY,
	KEY_PLAYPAUSE,
	KEY_FASTFORWARD,
	KEY_TV,
	KEY_RECORD,
	KEY_STOP,
	KEY_RADIO,
};

struct bcmrc_par {
	struct input_dev *input;
	struct uart_8250_port uart;
	void __iomem *iomem_base;
	spinlock_t hardware_lock;
	int i;
	unsigned char buffer[16];
	int irq;
	unsigned short keymap[ARRAY_SIZE(vuduo4k_remote_key_table)];
};

static struct bcmrc_par bcmrc;

static unsigned int get_com_membase_reg(int com_nr)
{
	unsigned int result;
	switch (com_nr) {
		case COM0:
			result = UARTA_REG_START + BASE_REG_ADDR;
			break;
		case COM1:
			result = UARTB_REG_START + BASE_REG_ADDR;
			break;
		case COM2:
			result = UARTC_REG_START + BASE_REG_ADDR;
			break;
	}
	return result;
}

static unsigned int get_com_irq(int com_nr)
{
	unsigned int result;
	switch (com_nr) {
		case COM0:
			result = UARTA_IRQ;
			break;
		case COM1:
			result = UARTB_IRQ;
			break;
		case COM2:
			result = UARTC_IRQ;
			break;
	}
	return result;
}

static inline unsigned int serial_in(struct uart_8250_port *up, unsigned int offset)
{
	unsigned int result;
	offset = offset << up->port.regshift;

	switch (up->port.iotype) {
		case UPIO_HUB6:
			outb(up->port.hub6 - 1 + offset, up->port.iobase);
			result = inb(up->port.iobase + 1);
			//bcmrc_info("UPIO_HUB6, iobase 0x%.4x, offset: 0x%.4x, result: %d\n", up->port.iobase, offset, result);
			break;

		case UPIO_MEM:
			result = readb(up->port.membase + offset);
			//bcmrc_info("UPIO_MEM, membase 0x%.4x, offset: 0x%.4x, reg: 0x%.4x, result: %d\n", up->port.membase, offset, up->port.membase + offset, result);
			break;

		case UPIO_MEM32:
			result = readl(up->port.membase + offset);
			//bcmrc_info("UPIO_MEM32, membase 0x%.4x, offset: 0x%.4x, result: %d\n", up->port.membase, offset, result);
			break;

		default:
			//return ioread32(up->port.membase + offset);
			result = inb(up->port.iobase + offset);
			//bcmrc_info("default, membase 0x%.4x, offset: 0x%.4x, result: %d\n", up->port.iobase, offset, result);
			break;
	}
	return result;
}

static inline void serial_out(struct uart_8250_port *up, unsigned int offset, unsigned int value)
{
	offset = offset << up->port.regshift;

	switch (up->port.iotype) {
		case UPIO_HUB6:
			//bcmrc_info("UPIO_HUB6, iobase 0x%.4x, offset: 0x%.4x, value: %d\n", up->port.iobase, offset, value);
			outb(up->port.hub6 - 1 + offset, up->port.iobase);
			outb(value, up->port.iobase + 1);
			break;

		case UPIO_MEM:
			//bcmrc_info("UPIO_MEM, membase 0x%.4x, offset: 0x%.4x, reg: 0x%.4x, value: %d\n", up->port.membase, offset, up->port.membase + offset, value);
			writeb(value, up->port.membase + offset);
			break;

		case UPIO_MEM32:
			//bcmrc_info("UPIO_MEM32, membase 0x%.4x, offset: 0x%.4x, value: %d\n", up->port.membase, offset, value);
			writel(value, up->port.membase + offset);
			break;

		default:
			//bcmrc_info("default, membase 0x%.4x, offset: 0x%.4x, value %d\n", up->port.iobase, offset, value);
			//iowrite32(value, up->port.membase + offset);
			outb(value, up->port.iobase + offset);
			break;
	}
}

static int bcmrc_open(struct input_dev *dev)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned long flags;
#if 0
	/* initialize timestamp */
	//par->lastkt = ktime_get();

	spin_lock_irqsave(&par->hardware_lock, flags);

	/* Set DLAB 0. */
	serial_out(&par->uart, UART_LCR, serial_in(&par->uart, (UART_LCR) & (~UART_LCR_DLAB)));

	serial_out(&par->uart, UART_IER, serial_in(&par->uart, (UART_IER) | UART_IER_MSI));

	spin_unlock_irqrestore(&par->hardware_lock, flags);
#endif
	return 0;
}

static void bcmrc_close(struct input_dev *dev)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned long flags;
#if 0
	spin_lock_irqsave(&par->hardware_lock, flags);

	/* Set DLAB 0. */
	serial_out(&par->uart, UART_LCR, serial_in(&par->uart, (UART_LCR) & (~UART_LCR_DLAB)));

	/* First of all, disable all interrupts */
	serial_out(&par->uart, UART_IER, serial_in(&par->uart, (UART_IER) & (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))));

	spin_unlock_irqrestore(&par->hardware_lock, flags);
#endif
}

static long bcmrc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	struct bcmrc_par *par = (struct bcmrc_par*) filep->private_data;
	int result;

	switch (cmd) {

	}

	return result;
}

static int bcmrc_frontpanel_key_mapping(struct input_dev *dev, unsigned int key)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned int result;

	switch (key) {
		case 0x01:
			result = KEY_POWER;
			break;
		case 0x02:
			result = KEY_VOLUMEUP;
			break;
		case 0x04:
			result = KEY_VOLUMEDOWN;
			break;
		case 0x08:
			result = KEY_CHANNELUP;
			break;
		case 0x80:
			result = KEY_CHANNELDOWN;
			break;
		default:
			bcmrc_info("Unhandled key: 0x%.2x\n", key);
			result = 0;
			break;
	}
	return result;
}

static int bcmrc_remote_key_mapping(struct input_dev *dev, unsigned int key)
{
	struct bcmrc_par *par = input_get_drvdata(dev);
	unsigned int result;

	switch (key) {
		case 0x0c:
			result = KEY_POWER;
			break;
		case 0x3c:
			result = KEY_TEXT;
			break;
		case 0x4b:
			result = KEY_SUBTITLE;
			break;
		case 0x81:
			result = KEY_HELP;
			break;
		case 0x00:
			result = KEY_0;
			break;
		case 0x01:
			result = KEY_1;
			break;
		case 0x02:
			result = KEY_2;
			break;
		case 0x03:
			result = KEY_3;
			break;
		case 0x04:
			result = KEY_4;
			break;
		case 0x05:
			result = KEY_5;
			break;
		case 0x06:
			result = KEY_6;
			break;
		case 0x07:
			result = KEY_7;
			break;
		case 0x08:
			result = KEY_8;
			break;
		case 0x09:
			result = KEY_9;
			break;
		case 0xbb:
			result = KEY_PREVIOUS;
			break;
		case 0xbc:
			result = KEY_NEXT;
			break;
		case 0x6d:
			result = KEY_RED;
			break;
		case 0x6e:
			result = KEY_GREEN;
			break;
		case 0x6f:
			result = KEY_YELLOW;
			break;
		case 0x70:
			result = KEY_BLUE;
			break;
		case 0x49:
			result = KEY_VIDEO;
			break;
		case 0x54:
			result = KEY_MENU;
			break;
		case 0xcc:
			result = KEY_EXIT;
			break;
		case 0x55:
			result = KEY_INFO;
			break;
		case 0x5c:
			result = KEY_OK;
			break;
		case 0x58:
			result = KEY_UP;
			break;
		case 0x59:
			result = KEY_DOWN;
			break;
		case 0x5b:
			result = KEY_RIGHT;
			break;
		case 0x5a:
			result = KEY_LEFT;
			break;
		case 0x10:
			result = KEY_VOLUMEUP;
			break;
		case 0x11:
			result = KEY_VOLUMEDOWN;
			break;
		case 0x20:
			result = KEY_CHANNELUP;
			break;
		case 0x21:
			result = KEY_CHANNELDOWN;
			break;
		case 0xe5:
			result = KEY_AUDIO;
			break;
		case 0x0d:
			result = KEY_MUTE;
			break;
		case 0xe6:
			result = KEY_EDIT;
			break;
		case 0x29:
			result = KEY_REWIND;
			break;
		case 0x2c:
			result = KEY_PLAY;
			break;
		case 0x30:
			result = KEY_PLAYPAUSE;
			break;
		case 0x28:
			result = KEY_FASTFORWARD;
			break;
		case 0xe4:
			result = KEY_TV;
			break;
		case 0x37:
			result = KEY_RECORD;
			break;
		case 0x31:
			result = KEY_STOP;
			break;
		case 0xf2:
			result = KEY_RADIO;
			break;
		default:
			bcmrc_info("Unhandled key: 0x%.2x\n", key);
			result = 0;
			break;
	}
	return result;
}

static irqreturn_t bcmrc_irq_handler(int irq, void *dev_id)
{
	struct bcmrc_par *par = (struct bcmrc_par *)dev_id;
	struct input_dev *input = par->input;
	unsigned long flags;
	unsigned int iir, lsr, i = 0;
	int counter = 0, max_count = 8;

	while ((iir = serial_in(&par->uart, UART_IIR & UART_IIR_ID))) {
		if (++counter > 256) {
			//bcmrc_error("Trapped in interrupt, counter %d\n", counter);
			break;
		}

		switch (iir & UART_IIR_ID) {
			case UART_IIR_MSI:
				(void) serial_in(&par->uart, UART_MSR);
				break;
			case UART_IIR_RLSI:
			case UART_IIR_THRI:
				(void) serial_in(&par->uart, UART_LSR);
				break;
			case UART_IIR_RDI:
				spin_lock_irqsave(&par->hardware_lock, flags);
				do {
					par->buffer[par->i++] = serial_in(&par->uart, UART_RX);
					if (par->i == 7) {
						//bcmrc_info("first packet 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x\n", par->buffer[0], par->buffer[1], par->buffer[2], par->buffer[3], par->buffer[4], par->buffer[5], par->buffer[6], par->buffer[7]);
						if (par->buffer[0] == 0xd1)
							input_report_key(par->input, bcmrc_frontpanel_key_mapping(par->input, par->buffer[1]), 1);
						else if (par->buffer[0] == 0xd2)
							input_report_key(par->input, bcmrc_remote_key_mapping(par->input, par->buffer[1]), 1);
						input_sync(par->input);
					}
					if (par->i == 15) {
						//bcmrc_info("second packet 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x\n", par->buffer[8], par->buffer[9], par->buffer[10], par->buffer[11], par->buffer[12], par->buffer[13], par->buffer[14], par->buffer[15]);
						if (par->buffer[0] == 0xd1)
							input_report_key(par->input, bcmrc_frontpanel_key_mapping(par->input, par->buffer[1]), 0);
						else if (par->buffer[0] == 0xd2)
							input_report_key(par->input, bcmrc_remote_key_mapping(par->input, par->buffer[1]), 0);
						input_sync(par->input);
						par->i = 0;
					}
					lsr = serial_in(&par->uart, UART_LSR);
				} while (lsr & UART_LSR_DR);
				spin_unlock_irqrestore(&par->hardware_lock, flags);
				break;
			default:
				break;
		}
	}

	return IRQ_RETVAL(1);
}

int init_bcmrcdev(void)
{
	int result, i;
	struct bcmrc_par *par;
	struct input_dev *input_dev;
	struct uart_8250_port uart;

	unsigned long flags;

	par = kzalloc(sizeof(struct bcmrc_par), GFP_KERNEL);
	if (!par) {
		bcmrc_error("Error allocate primary structure!");
		return -ENOMEM;
		goto err_free_mem;
	}

	par->uart = uart;

	par->irq = get_com_irq(COM2);

	par->iomem_base = ioremap(get_com_membase_reg(COM2), COM_ADDRSIZE);
	if (!par->iomem_base) {
		bcmrc_error("Error remap memory!");
		goto err_iounmap;
	}

	result = request_threaded_irq(par->irq, bcmrc_irq_handler, 0, 0, "serial", par);
	if (result < 0) {
		if (result == -EBUSY)
			bcmrc_error("IRQ %d busy\n", par->irq);
		else if (result == -EINVAL)
			bcmrc_error("Bad irq number\n");
		return -EBUSY;
		goto err_free_input;
	}

	memset(&par->uart, 0, sizeof(par->uart));

	par->uart.port.type = PORT_16550A;
	par->uart.port.irq = par->irq;
	par->uart.port.uartclk = 5062500; /* 3686400 */
	par->uart.port.flags = UPF_SHARE_IRQ;
	par->uart.port.iotype = UPIO_MEM;
	par->uart.port.membase = par->iomem_base;
	par->uart.port.regshift = 2;

	spin_lock_irqsave(&par->hardware_lock, flags);

	serial_out(&par->uart, UART_IER, 0);

	/* Set DLAB 0. */
	serial_out(&par->uart, UART_LCR, serial_in(&par->uart, (UART_LCR) & (~UART_LCR_DLAB)));

	/* First of all, disable all interrupts */
	serial_out(&par->uart, UART_IER, serial_in(&par->uart, (UART_IER) & (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))));

	/* Clear registers. */
	serial_in(&par->uart, UART_LSR);
	serial_in(&par->uart, UART_RX);
	serial_in(&par->uart, UART_IIR);
	serial_in(&par->uart, UART_MSR);

	serial_out(&par->uart, UART_IER, 1);

	/* Clear registers again to be sure. */
	serial_in(&par->uart, UART_LSR);
	serial_in(&par->uart, UART_RX);
	serial_in(&par->uart, UART_IIR);
	serial_in(&par->uart, UART_MSR);

	spin_unlock_irqrestore(&par->hardware_lock, flags);

	input_dev = input_allocate_device();
	if (!input_dev) {
		bcmrc_error("Error alocate input device structure!");
		return -ENOMEM;
		goto err_free_input;
	}

	memcpy(par->keymap, vuduo4k_remote_key_table, sizeof(par->keymap));

	input_dev->keycode = par->keymap;
	input_dev->keycodesize = sizeof(unsigned short);
	input_dev->keycodemax = ARRAY_SIZE(par->keymap);

	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
	__set_bit(EV_KEY, input_dev->evbit);
	for (i = 0; i < ARRAY_SIZE(vuduo4k_remote_key_table); i++)
		__set_bit(vuduo4k_remote_key_table[i], input_dev->keybit);
	__clear_bit(KEY_RESERVED, input_dev->keybit);

	input_dev->name = "dreambox advanced remote control (native)";
	input_dev->phys = "event0";

	input_dev->id.bustype = BUS_HOST;

	input_dev->open = bcmrc_open;
	input_dev->close = bcmrc_close;

	par->input = input_dev;

	input_set_drvdata(par->input, par);

	result = input_register_device(par->input);
	if (result) {
		return -1;
	}

	return 0;

err_free_input:
	input_free_device(input_dev);
err_iounmap:
	iounmap(par->iomem_base);
err_free_mem_region:
	release_mem_region(get_com_membase_reg(COM2), COM_ADDRSIZE);
err_free_mem:
	input_free_device(input_dev);
	kfree(par);
	return result;
}

void exit_bcmrcdev(void)
{
	struct input_dev *input_dev;
	input_unregister_device(input_dev);
	input_free_device(input_dev);
}

 

I've tested your code but it doesn't work for me on vuuno4kse. How you get it to work?

 

bye



Re: Broadcom drivers #13 dpeddi

  • Senior Member
  • 41 posts

+4
Neutral

Posted 6 January 2021 - 02:15

this is my error
 ARM ioremap() warning has been disabled!
 genirq: Flags mismatch irq 130. 00000004 (serial) vs. 00000084 (V3D_INT)
 bcmrc: init_bcmrcdev IRQ 130 busy


Re: Broadcom drivers #14 dpeddi

  • Senior Member
  • 41 posts

+4
Neutral

Posted 6 January 2021 - 02:32

I've adapted the registry for vuuno4kse
[   35.978107] input: dreambox advanced remote control (native) as /devices/virtual/input/input5


Re: Broadcom drivers #15 redblue

  • Member
  • 7 posts

0
Neutral

Posted 9 January 2021 - 02:58

Hello

You have two options to reach the data that interests you. First dvb-core decompilation, looking for a function called bm750_input_event_init. The second is the file: https://github.com/m...b1/bchp_uartc.h



Re: Broadcom drivers #16 dpeddi

  • Senior Member
  • 41 posts

+4
Neutral

Posted 9 January 2021 - 09:48

Hello
You have two options to reach the data that interests you. First dvb-core decompilation, looking for a function called bm750_input_event_init. The second is the file: https://github.com/m...b1/bchp_uartc.h


Yes i know... I had to look at 7439, probably the best way is to use the sdk makefile and let it to auto load the correcr header. For now I just followed the quick and dirty way just to test if it works and I've copied the raw address from the sdk header..

Your code works(great!), good starting point, but with really poor performance.. i have to press multiple time (up to 8) the same button to get it recognized.

I've decompiled the driver (the one from vuuno4kse) as well and the interrupt routine seems to have differencies... Maybe it lack some other checks.

Later i plan to compare the function from both vuduo4k and vuuno4kse but i expect to be identical


E.


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users