Skip to content

Commit

Permalink
Merge branch 'pxa-tosa' into pxa
Browse files Browse the repository at this point in the history
Conflicts:

	arch/arm/mach-pxa/Kconfig
	arch/arm/mach-pxa/tosa.c
	arch/arm/mach-pxa/spitz.c
  • Loading branch information
Russell King authored and Russell King committed Jul 12, 2008
2 parents a9da4f7 + 9388704 commit 7fecc34
Show file tree
Hide file tree
Showing 22 changed files with 1,539 additions and 97 deletions.
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained

ARM/TOSA MACHINE SUPPORT
P: Dmitry Baryshkov
M: dbaryshkov@gmail.com
P: Dirk Opfer
M: dirk@opfer-online.de
S: Maintained
Expand Down
9 changes: 9 additions & 0 deletions arch/arm/mach-pxa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,13 @@ config PXA_PWM
default BACKLIGHT_PWM
help
Enable support for PXA2xx/PXA3xx PWM controllers

config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
depends on MACH_TOSA
select RFKILL
help
This is a simple driver that is able to control
the state of built in bluetooth chip on tosa.

endif
4 changes: 3 additions & 1 deletion arch/arm/mach-pxa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Common support (must be linked before board specific support)
obj-y += clock.o devices.o generic.o irq.o dma.o \
time.o gpio.o
time.o gpio.o reset.o
obj-$(CONFIG_PM) += pm.o sleep.o standby.o
obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o

Expand Down Expand Up @@ -61,3 +61,5 @@ obj-$(CONFIG_LEDS) += $(led-y)
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
endif

obj-$(CONFIG_TOSA_BT) += tosa-bt.o
96 changes: 96 additions & 0 deletions arch/arm/mach-pxa/reset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/proc-fns.h>

#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-regs.h>

static void do_hw_reset(void);

static int reset_gpio = -1;

int init_gpio_reset(int gpio)
{
int rc;

rc = gpio_request(gpio, "reset generator");
if (rc) {
printk(KERN_ERR "Can't request reset_gpio\n");
goto out;
}

rc = gpio_direction_input(gpio);
if (rc) {
printk(KERN_ERR "Can't configure reset_gpio for input\n");
gpio_free(gpio);
goto out;
}

out:
if (!rc)
reset_gpio = gpio;

return rc;
}

/*
* Trigger GPIO reset.
* This covers various types of logic connecting gpio pin
* to RESET pins (nRESET or GPIO_RESET):
*/
static void do_gpio_reset(void)
{
BUG_ON(reset_gpio == -1);

/* drive it low */
gpio_direction_output(reset_gpio, 0);
mdelay(2);
/* rising edge or drive high */
gpio_set_value(reset_gpio, 1);
mdelay(2);
/* falling edge */
gpio_set_value(reset_gpio, 0);

/* give it some time */
mdelay(10);

WARN_ON(1);
/* fallback */
do_hw_reset();
}

static void do_hw_reset(void)
{
/* Initialize the watchdog and let it fire */
OWER = OWER_WME;
OSSR = OSSR_M3;
OSMR3 = OSCR + 368640; /* ... in 100 ms */
}

void arch_reset(char mode)
{
if (cpu_is_pxa2xx())
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;

switch (mode) {
case 's':
/* Jump into ROM at address 0 */
cpu_reset(0);
break;
case 'h':
do_hw_reset();
break;
case 'g':
do_gpio_reset();
break;
}
}

8 changes: 3 additions & 5 deletions arch/arm/mach-pxa/spitz.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-regs.h>
#include <asm/arch/pxa2xx-gpio.h>
#include <asm/arch/pxa27x-udc.h>
#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/ohci.h>
Expand Down Expand Up @@ -529,11 +530,7 @@ static struct platform_device *devices[] __initdata = {

static void spitz_poweroff(void)
{
pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);

mdelay(1000);
arm_machine_restart('h');
arm_machine_restart('g');
}

static void spitz_restart(char mode)
Expand All @@ -547,6 +544,7 @@ static void spitz_restart(char mode)

static void __init common_init(void)
{
init_gpio_reset(SPITZ_GPIO_ON_RESET);
pm_power_off = spitz_poweroff;
arm_pm_restart = spitz_restart;

Expand Down
150 changes: 150 additions & 0 deletions arch/arm/mach-pxa/tosa-bt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Bluetooth built-in chip control
*
* Copyright (c) 2008 Dmitry Baryshkov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/rfkill.h>

#include <asm/arch/tosa_bt.h>

static void tosa_bt_on(struct tosa_bt_data *data)
{
gpio_set_value(data->gpio_reset, 0);
gpio_set_value(data->gpio_pwr, 1);
gpio_set_value(data->gpio_reset, 1);
mdelay(20);
gpio_set_value(data->gpio_reset, 0);
}

static void tosa_bt_off(struct tosa_bt_data *data)
{
gpio_set_value(data->gpio_reset, 1);
mdelay(10);
gpio_set_value(data->gpio_pwr, 0);
gpio_set_value(data->gpio_reset, 0);
}

static int tosa_bt_toggle_radio(void *data, enum rfkill_state state)
{
pr_info("BT_RADIO going: %s\n",
state == RFKILL_STATE_ON ? "on" : "off");

if (state == RFKILL_STATE_ON) {
pr_info("TOSA_BT: going ON\n");
tosa_bt_on(data);
} else {
pr_info("TOSA_BT: going OFF\n");
tosa_bt_off(data);
}
return 0;
}

static int tosa_bt_probe(struct platform_device *dev)
{
int rc;
struct rfkill *rfk;

struct tosa_bt_data *data = dev->dev.platform_data;

rc = gpio_request(data->gpio_reset, "Bluetooth reset");
if (rc)
goto err_reset;
rc = gpio_direction_output(data->gpio_reset, 0);
if (rc)
goto err_reset_dir;
rc = gpio_request(data->gpio_pwr, "Bluetooth power");
if (rc)
goto err_pwr;
rc = gpio_direction_output(data->gpio_pwr, 0);
if (rc)
goto err_pwr_dir;

rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH);
if (!rfk) {
rc = -ENOMEM;
goto err_rfk_alloc;
}

rfk->name = "tosa-bt";
rfk->toggle_radio = tosa_bt_toggle_radio;
rfk->data = data;
#ifdef CONFIG_RFKILL_LEDS
rfk->led_trigger.name = "tosa-bt";
#endif

rc = rfkill_register(rfk);
if (rc)
goto err_rfkill;

platform_set_drvdata(dev, rfk);

return 0;

err_rfkill:
if (rfk)
rfkill_free(rfk);
rfk = NULL;
err_rfk_alloc:
tosa_bt_off(data);
err_pwr_dir:
gpio_free(data->gpio_pwr);
err_pwr:
err_reset_dir:
gpio_free(data->gpio_reset);
err_reset:
return rc;
}

static int __devexit tosa_bt_remove(struct platform_device *dev)
{
struct tosa_bt_data *data = dev->dev.platform_data;
struct rfkill *rfk = platform_get_drvdata(dev);

platform_set_drvdata(dev, NULL);

if (rfk)
rfkill_unregister(rfk);
rfk = NULL;

tosa_bt_off(data);

gpio_free(data->gpio_pwr);
gpio_free(data->gpio_reset);

return 0;
}

static struct platform_driver tosa_bt_driver = {
.probe = tosa_bt_probe,
.remove = __devexit_p(tosa_bt_remove),

.driver = {
.name = "tosa-bt",
.owner = THIS_MODULE,
},
};


static int __init tosa_bt_init(void)
{
return platform_driver_register(&tosa_bt_driver);
}

static void __exit tosa_bt_exit(void)
{
platform_driver_unregister(&tosa_bt_driver);
}

module_init(tosa_bt_init);
module_exit(tosa_bt_exit);
Loading

0 comments on commit 7fecc34

Please sign in to comment.