Commit 3a2ef8db authored by Russell King's avatar Russell King

[ARM] Add platform-based IrDA device support.

Move the platform specific IrDA support code out of sa1100_ir into
the platform support files.  This allows sa1100_ir to build again.
parent da1a8bfa
......@@ -31,6 +31,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/irda.h>
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
#include <asm/arch/assabet.h>
......@@ -94,6 +95,11 @@ static void assabet_lcd_power(int on)
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
}
/*
* Assabet flash support code.
*/
#ifdef ASSABET_REV_4
/*
* Phase 4 Assabet has two 28F160B3 flash parts in bank 0:
......@@ -156,6 +162,42 @@ static struct resource assabet_flash_resources[] = {
}
};
/*
* Assabet IrDA support code.
*/
static int assabet_irda_set_power(struct device *dev, unsigned int state)
{
static unsigned int bcr_state[4] = {
ASSABET_BCR_IRDA_MD0,
ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0,
ASSABET_BCR_IRDA_MD1,
0
};
if (state < 4) {
state = bcr_state[state];
ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1|
ASSABET_BCR_IRDA_MD0));
ASSABET_BCR_set(state);
}
return 0;
}
static void assabet_irda_set_speed(struct device *dev, unsigned int speed)
{
if (speed < 4000000)
ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
else
ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
}
static struct irda_platform_data assabet_irda_data = {
.set_power = assabet_irda_set_power,
.set_speed = assabet_irda_set_speed,
};
static void __init assabet_init(void)
{
/*
......@@ -203,6 +245,7 @@ static void __init assabet_init(void)
sa11x0_set_flash_data(&assabet_flash_data, assabet_flash_resources,
ARRAY_SIZE(assabet_flash_resources));
sa11x0_set_irda_data(&assabet_irda_data);
}
/*
......
......@@ -283,6 +283,16 @@ void sa11x0_set_flash_data(struct flash_platform_data *flash,
sa11x0mtd_device.num_resources = nr;
}
static struct platform_device sa11x0ir_device = {
.name = "sa11x0-ir",
.id = -1,
};
void sa11x0_set_irda_data(struct irda_platform_data *irda)
{
sa11x0ir_device.dev.platform_data = irda;
}
static struct platform_device *sa11x0_devices[] __initdata = {
&sa11x0udc_device,
&sa11x0uart1_device,
......@@ -298,6 +308,9 @@ static int __init sa1100_init(void)
{
pm_power_off = sa1100_power_off;
if (sa11x0ir_device.dev.platform_data)
platform_device_register(&sa11x0ir_device);
return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
}
......
......@@ -33,3 +33,6 @@ struct resource;
extern void sa11x0_set_flash_data(struct flash_platform_data *flash,
struct resource *res, int nr);
struct irda_platform_data;
void sa11x0_set_irda_data(struct irda_platform_data *irda);
......@@ -38,6 +38,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/irda.h>
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
......@@ -119,9 +120,34 @@ static struct resource h3xxx_flash_resource = {
.flags = IORESOURCE_MEM,
};
/*
* This turns the IRDA power on or off on the Compaq H3600
*/
static int h3600_irda_set_power(struct device *dev, unsigned int state)
{
assign_h3600_egpio( IPAQ_EGPIO_IR_ON, state );
return 0;
}
static void h3600_irda_set_speed(struct device *dev, int speed)
{
if (speed < 4000000) {
clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
} else {
set_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
}
}
static struct irda_platform_data h3600_irda_data = {
.set_power = h3600_irda_set_power,
.set_speed = h3600_irda_set_speed,
};
static void h3xxx_mach_init(void)
{
sa11x0_set_flash_data(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
sa11x0_set_irda_data(&h3600_irda_data);
}
/*
......
......@@ -39,19 +39,7 @@
#include <asm/irq.h>
#include <asm/dma.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/arch/assabet.h>
#include <asm/arch/h3600.h>
#include <asm/arch/yopy.h>
#ifndef GPIO_IRDA_FIR
#define GPIO_IRDA_FIR (0)
#endif
#ifndef GPIO_IRDA_POWER
#define GPIO_IRDA_POWER (0)
#endif
#include <asm/mach/irda.h>
static int power_level = 3;
static int tx_lpm;
......@@ -75,6 +63,7 @@ struct sa1100_irda {
struct net_device_stats stats;
struct device *dev;
struct irda_platform_data *pdata;
struct irlap_cb *irlap;
struct qos_info qos;
......@@ -170,12 +159,8 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
if (machine_is_assabet())
ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
if (machine_is_h3xxx())
clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
if (machine_is_yopy())
PPSR &= ~GPIO_IRDA_FIR;
if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
si->speed = speed;
......@@ -194,12 +179,8 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
si->speed = speed;
if (machine_is_assabet())
ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
if (machine_is_h3xxx())
set_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
if (machine_is_yopy())
PPSR |= GPIO_IRDA_FIR;
if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
sa1100_irda_rx_alloc(si);
sa1100_irda_rx_dma_start(si);
......@@ -215,51 +196,6 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
return ret;
}
/*
* This sets the IRDA power level on the Assabet.
*/
static inline int
sa1100_irda_set_power_assabet(struct sa1100_irda *si, unsigned int state)
{
static unsigned int bcr_state[4] = {
ASSABET_BCR_IRDA_MD0,
ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0,
ASSABET_BCR_IRDA_MD1,
0
};
if (state < 4) {
state = bcr_state[state];
ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1|
ASSABET_BCR_IRDA_MD0));
ASSABET_BCR_set(state);
}
return 0;
}
/*
* This turns the IRDA power on or off on the Compaq H3600
*/
static inline int
sa1100_irda_set_power_h3600(struct sa1100_irda *si, unsigned int state)
{
assign_h3600_egpio( IPAQ_EGPIO_IR_ON, state );
return 0;
}
/*
* This turns the IRDA power on or off on the Yopy
*/
static inline int
sa1100_irda_set_power_yopy(struct sa1100_irda *si, unsigned int state)
{
if (state)
PPSR &= ~GPIO_IRDA_POWER;
else
PPSR |= GPIO_IRDA_POWER;
return 0;
}
/*
* Control the power state of the IrDA transmitter.
* State:
......@@ -274,14 +210,8 @@ static int
__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
{
int ret = 0;
if (machine_is_assabet())
ret = sa1100_irda_set_power_assabet(si, state);
if (machine_is_h3xxx())
ret = sa1100_irda_set_power_h3600(si, state);
if (machine_is_yopy())
ret = sa1100_irda_set_power_yopy(si, state);
if (si->pdata->set_power)
ret = si->pdata->set_power(si->dev, state);
return ret;
}
......@@ -304,11 +234,8 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
/*
* Ensure that the ports for this device are setup correctly.
*/
if (machine_is_yopy()) {
PPDR |= GPIO_IRDA_POWER | GPIO_IRDA_FIR;
PPSR |= GPIO_IRDA_POWER | GPIO_IRDA_FIR;
PSDR |= GPIO_IRDA_POWER | GPIO_IRDA_FIR;
}
if (si->pdata->startup)
si->pdata->startup(si->dev);
/*
* Configure PPC for IRDA - we want to drive TXD2 low.
......@@ -333,10 +260,15 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
ret = sa1100_irda_set_speed(si, si->speed = 9600);
if (ret)
return ret;
if (ret) {
Ser2UTCR3 = 0;
Ser2HSCR0 = 0;
return 0;
if (si->pdata->shutdown)
si->pdata->shutdown(si->dev);
}
return ret;
}
static void sa1100_irda_shutdown(struct sa1100_irda *si)
......@@ -350,6 +282,9 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
/* Disable the port. */
Ser2UTCR3 = 0;
Ser2HSCR0 = 0;
if (si->pdata->shutdown)
si->pdata->shutdown(si->dev);
}
#ifdef CONFIG_PM
......@@ -959,6 +894,9 @@ static int sa1100_irda_probe(struct device *_dev)
unsigned int baudrate_mask;
int err;
if (!pdev->dev.platform_data)
return -EINVAL;
err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY;
if (err)
goto err_mem_1;
......@@ -975,6 +913,7 @@ static int sa1100_irda_probe(struct device *_dev)
si = dev->priv;
si->dev = &pdev->dev;
si->pdata = pdev->dev.platform_data;
/*
* Initialise the HP-SIR buffers
......@@ -1028,7 +967,7 @@ static int sa1100_irda_probe(struct device *_dev)
err = register_netdev(dev);
if (err == 0)
dev_set_drvdata(&pdev->dev, si);
dev_set_drvdata(&pdev->dev, dev);
if (err) {
err_mem_5:
......@@ -1074,15 +1013,8 @@ static struct device_driver sa1100ir_driver = {
.resume = sa1100_irda_resume,
};
static struct platform_device sa1100ir_device = {
.name = "sa11x0-ir",
.id = 0,
};
static int __init sa1100_irda_init(void)
{
int ret;
/*
* Limit power level a sensible range.
*/
......@@ -1091,19 +1023,12 @@ static int __init sa1100_irda_init(void)
if (power_level > 3)
power_level = 3;
ret = driver_register(&sa1100ir_driver);
if (ret == 0) {
ret = platform_device_register(&sa1100ir_device);
if (ret)
driver_unregister(&sa1100ir_driver);
}
return ret;
return driver_register(&sa1100ir_driver);
}
static void __exit sa1100_irda_exit(void)
{
driver_unregister(&sa1100ir_driver);
platform_device_unregister(&sa1100ir_device);
}
module_init(sa1100_irda_init);
......
/*
* linux/include/asm-arm/mach/irda.h
*
* Copyright (C) 2004 Russell King.
*
* 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.
*/
#ifndef __ASM_ARM_MACH_IRDA_H
#define __ASM_ARM_MACH_IRDA_H
struct irda_platform_data {
int (*startup)(struct device *);
void (*shutdown)(struct device *);
int (*set_power)(struct device *, unsigned int state);
void (*set_speed)(struct device *, int speed);
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment