Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ci20 v3.18 bluetooth v2 #43

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Documentation/devicetree/bindings/net/rfkill/rfkill-relugator.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Regulator consumer for rfkill devices

Required properties:
- compatible : Must be "rfkill-regulator".
- label : Name of rfkill device.
- type : Type of rfkill device.

Possible values (defined in include/dt-bindings/net/rfkill-regulator.h):
RFKILL_TYPE_ALL
RFKILL_TYPE_WLAN
RFKILL_TYPE_BLUETOOTH
RFKILL_TYPE_UWB
RFKILL_TYPE_WIMAX
RFKILL_TYPE_WWAN
RFKILL_TYPE_GPS
RFKILL_TYPE_FM
RFKILL_TYPE_NFC

- vrfkill-supply - regulator device.

Example:
gps-rfkill {
compatible = "rfkill-regulator";
label = "GPS";
type = <RFKILL_TYPE_GPS>;
vrfkill-supply = <&reg>;
};

9 changes: 8 additions & 1 deletion arch/mips/boot/dts/ci20.dts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/net/rfkill-regulator.h>
#include "jz4780.dtsi"

/ {
Expand Down Expand Up @@ -69,7 +70,6 @@
regulator-name = "bt_reset_gpio";
gpio = <&gpf 8 0>;
enable-active-high;
regulator-always-on;
};

/* HACK: Keeping BT_reg_on high. No simple driver fix */
Expand All @@ -89,6 +89,13 @@
enable-active-high;
regulator-always-on;
};

bt-rfkill {
compatible = "rfkill-regulator";
label = "bt-reset";
type = <RFKILL_TYPE_BLUETOOTH>;
vrfkill-supply = <&bt_reset>;
};
};

&ext {
Expand Down
59 changes: 47 additions & 12 deletions drivers/tty/serial/8250/8250_ingenic.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,10 @@ EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart",
ingenic_early_console_setup);


static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
{
int mcr, orig;
int ier;

switch (offset) {
case UART_FCR:
Expand All @@ -143,19 +144,20 @@ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
break;

case UART_IER:
/* Enable receive timeout interrupt with the
* receive line status interrupt */
value |= (value & 0x4) << 2;
break;

case UART_MCR:
/* If we have enabled modem status IRQs we should enable modem
* mode. */
mcr = orig = p->serial_in(p, UART_MCR);
if (value & UART_IER_MSI) {
mcr |= UART_MCR_MDCE | UART_MCR_FCM;
} else {
mcr &= ~(UART_MCR_MDCE | UART_MCR_FCM);
}

if (mcr != orig)
ingenic_uart_serial_out(p, UART_MCR, mcr);
ier = p->serial_in(p, UART_IER);

value |= (value & 0x4) << 2;
if (ier & UART_IER_MSI)
value |= UART_MCR_MDCE | UART_MCR_FCM;
else
value &= ~(UART_MCR_MDCE | UART_MCR_FCM);
break;

default:
Expand All @@ -165,8 +167,31 @@ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
writeb(value, p->membase + (offset << p->regshift));
}

static unsigned int ingenic_uart_serial_in(struct uart_port *p, int offset)
{
unsigned int value;

value = readb(p->membase + (offset << p->regshift));

/* Hide non-16550 compliant bits from higher levels */
switch (offset) {
case UART_FCR:
value &= ~UART_FCR_UME;
break;

case UART_MCR:
value &= ~(UART_MCR_MDCE | UART_MCR_FCM);
break;

default:
break;
}
return value;
}

static int ingenic_uart_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct uart_8250_port uart = {};
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
Expand All @@ -184,13 +209,23 @@ static int ingenic_uart_probe(struct platform_device *pdev)

spin_lock_init(&uart.port.lock);
uart.port.type = PORT_16550;
uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP;
uart.port.iotype = UPIO_MEM;
uart.port.mapbase = regs->start;
uart.port.regshift = 2;
uart.port.serial_out = ingenic_uart_serial_out;
uart.port.serial_in = ingenic_uart_serial_in;
uart.port.irq = irq->start;
uart.port.dev = &pdev->dev;
if (of_device_is_compatible(np, "ingenic,jz4780-uart")) {
uart.port.fifosize = 64;
uart.tx_loadsz = 32;
uart.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
uart.capabilities = UART_CAP_FIFO | UART_CAP_RTOIE;
} else {
/* Use defaults */
uart.port.flags |= UPF_FIXED_TYPE;
}

/* Check for a fixed line number */
line = of_alias_get_id(pdev->dev.of_node, "serial");
Expand Down
23 changes: 23 additions & 0 deletions include/dt-bindings/net/rfkill-regulator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* This header provides macros for rfkill-regulator bindings.
*
* Copyright (C) 2014 Marek Belisko <marek@goldelico.com>
*
* GPLv2 only
*/

#ifndef __DT_BINDINGS_RFKILL_REGULATOR_H__
#define __DT_BINDINGS_RFKILL_REGULATOR_H__


#define RFKILL_TYPE_ALL (0)
#define RFKILL_TYPE_WLAN (1)
#define RFKILL_TYPE_BLUETOOTH (2)
#define RFKILL_TYPE_UWB (3)
#define RFKILL_TYPE_WIMAX (4)
#define RFKILL_TYPE_WWAN (5)
#define RFKILL_TYPE_GPS (6)
#define RFKILL_TYPE_FM (7)
#define RFKILL_TYPE_NFC (8)

#endif /* __DT_BINDINGS_RFKILL_REGULATOR_H__ */
38 changes: 38 additions & 0 deletions net/rfkill/rfkill-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/regulator/consumer.h>
#include <linux/rfkill.h>
#include <linux/rfkill-regulator.h>
#include <linux/of_platform.h>

struct rfkill_regulator_data {
struct rfkill *rf_kill;
Expand Down Expand Up @@ -57,6 +58,31 @@ static struct rfkill_ops rfkill_regulator_ops = {
.set_block = rfkill_regulator_set_block,
};

#ifdef CONFIG_OF
static struct rfkill_regulator_platform_data *
rfkill_regulator_parse_pdata(struct device *dev)
{
struct rfkill_regulator_platform_data *pdata;
struct device_node *np = dev->of_node;
u32 num;
if (!np)
return NULL;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
if (of_property_read_u32(np, "type", &num) == 0)
pdata->type = num;
of_property_read_string(np, "label", &pdata->name);
return pdata;
}
#else
static inline struct rfkill_regulator_platform_data *
rfkill_regulator_parse_pdata(struct device *dev)
{
return NULL;
}
#endif

static int rfkill_regulator_probe(struct platform_device *pdev)
{
struct rfkill_regulator_platform_data *pdata = pdev->dev.platform_data;
Expand All @@ -65,6 +91,9 @@ static int rfkill_regulator_probe(struct platform_device *pdev)
struct rfkill *rf_kill;
int ret = 0;

if (!pdata)
pdata = rfkill_regulator_parse_pdata(&pdev->dev);

if (pdata == NULL) {
dev_err(&pdev->dev, "no platform data\n");
return -ENODEV;
Expand Down Expand Up @@ -137,12 +166,21 @@ static int rfkill_regulator_remove(struct platform_device *pdev)
return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id rfkill_regulator_match[] = {
{.compatible = "rfkill-regulator"},
{}
};
MODULE_DEVICE_TABLE(of, rfkill_regulator_match);
#endif

static struct platform_driver rfkill_regulator_driver = {
.probe = rfkill_regulator_probe,
.remove = rfkill_regulator_remove,
.driver = {
.name = "rfkill-regulator",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(rfkill_regulator_match),
},
};

Expand Down