rendered paste bodyIndex: Kconfig
===================================================================
RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/htcblueangel/Kconfig,v
retrieving revision 1.8
diff -u -r1.8 Kconfig
--- Kconfig 17 Dec 2006 12:23:37 -0000 1.8
+++ Kconfig 30 Dec 2006 19:53:03 -0000
@@ -46,10 +46,6 @@
Support for function keys
Pull-out keyboard not yet working
-menuconfig MACH_BLUEANGEL_AUDIO
- tristate "HTC Blueangel audio support"
- depends on MACH_BLUEANGEL
-
menuconfig MACH_BLUEANGEL_BATTERY
tristate "HTC Blueangel battery support"
depends on MACH_BLUEANGEL
@@ -68,7 +64,12 @@
---help---
Required for using data transfer via GPRS, CSD and FAX
+menuconfig MACH_BLUEANGEL_TSC2200
+ tristate "HTC Blueangel tsc2200 support"
+ depends on MACH_BLUEANGEL
+ ---help---
+ Required for using tsc2200
+
config MACH_BLUEANGEL_UDC
bool "HTC Blueangel UDC support"
depends on MACH_BLUEANGEL
-
Index: Makefile
===================================================================
RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/htcblueangel/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- Makefile 17 Dec 2006 12:23:37 -0000 1.7
+++ Makefile 30 Dec 2006 19:53:03 -0000
@@ -3,7 +3,7 @@
#
obj-$(CONFIG_MACH_BLUEANGEL) += blueangel.o
-obj-$(CONFIG_MACH_BLUEANGEL) += blueangel_tsc2200.o
+obj-$(CONFIG_MACH_BLUEANGEL_TSC2200) += blueangel_tsc2200.o
obj-$(CONFIG_MACH_BLUEANGEL_LCD) += blueangel_lcd.o
obj-$(CONFIG_MACH_BLUEANGEL_DS1WM) += blueangel_ds1wm.o
obj-$(CONFIG_MACH_BLUEANGEL_BACKLIGHT) += blueangel_bl.o
@@ -16,3 +16,4 @@
obj-$(CONFIG_MACH_BLUEANGEL_ROM) += blueangel_rom.o
obj-$(CONFIG_MACH_BLUEANGEL_DPRAM) += blueangel_dpram.o
obj-$(CONFIG_MACH_BLUEANGEL_UDC) += blueangel_udc.o
+obj-$(CONFIG_MACH_BLUEANGEL_DS1WM) += blueangel_ds1wm.o
Index: blueangel_battery.c
===================================================================
RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/htcblueangel/blueangel_battery.c,v
retrieving revision 1.5
diff -u -r1.5 blueangel_battery.c
--- blueangel_battery.c 22 Dec 2006 03:57:06 -0000 1.5
+++ blueangel_battery.c 30 Dec 2006 19:53:04 -0000
@@ -12,6 +12,8 @@
#include <linux/version.h>
#include <linux/battery.h>
#include <linux/leds.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/soc/asic3_base.h>
#include <linux/platform_device.h>
@@ -23,15 +25,54 @@
#include <linux/soc/tsc2200.h>
+#include "../../../../drivers/w1/w1.h"
+#include "../../../../drivers/w1/slaves/w1_ds2760.h"
+
#ifdef DEBUG
#define dprintk(x...) printk(x)
#else
#define dprintk(x...)
#endif
+#define BATTERY_CHECK_INTERVAL (HZ * 60) /* every 60 seconds */
+
+#define BLUEANGEL_BATTERY_MAX_VOLTAGE 4400 /* My measurements */
+#define BLUEANGEL_BATTERY_MIN_VOLTAGE 0 /* Maybe incorrect */
+#define BLUEANGEL_BATTERY_MAX_CURRENT 950 /* MUST BE MEASURED */
+#define BLUEANGEL_BATTERY_MIN_CURRENT -950 /* Maybe incorrect */
+#define BLUEANGEL_BATTERY_MIN_CHARGE 0 /* Maybe incorrect */
+
+/* DS2760 device */
+struct device *ds2760_dev = NULL;
+
+/* Cache the battery status for this many seconds. */
+#define STATUS_CACHE_TIME (HZ * 1)
+static struct ds2760_status battery_status;
+
+
extern struct platform_device blueangel_tsc2200;
+extern struct platform_device blueangel_asic3;
+
DEFINE_LED_TRIGGER(ledtrig_cradle);
+DEFINE_LED_TRIGGER(ledtrig_phone);
+
+/* w1_samcop device */
+static struct workqueue_struct *probe_q;
+static struct work_struct probe_work;
+
+/* battery monitor */
+static struct timer_list monitor_timer;
+static struct workqueue_struct *monitor_q;
+static struct work_struct monitor_work;
+
+static int battery_charge_state;
+#define BATTERY_STATE_UNKNOWN 0
+#define BATTERY_DISCHARGING 1
+#define BATTERY_CHARGING 2
+#define BATTERY_FULL 3
+/* AC present? */
+static int power_status;
static void bat_tsc2200_start_conv_scan(void)
@@ -47,18 +88,6 @@
TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
}
-static void bat_tsc2200_start_conv_temp(void)
-{
- tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_REF, 31);
- tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC,
- TSC2200_CTRLREG_ADC_AD3 |
- TSC2200_CTRLREG_ADC_AD1 |
- TSC2200_CTRLREG_ADC_RES (TSC2200_CTRLREG_ADC_RES_12BITP) |
- TSC2200_CTRLREG_ADC_AVG (TSC2200_CTRLREG_ADC_8AVG) |
- TSC2200_CTRLREG_ADC_CL (TSC2200_CTRLREG_ADC_CL_2MHZ_12BIT) |
- TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
-}
-
static void bat_tsc2200_stop_conv(void)
{
tsc2200_write(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC,
@@ -70,6 +99,60 @@
TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
}
+int blueangel_battery_read_status(void)
+{
+ if (jiffies < (battery_status.update_time + STATUS_CACHE_TIME))
+ return 0;
+
+ if (!ds2760_dev)
+ return 0;
+
+ if (!w1_ds2760_status(ds2760_dev, &battery_status)) {
+ printk("call to w1_ds2760_status failed (0x%08x)\n",
+ (unsigned int)ds2760_dev);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+blueangel_battery_match_callback(struct device *dev, void *data)
+{
+ struct w1_slave *sl;
+
+ if (!(dev->driver && dev->driver->name &&
+ (strcmp(dev->driver->name, "w1_slave_driver") == 0)))
+ return 0;
+
+ sl = container_of(dev, struct w1_slave, dev);
+
+ /* DS2760 w1 slave device names begin with the family number 0x30. */
+ if (strncmp(sl->name, "30-", 3) != 0)
+ return 0;
+
+ return 1;
+}
+
+void
+blueangel_battery_probe_work(void *data)
+{
+ struct bus_type *bus;
+
+ /* Get the battery w1 slave device. */
+ bus = find_bus("w1");
+ if (bus)
+ ds2760_dev = bus_find_device(bus, NULL, NULL,
+ blueangel_battery_match_callback);
+
+ if (!ds2760_dev) {
+ /* No DS2760 device found; try again later. */
+ //queue_delayed_work(probe_q, &probe_work, HZ * 5);
+ return;
+ }
+}
+
+
static int blueangel_battery_get_status(struct battery *bat)
{
dprintk("%s: in.\n", __FUNCTION__);
@@ -108,116 +191,176 @@
static int blueangel_battery_get_voltage(struct battery *bat)
{
int retval;
-
- dprintk("%s: in.\n", __FUNCTION__);
-
- //down_interruptible(&tsc2200_sem);
- //tsc2200_lock(&blueangel_tsc2200.dev);
- bat_tsc2200_start_conv_scan();
-
- while ( !(tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC) & 0x4000) &&
- !tsc2200_dav(&blueangel_tsc2200.dev )) {
- dprintk("B2: %X\n", tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC));
- mdelay(1);
- }
-
- retval = tsc2200_read(&blueangel_tsc2200.dev, TSC2200_DATAREG_AUX2);
-
- bat_tsc2200_stop_conv();
- //tsc2200_unlock(&blueangel_tsc2200.dev);
- //up(&tsc2200_sem);
+ blueangel_battery_read_status();
+ retval = battery_status.voltage_mV;
return retval;
}
static int blueangel_battery_get_temp(struct battery *bat)
{
int retval;
+ blueangel_battery_read_status();
+ retval = battery_status.temp_C;
- dprintk("%s: in.\n", __FUNCTION__);
+ return retval;
+}
+blueangel_battery_get_max_voltage(struct battery *bat)
+{
+ return BLUEANGEL_BATTERY_MAX_VOLTAGE;
+}
- //down_interruptible(&tsc2200_sem);
- //tsc2200_lock(&blueangel_tsc2200.dev);
- bat_tsc2200_start_conv_temp();
+int
+blueangel_battery_get_min_voltage(struct battery *bat)
+{
+ return BLUEANGEL_BATTERY_MIN_VOLTAGE;
+}
- while ( !(tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC) & 0x4000) &&
- !tsc2200_dav(&blueangel_tsc2200.dev)) {
- dprintk("1: %X\n", tsc2200_read(&blueangel_tsc2200.dev, TSC2200_CTRLREG_ADC));
- mdelay(1);
- }
-
- retval = tsc2200_read(&blueangel_tsc2200.dev, TSC2200_DATAREG_TEMP1);
- dprintk("retval=0x%x\n", retval);
-
- bat_tsc2200_stop_conv();
- //tsc2200_unlock(&blueangel_tsc2200.dev);
- //up(&tsc2200_sem);
- dprintk("%s: out\n", __FUNCTION__);
- return retval;
+int
+blueangel_battery_get_max_current(struct battery *bat)
+{
+ return BLUEANGEL_BATTERY_MAX_CURRENT;
+}
+
+int
+blueangel_battery_get_min_current(struct battery *bat)
+{
+ return BLUEANGEL_BATTERY_MIN_CURRENT;
+}
+
+int
+blueangel_battery_get_current(struct battery *bat)
+{
+ blueangel_battery_read_status();
+ return battery_status.current_mA;
+}
+int
+blueangel_battery_get_max_charge(struct battery *bat)
+{
+ blueangel_battery_read_status();
+ return battery_status.rated_capacity;
}
+int
+blueangel_battery_get_min_charge(struct battery *bat)
+{
+ return BLUEANGEL_BATTERY_MIN_CHARGE;
+}
+
+int
+blueangel_battery_get_charge(struct battery *bat)
+{
+ blueangel_battery_read_status();
+ return battery_status.accum_current_mAh;
+}
+
+
struct battery battery_dev = {
- .name = "Main battery",
+ .name = "main",
.id = "battery0",
.get_voltage = blueangel_battery_get_voltage,
- .get_status = blueangel_battery_get_status,
- //.get_temp = blueangel_battery_get_temp,
+ .get_min_voltage = blueangel_battery_get_min_voltage,
+ .get_max_voltage = blueangel_battery_get_max_voltage,
+ .get_current = blueangel_battery_get_current,
+ .get_min_current = blueangel_battery_get_min_current,
+ .get_max_current = blueangel_battery_get_max_current,
+ .get_charge = blueangel_battery_get_charge,
+ .get_min_charge = blueangel_battery_get_min_charge,
+ .get_max_charge = blueangel_battery_get_max_charge,
+ .get_temp = blueangel_battery_get_temp,
+ .get_status = blueangel_battery_get_status,
+
};
struct battery battery_dev1 = {
- .name = "Backup battery",
+ .name = "backup",
.id = "battery1",
.get_voltage = blueangel_battery_get_voltage1,
.get_status = blueangel_battery_get_status,
- //.get_temp = blueangel_battery_get_tempi1,
};
+static irqreturn_t
+blueangel_ac_plug_isr (int isr, void *data)
+{
+
+ /* Update the LED status right away, for timely feedback. */
+ /* Set the proper charging rate. */
+ if (!(asic3_get_gpio_status_d(&blueangel_asic3.dev) & GPIOD_AC_CHARGER_N)) {
+ power_status = APM_AC_ONLINE;
+ }
+ if (!(GPLR(GPIO_NR_BLUEANGEL_USB_DETECT_N) & GPIO_bit(GPIO_NR_BLUEANGEL_USB_DETECT_N))) {
+ power_status = APM_AC_ONLINE;
+ }
+ if (power_status) {
+ /* Start off with a solid LED; if we're charging,
+ the LED state will be updated when the queued work runs. */
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_event(ledtrig_cradle, LED_FULL);
+ #endif
+ } else {
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_event(ledtrig_cradle, LED_OFF);
+ #endif
+ }
+
+ /* Force the data to be re-read. */
+ battery_status.update_time = 0;
+
+ /* Wait a few seconds to let the DS2760 update its current reading. */
+ queue_delayed_work(monitor_q, &monitor_work, HZ * 7);
+
+ return IRQ_HANDLED;
+}
+
+
static void
blueangel_battery_get_power_status (struct apm_power_info *info)
{
- int val;
- int val1;
- int full=0x8ea;
- int empty=0x8a3;
-
- int full1=0xb0f;
- int empty1=0x8a3;
- val=blueangel_battery_get_voltage(NULL);
- val1=blueangel_battery_get_voltage1(NULL);
-
- info->battery_life = (val1-empty)*100/(full-empty);
- if (info->battery_life < 0 || info->battery_life > 100)
- printk("battery voltage (0x%x) not within [0x%x,0x%x]. Please report.\n", val, full, empty);
- if (info->battery_life < 0)
- info->battery_life = 0;
- if (info->battery_life > 100)
- info->battery_life = 100;
+ blueangel_battery_read_status();
+
info->ac_line_status = APM_AC_OFFLINE;
- if (!(asic3_get_gpio_status_d(&blueangel_tsc2200.dev) & GPIOD_AC_CHARGER_N)) {
+ if (!(asic3_get_gpio_status_d(&blueangel_asic3.dev) & GPIOD_AC_CHARGER_N)) {
info->ac_line_status = APM_AC_ONLINE;
}
if (!(GPLR(GPIO_NR_BLUEANGEL_USB_DETECT_N) & GPIO_bit(GPIO_NR_BLUEANGEL_USB_DETECT_N))) {
info->ac_line_status = APM_AC_ONLINE;
}
- info->units=APM_UNITS_MINS;
- info->time = 360 * info->battery_life/100; /* time remaining */
- info->battery_flag = 0;
- if (info->ac_line_status == APM_AC_OFFLINE) {
+ power_status = info->ac_line_status;
+
+ if (info->ac_line_status == APM_AC_ONLINE && current > 0) {
#ifdef CONFIG_LEDS_TRIGGERS
- led_trigger_event(ledtrig_cradle, LED_OFF);
+ led_trigger_event(ledtrig_cradle, LED_FULL);
#endif
- info->battery_status = APM_BATTERY_STATUS_CRITICAL;
- if(info->battery_life > 5) {
- info->battery_status = APM_BATTERY_STATUS_LOW;
- }
- if(info->battery_life > 20) {
- info->battery_status = APM_BATTERY_STATUS_HIGH;
- }
- } else {
- info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ } else {
#ifdef CONFIG_LEDS_TRIGGERS
- led_trigger_event(ledtrig_cradle, LED_FULL);
+ led_trigger_event(ledtrig_cradle, LED_OFF);
#endif
- }
+
+ info->battery_status = battery_status.accum_current_mAh >
+ ((battery_status.rated_capacity * 75) / 100) ?
+ APM_BATTERY_STATUS_HIGH :
+ battery_status.accum_current_mAh >
+ ((battery_status.rated_capacity* 25) / 100) ?
+ APM_BATTERY_STATUS_LOW : APM_BATTERY_STATUS_CRITICAL;
+ }
+
+ info->battery_flag = info->battery_status;
+
+ if (battery_status.rated_capacity)
+ info->battery_life = (battery_status.accum_current_mAh * 100) /
+ battery_status.rated_capacity;
+
+ if (info->battery_life > 100)
+ info->battery_life = 100;
+ if (info->battery_life < 0)
+ info->battery_life = 0;
+
+ if (battery_status.current_mA) {
+ info->time = - ((battery_status.accum_current_mAh * 6000) /
+ battery_status.current_mA) / 100;
+ info->units = APM_UNITS_MINS;
+ } else
+ info->units = APM_UNITS_UNKNOWN;
}
static int bat_setup(void)
@@ -227,17 +370,131 @@
return 0;
}
-static int __init bat_init(void)
+static void
+blueangel_battery_timer(unsigned long data)
{
- bat_setup();
- blueangel_battery_get_voltage(NULL);
- blueangel_battery_get_voltage1(NULL);
- blueangel_battery_get_temp(NULL);
- apm_get_power_status = blueangel_battery_get_power_status;
+ queue_work(monitor_q, &monitor_work);
+ mod_timer(&monitor_timer, jiffies + BATTERY_CHECK_INTERVAL);
+}
+
+void
+blueangel_battery_update_status(void *data)
+{
+ static int full_counter;
+
+ blueangel_battery_read_status();
+
+ if (battery_charge_state == BATTERY_STATE_UNKNOWN)
+ full_counter = 0;
+
+ /* Set the proper charging rate. */
+ if (!(asic3_get_gpio_status_d(&blueangel_asic3.dev) & GPIOD_AC_CHARGER_N)) {
+ power_status = APM_AC_ONLINE;
+ }
+ if (!(GPLR(GPIO_NR_BLUEANGEL_USB_DETECT_N) & GPIO_bit(GPIO_NR_BLUEANGEL_USB_DETECT_N))) {
+ power_status = APM_AC_ONLINE;
+ }
+ if (power_status) {
+
+ asic3_set_gpio_out_c(&blueangel_asic3.dev,1 << GPIOC_CHARGER_MODE, 1 << GPIOC_CHARGER_MODE);
+
+ if (battery_status.current_mA > 10) {
+
+ battery_charge_state = BATTERY_CHARGING;
+ full_counter = 0;
+
+ } else if (battery_status.current_mA < 10 &&
+ battery_charge_state != BATTERY_FULL) {
+
+ /* Don't consider the battery to be full unless
+ * we've seen the current < 10 mA at least two
+ * consecutive times. */
+
+ full_counter++;
+
+ if (full_counter < 2)
+ battery_charge_state = BATTERY_CHARGING;
+ else {
+
+ unsigned char acr[2];
+
+ acr[0] = (battery_status.rated_capacity * 4) >> 8;
+ acr[1] = (battery_status.rated_capacity * 4) & 0xff;
+
+ if (w1_ds2760_write(ds2760_dev, acr,
+ DS2760_CURRENT_ACCUM_MSB, 2) < 2)
+ printk(KERN_ERR "ACR reset failed\n");
+ battery_charge_state = BATTERY_FULL;
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_event(ledtrig_phone, LED_FULL);
+ #endif
+ }
+ }
+
+ if (battery_charge_state == BATTERY_CHARGING) {
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_event(ledtrig_cradle, LED_FULL);
+ #endif
+ } else {
+
+ /* Set the LED solid while on AC and not charging. */
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_event(ledtrig_phone, LED_FULL);
+ led_trigger_event(ledtrig_cradle, LED_OFF);
+ #endif
+ }
+
+ } else {
+
+ battery_charge_state = BATTERY_DISCHARGING;
+ full_counter = 0;
+ asic3_set_gpio_out_c(&blueangel_asic3.dev,1 << GPIOC_CHARGER_MODE, 0);
+
+ /* Turn off the LED while unplugged from AC. */
#ifdef CONFIG_LEDS_TRIGGERS
- led_trigger_register_simple("charge", &ledtrig_cradle);
+ led_trigger_event(ledtrig_cradle, LED_OFF);
#endif
+ }
+
+}
+
+
+
+static int __init bat_init(void)
+{
+ bat_setup();
+
+ battery_charge_state = BATTERY_STATE_UNKNOWN;
+
+ /* Install an interrupt handler for AC plug/unplug. */
+ set_irq_type(IRQ_GPIO(GPIO_NR_BLUEANGEL_USB_DETECT_N), IRQT_BOTHEDGE);
+ request_irq(IRQ_GPIO(GPIO_NR_BLUEANGEL_USB_DETECT_N), blueangel_ac_plug_isr, SA_SAMPLE_RANDOM,
+ "AC plug", NULL);
+
+ /* Create a workqueue in which the battery monitor will run. */
+ monitor_q = create_singlethread_workqueue("battmon");
+ INIT_WORK(&monitor_work, blueangel_battery_update_status, NULL);
+
+ /* Create a timer to run the battery monitor every
+ BATTERY_CHECK_INTERVAL seconds. */
+ init_timer(&monitor_timer);
+ monitor_timer.function = blueangel_battery_timer;
+ monitor_timer.data = 0;
+ /* Start the first monitor task a few seconds from now. */
+ mod_timer(&monitor_timer, jiffies + HZ * 10);
+
+ apm_get_power_status = blueangel_battery_get_power_status;
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_register_simple("charge", &ledtrig_cradle);
+ led_trigger_register_simple("phone", &ledtrig_phone);
+ #endif
+
+ /* Get the DS2760 W1 device. */
+ probe_q = create_singlethread_workqueue("battmonprb");
+ INIT_WORK(&probe_work, blueangel_battery_probe_work, NULL);
+ blueangel_battery_probe_work(NULL);
+ //enable_irq(IRQ_GPIO(GPIO_NR_BLUEANGEL_USB_DETECT_N));
return 0;
}
@@ -246,14 +503,32 @@
apm_get_power_status = NULL;
battery_class_unregister(&battery_dev);
battery_class_unregister(&battery_dev1);
- #ifdef CONFIG_LEDS_TRIGGERS
- led_trigger_unregister_simple(ledtrig_cradle);
- #endif
+
+ disable_irq(IRQ_GPIO(GPIO_NR_BLUEANGEL_USB_DETECT_N));
+ free_irq(IRQ_GPIO(GPIO_NR_BLUEANGEL_USB_DETECT_N), NULL);
+
+
+ cancel_delayed_work(&monitor_work);
+ flush_workqueue(monitor_q);
+ destroy_workqueue(monitor_q);
+
+ cancel_delayed_work(&probe_work);
+ flush_workqueue(probe_q);
+ destroy_workqueue(probe_q);
+
+ if (ds2760_dev)
+ put_device(ds2760_dev);
+ #ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_event(ledtrig_phone, LED_OFF);
+ led_trigger_unregister_simple(ledtrig_phone);
+ led_trigger_event(ledtrig_cradle, LED_OFF);
+ led_trigger_unregister_simple(ledtrig_cradle);
+ #endif
}
module_init(bat_init)
module_exit(bat_exit)
MODULE_AUTHOR("Matthias Burghardt");
-MODULE_DESCRIPTION("Battery (TI TSC2200) support for the HTC Blueangel");
+MODULE_DESCRIPTION("Battery (TI TSC2200) and DS2760 upport for the HTC Blueangel");
MODULE_LICENSE("GPL");
Index: blueangel_ds1wm.c
===================================================================
RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/htcblueangel/blueangel_ds1wm.c,v
retrieving revision 1.5
diff -u -r1.5 blueangel_ds1wm.c
--- blueangel_ds1wm.c 17 Dec 2006 12:23:37 -0000 1.5
+++ blueangel_ds1wm.c 30 Dec 2006 19:53:04 -0000
@@ -36,7 +36,7 @@
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 0,
+// .start = 0,
.flags = IORESOURCE_IRQ,
}
@@ -75,9 +75,8 @@
int irq;
printk("HTC Blueangel DS1WM driver\n");
irq = asic3_irq_base(&blueangel_asic3.dev) + BLUEANGEL_OWM_IRQ;
-
- enable_irq(irq);
blueangel_ds1wm_resources[1].start = irq;
+ blueangel_ds1wm_resources[1].end = irq;
if (clk_register(&ds1wm_clk) < 0)
printk(KERN_ERR "failed to register DS1WM clock\n");
@@ -97,13 +96,14 @@
platform_device_put(blueangel_ds1wm);
printk("blueangel_ds1wm: failed to add platform device\n");
}
+ printk("HTC Blueangel DS1WM registered\n");
return ret;
}
static void blueangel_ds1wm_exit(void)
{
- disable_irq(asic3_irq_base(&blueangel_asic3.dev) + BLUEANGEL_OWM_IRQ);
+ //disable_irq(asic3_irq_base(&blueangel_asic3.dev) + BLUEANGEL_OWM_IRQ);
platform_device_del(blueangel_ds1wm);
}
Index: blueangel_lcd.c
===================================================================
RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/htcblueangel/blueangel_lcd.c,v
retrieving revision 1.8
diff -u -r1.8 blueangel_lcd.c
--- blueangel_lcd.c 21 Dec 2006 00:18:17 -0000 1.8
+++ blueangel_lcd.c 30 Dec 2006 19:53:04 -0000
@@ -221,7 +221,7 @@
.lcd_format = 0x00000003,
.lcdd_cntl1 = 0x00000000,
.lcdd_cntl2 = 0x0003ffff,
- .genlcd_cntl1 = 0x00fff003, // 0x00fff003
+ .genlcd_cntl1 = 0x00abf003, // 0x00fff003
.genlcd_cntl2 = 0x00000003,
.genlcd_cntl3 = 0x000102aa,
};
Index: blueangel_pcmcia.c
===================================================================
RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/htcblueangel/blueangel_pcmcia.c,v
retrieving revision 1.5
diff -u -r1.5 blueangel_pcmcia.c
--- blueangel_pcmcia.c 4 Dec 2006 02:23:51 -0000 1.5
+++ blueangel_pcmcia.c 30 Dec 2006 19:53:04 -0000
@@ -1,278 +1,170 @@
-/*
- * HTC Blueangel PCMCIA support
- *
- * Copyright (c) 2005 SDG Systems, LLC
- *
- * Based on code from iPAQ h2200
- * Copyright 2004 Koen Kooi <koen@vestingbar.nl>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
+ /*
+ * h4000_pcmcia.c
+ *
+ * Created Apr 2, 2005, by Shawn Anderson
+ *
+ * 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/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/soc-old.h>
-
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
-#include <asm/irq.h>
-
#include <asm/arch/pxa-regs.h>
-#include <asm/arch/htcblueangel-gpio.h>
-#include <asm/arch/htcblueangel-asic.h>
#include <asm/hardware/ipaq-asic3.h>
#include <linux/soc/asic3_base.h>
-
#include "../../../../drivers/pcmcia/soc_common.h"
+#include "../../../../drivers/pcmcia/pxa2xx_base.h"
+#include <asm/arch/htcblueangel-gpio.h>
+#include <asm/arch/htcblueangel-asic.h>
extern struct platform_device blueangel_asic3;
-/*
- * CF resources used on blueangel :
- *
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_POE_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PWE_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PIOR_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PIOW_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PCE1_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PCE2_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PREG_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PWAIT_N_MD);
- * pxa_gpio_mode(GPIO_NR_BLUEANGEL_PIOIS16_N_MD);
- */
-
-#if 0
-#define _debug(s, args...) printk (KERN_INFO s, ##args)
-#define _debug_func(s, args...) _debug ("%s: " s, __FUNCTION__, ##args)
-#else
-#define _debug(s, args...)
-#define _debug_func(s, args...) _debug ("%s: " s, __FUNCTION__, ##args)
-#endif
-
-#if 0
-static struct pcmcia_irqs blueangel_cd_irq[] = {
- { 0, 0, "PCMCIA CD" } /* fill in IRQ below */
-};
-#endif
+#define GET_BLUEANGEL_GPIO(gpio) \
+ (GPLR(GPIO_NR_BLUEANGEL_ ## gpio) & GPIO_bit(GPIO_NR_BLUEANGEL_ ## gpio))
+
+#define SET_BLUEANGEL_GPIO(gpio, setp) \
+do { \
+if (setp) \
+ GPSR( gpio) = GPIO_bit( gpio); \
+else \
+ GPCR( gpio) = GPIO_bit( gpio); \
+} while (0)
-static int power_en=0;
+static struct pcmcia_irqs irqs[] = {
+ {0, IRQ_GPIO(75), "PCMCIA0"},
+};
-static void
-blueangel_cf_reset( int state )
+static irqreturn_t acx_event(int irq, void* data, struct pt_regs *regs)
{
- printk("reset\n");
-#if 0
- _debug_func ("%d\n", state);
- SET_HX4700_GPIO( CF_RESET, state?1:0 );
-#endif
-}
+ struct acx_data *devdata = data;
-static int
-blueangel_pcmcia_hw_init( struct soc_pcmcia_socket *skt )
+ printk("acx receive irq pcmcia shared\n");
+
+ return IRQ_HANDLED;
+};
+static int htcblueangel_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- int statusd;
- int irq;
+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | GPIO_bit(GPIO49_nPWE) |
+ GPIO_bit(GPIO52_nPCE_1_MD) | GPIO_bit(GPIO53_nPCE_2_MD) |
+ GPIO_bit(GPIO55_nPREG_MD) | GPIO_bit(GPIO56_nPWAIT_MD);
- _debug_func ("\n");
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO52_nPCE_1_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(75 | GPIO_IN);
- printk("hw_init\n");
-#if 0
- /* Turn on sleep mode, I think */
- asic3_set_extcf_select(&blueangel_asic3.dev,
- ASIC3_EXTCF_CF_SLEEP | (ASIC3_EXTCF_CF0_SLEEP_MODE * 3) | ASIC3_EXTCF_CF0_BUF_EN | ASIC3_EXTCF_CF0_PWAIT_EN,
- ASIC3_EXTCF_CF_SLEEP | 0 | 0 | 0
- );
- mdelay(50);
-
- statusd = asic3_get_gpio_status_d( &blueangel_asic3.dev );
- power_en = (statusd & (1<<GPIOD_CF_CD_N)) ? 0 : 1;
-
- irq = hx4700_cd_irq[0].irq = asic3_irq_base( &hx4700_asic3.dev )
- + ASIC3_GPIOD_IRQ_BASE + GPIOD_CF_CD_N;
- skt->irq = HX4700_IRQ( CF_RNB );
-
- if (power_en) {
- hx4700_egpio_enable( EGPIO4_CF_3V3_ON );
- set_irq_type( irq, IRQT_RISING );
- }
- else {
- hx4700_egpio_disable( EGPIO4_CF_3V3_ON );
- set_irq_type( irq, IRQT_FALLING );
- }
+ asic3_set_clock_cdex(&blueangel_asic3.dev, CLOCK_CDEX_EX1, CLOCK_CDEX_EX1);
+ asic3_set_gpio_out_a(&blueangel_asic3.dev, 1 << GPIOA_WLAN_RESET,
+ 1 << GPIOA_WLAN_RESET);
+ asic3_set_gpio_out_a(&blueangel_asic3.dev, 1 << GPIOA_WLAN_RESET, 0);
- pxa_gpio_mode(GPIO_NR_HX4700_POE_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PWE_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PIOR_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PIOW_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PCE1_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PCE2_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PREG_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PWAIT_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PIOIS16_N_MD | GPIO_DFLT_HIGH);
- pxa_gpio_mode(GPIO_NR_HX4700_PSKTSEL_MD);
+ skt->irq = irqs[0].irq;
- return soc_pcmcia_request_irqs(skt, blueangel_cd_irq, ARRAY_SIZE(blueangel_cd_irq));
-#endif
- return 0;
+ return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
-/*
- * Release all resources.
- */
-static void
-blueangel_pcmcia_hw_shutdown( struct soc_pcmcia_socket *skt )
+static void htcblueangel_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- printk("shutdown\n");
-#if 0
- _debug_func ("\n");
- soc_pcmcia_free_irqs( skt, blueangel_cd_irq, ARRAY_SIZE(blueangel_cd_irq) );
-#endif
+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
-static void
-blueangel_pcmcia_socket_state( struct soc_pcmcia_socket *skt,
- struct pcmcia_state *state )
+static void htcblueangel_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
{
- int statusd;
-
- printk("socket_state\n");
- state->detect = 1;
- state->ready = 1;
- state->bvd1 = 1;
- state->bvd2 = 1;
+ state->detect = GET_BLUEANGEL_GPIO(WLAN_IRQ2_N) ? 1 : 0; // 1; // always attached
+ state->ready = 1; //GET_BLUEANGEL_GPIO(WLAN_IRQ2_N) ? 1 : 0;
+ state->bvd1 = 1;
+ state->bvd2 = 1;
state->wrprot = 0;
- state->vs_3v = 1;
- state->vs_Xv = 0;
-
-#if 0
- if (state->detect)
- asic3_set_gpio_status_c( &hx4700_asic3.dev, 1<<GPIOC_CIOR_N,
- 1<<GPIOC_CIOR_N );
- else
- asic3_set_gpio_status_c( &hx4700_asic3.dev, 1<<GPIOC_CIOR_N, 0 );
-#endif
-
- _debug( "detect:%d ready:%d vcc:%d\n",
- state->detect, state->ready, state->vs_3v );
-}
+ state->vs_3v = asic3_get_gpio_status_a(&blueangel_asic3.dev)
+ & (1 << GPIOA_WLAN_PWR2);
+ state->vs_Xv = 0;
+};
-static int
-blueangel_pcmcia_config_socket( struct soc_pcmcia_socket *skt,
- const socket_state_t *state )
+static int htcblueangel_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t * state)
{
- int statusc;
-
-#if 0
- statusc = asic3_get_gpio_status_c( &hx4700_asic3.dev );
-#endif
- printk("config_socket\n");
- /* Silently ignore Vpp, output enable, speaker enable. */
- _debug_func( "Reset:%d Vcc:%d Astatusc=0x%x\n",
- (state->flags & SS_RESET) ? 1 : 0, state->Vcc,
- statusc );
-
-#if 0
- blueangel_cf_reset( state->flags & SS_RESET );
- if (state->Vcc == 0) {
- /* Turn on sleep mode, I think. No docs for these bits. */
- asic3_set_extcf_select(&blueangel_asic3.dev,
- ASIC3_EXTCF_CF_SLEEP | (ASIC3_EXTCF_CF0_SLEEP_MODE * 3) | ASIC3_EXTCF_CF0_BUF_EN | ASIC3_EXTCF_CF0_PWAIT_EN,
- ASIC3_EXTCF_CF_SLEEP | 0 | 0 | 0
- );
- blueangel_egpio_disable( EGPIO4_CF_3V3_ON );
- power_en = 0;
- }
- else if (state->Vcc == 33 || state->Vcc == 50) {
- blueangel_egpio_enable( EGPIO4_CF_3V3_ON );
- mdelay(1);
- /* Turn on CF stuff without messing with SD bit 14. */
- asic3_set_extcf_select(&blueangel_asic3.dev,
- ASIC3_EXTCF_CF_SLEEP | (ASIC3_EXTCF_CF0_SLEEP_MODE * 3) | ASIC3_EXTCF_CF0_BUF_EN | ASIC3_EXTCF_CF0_PWAIT_EN,
- 0 | (ASIC3_EXTCF_CF0_SLEEP_MODE * 2) | ASIC3_EXTCF_CF0_BUF_EN | ASIC3_EXTCF_CF0_PWAIT_EN
- );
- power_en = 1;
+ switch (state->Vcc) {
+ case 0:
+ asic3_set_gpio_out_a(&blueangel_asic3.dev, 1 << GPIOA_WLAN_PWR1,
+ 1 << GPIOA_WLAN_PWR1);
+ asic3_set_gpio_out_a(&blueangel_asic3.dev, 1 << GPIOA_WLAN_PWR2,
+ 1 << GPIOA_WLAN_PWR2);
+ break;
+ case 50:
+ case 33:
+ asic3_set_gpio_out_a(&blueangel_asic3.dev, 1 << GPIOA_WLAN_PWR1,
+ 1 << GPIOA_WLAN_PWR1);
+ asic3_set_gpio_out_a(&blueangel_asic3.dev, 1 << GPIOA_WLAN_PWR2,
+ 1 << GPIOA_WLAN_PWR2);
+ break;
+ default:
+ printk(KERN_ERR "%s: Unsupported Vcc:%d\n", __FUNCTION__,
+ state->Vcc);
}
- else {
- printk (KERN_ERR "%s: Unsupported Vcc:%d\n",
- __FUNCTION__, state->Vcc);
- }
-#endif
return 0;
+
}
-/*
- * Enable card status IRQs on (re-)initialisation. This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void
-blueangel_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+static void htcblueangel_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
- printk("socket_init\n");
-#if 0
- _debug_func ("\n");
- blueangel_cf_reset(0);
-#endif
+ soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
-/*
- * Disable card status IRQs on suspend.
- */
-static void
-blueangel_pcmcia_socket_suspend( struct soc_pcmcia_socket *skt )
+static void htcblueangel_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
- printk("socket_suspend\n");
-#if 0
- _debug_func ("\n");
- blueangel_cf_reset(1);
-#endif
+ soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
-static struct pcmcia_low_level blueangel_pcmcia_ops = {
- .owner = THIS_MODULE,
- .nr = 1,
- .hw_init = blueangel_pcmcia_hw_init,
- .hw_shutdown = blueangel_pcmcia_hw_shutdown,
- .socket_state = blueangel_pcmcia_socket_state,
- .configure_socket = blueangel_pcmcia_config_socket,
- .socket_init = blueangel_pcmcia_socket_init,
- .socket_suspend = blueangel_pcmcia_socket_suspend,
+static struct pcmcia_low_level htcblueangel_pcmcia_ops = {
+ .owner = THIS_MODULE,
+ .first = 0,
+ .nr = 1,
+ .hw_init = htcblueangel_pcmcia_hw_init,
+ .hw_shutdown = htcblueangel_pcmcia_hw_shutdown,
+ .socket_state = htcblueangel_pcmcia_socket_state,
+ .configure_socket = htcblueangel_pcmcia_configure_socket,
+ .socket_init = htcblueangel_pcmcia_socket_init,
+ .socket_suspend = htcblueangel_pcmcia_socket_suspend,
+ .set_timing = pxa2xx_pcmcia_set_timing,
};
-static struct platform_device blueangel_pcmcia_device = {
- .name = "pxa2xx-pcmcia",
- .dev = {
- .platform_data = &blueangel_pcmcia_ops,
- }
+static struct platform_device htcblueangel_pcmcia = {
+ .name = "pxa2xx-pcmcia",
+ .dev = {.platform_data = &htcblueangel_pcmcia_ops},
};
-static int __init
-blueangel_pcmcia_init(void)
+static int __init htcblueangel_pcmcia_probe(struct platform_device *pdev)
{
- _debug_func ("\n");
+ return platform_device_register(&htcblueangel_pcmcia);
+}
- return platform_device_register( &blueangel_pcmcia_device );
+static struct platform_driver htcblueangel_pcmcia_driver = {
+ .driver = {
+ .name = "htcblueangel_pcmcia",
+ },
+ .probe = htcblueangel_pcmcia_probe,
+};
+
+static int __init htcblueangel_pcmcia_init(void)
+{
+ return platform_driver_register(&htcblueangel_pcmcia_driver);
}
-static void __exit
-blueangel_pcmcia_exit(void)
+static void __exit htcblueangel_pcmcia_exit(void)
{
- platform_device_unregister( &blueangel_pcmcia_device );
+ platform_device_unregister(&htcblueangel_pcmcia);
+ platform_driver_unregister(&htcblueangel_pcmcia_driver);
}
-module_init(blueangel_pcmcia_init);
-module_exit(blueangel_pcmcia_exit);
+module_init(htcblueangel_pcmcia_init);
+module_exit(htcblueangel_pcmcia_exit);
-MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
-MODULE_DESCRIPTION("HTC Blueangel PCMCIA/CF platform-specific driver");
MODULE_LICENSE("GPL");
-
-/* vim600: set noexpandtab sw=8 ts=8 :*/
-