diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 093106e0..9669f390 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -118,7 +118,7 @@ obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-spi.o board-htcleo-pane obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-ts.o board-htcleo-mmc.o ieee754-df.o board-htcleo-power.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-battery.o board-htcleo-log.o board-htcleo-audio.o board-htcleo-acoustic.o -obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-rfkill.o board-htcleo-wifi.o board-htcleo-microp.o +obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-bt.o board-htcleo-wifi.o board-htcleo-microp.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-proximity.o board-htcleo-leds.o board-htcleo-ls.o obj-$(CONFIG_MACH_HTCLEO) += clock-wince.o obj-$(CONFIG_HTCLEO_BACKLIGHT) += board-htcleo-bl.o diff --git a/arch/arm/mach-msm/board-htcleo-audio.c b/arch/arm/mach-msm/board-htcleo-audio.c index c92ce2de..c9f0be93 100644 --- a/arch/arm/mach-msm/board-htcleo-audio.c +++ b/arch/arm/mach-msm/board-htcleo-audio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "board-htcleo.h" #include "devices.h" @@ -318,12 +319,21 @@ static struct q6audio_analog_ops ops = .get_rx_vol = htcleo_get_rx_vol, }; +static void hs_mic_register(void) +{ + struct headset_notifier notifier; + notifier.id = HEADSET_REG_MIC_BIAS; + notifier.func = htcleo_mic_enable; + headset_notifier_register(¬ifier); +} + void __init htcleo_audio_init(void) { mutex_init(&mic_lock); mutex_init(&bt_sco_lock); q6audio_register_analog_ops(&ops); acoustic_register_ops(&acoustic); + hs_mic_register(); // q6audio_set_acdb_file("default_PMIC.acdb"); } diff --git a/arch/arm/mach-msm/board-htcleo-ls.c b/arch/arm/mach-msm/board-htcleo-ls.c index 49a9f442..6595d660 100644 --- a/arch/arm/mach-msm/board-htcleo-ls.c +++ b/arch/arm/mach-msm/board-htcleo-ls.c @@ -81,7 +81,7 @@ static void map_adc_to_level(uint32_t adc, uint32_t *value) if (adc > 1024) { - pr_err("map_adc_to_level: adc > 1024\n"); + pr_err("%s: adc > 1024\n", __func__); *value = 5; // set some good value at error return; } @@ -90,7 +90,7 @@ static void map_adc_to_level(uint32_t adc, uint32_t *value) { if (adc >= lsensor_adc_table[i]) { - D("map_adc_to_level: %d -> %d\n", adc, i); + D("%s: %d -> %d\n", __func__, adc, i); *value = i; return; } @@ -124,7 +124,7 @@ static void lightsensor_poll_function(struct work_struct *work) struct lsensor_data* p = &the_data; uint32_t adc = 0, level = 0; - D("@@@lsensor poll\n"); + D("%s\n", __func__); if (!p->enabled) { D(" disable\n"); @@ -149,14 +149,19 @@ static void lightsensor_poll_function(struct work_struct *work) static int lightsensor_enable(void) { struct lsensor_data* p = &the_data; + int rc = -EIO; - D("@@@lightsensor_enable\n"); + D("%s\n", __func__); if (p->enabled) { pr_err("lsensor: already enabled\n"); return 0; } + rc = capella_cm3602_power(LS_PWR_ON, 1); + if (rc < 0) + return -EIO; + the_data.old_level = -1; p->enabled = 1; @@ -168,14 +173,18 @@ static int lightsensor_enable(void) static int lightsensor_disable(void) { struct lsensor_data* p = &the_data; + int rc = -EIO; - D("@@@lightsensor_disable\n"); + D("%s\n", __func__); if (!p->enabled) { pr_err("lsensor: nothing to disable\n"); return 0; } + rc = capella_cm3602_power(LS_PWR_ON, 0); + if (rc < 0) + return -EIO; p->enabled = 0; cancel_delayed_work_sync(&the_data.work); @@ -231,6 +240,7 @@ static long lightsensor_ioctl(struct file *file, unsigned int cmd, unsigned long rc = -EFAULT; break; } + pr_info("%s ls set to: %d\n", __func__, val); rc = val ? lightsensor_enable() : lightsensor_disable(); break; case LIGHTSENSOR_IOCTL_GET_ENABLED: @@ -264,8 +274,6 @@ struct miscdevice lightsensor_misc = ////////////////////////////////////////////////////////////////////////// - - static int lsensor_probe(struct platform_device *pdev) { int ret = -EIO; @@ -279,7 +287,7 @@ static int lsensor_probe(struct platform_device *pdev) /* Light Sensor */ /* ret = device_create_file(&the_data->dev, &dev_attr_ls_adc); - ret = device_create_file(&the_data->dev, &dev_attr_ls_auto); + ret = device_create_file(&pdev->dev, &dev_attr_ls_auto); */ input_dev = input_allocate_device(); if (!input_dev) @@ -315,9 +323,10 @@ static int lsensor_probe(struct platform_device *pdev) } the_data.old_level = -1; + the_data.enabled=0; + the_data.opened=0; INIT_DELAYED_WORK(&the_data.work, lightsensor_poll_function); - ret = 0; //lsensor_setup(); if (!ret) goto done; @@ -331,7 +340,7 @@ done: return ret; // device_remove_file(&client->dev, &dev_attr_ls_adc); - // device_remove_file(&client->dev, &dev_attr_ls_auto); + // device_remove_file(&pdev->dev, &dev_attr_ls_auto); } diff --git a/arch/arm/mach-msm/board-htcleo-microp.c b/arch/arm/mach-msm/board-htcleo-microp.c index 7a3584ee..403fdb63 100644 --- a/arch/arm/mach-msm/board-htcleo-microp.c +++ b/arch/arm/mach-msm/board-htcleo-microp.c @@ -46,6 +46,9 @@ #include "board-htcleo.h" static uint32_t microp_als_kadc; +static int als_power_control; +static DEFINE_MUTEX(capella_cm3602_lock); + extern void p_sensor_irq_handler(void); @@ -262,33 +265,46 @@ static int microp_read_gpi_status(struct i2c_client *client, uint16_t *status) return 0; } -static int microp_interrupt_enable(struct i2c_client *client, uint16_t interrupt_mask) +static int microp_interrupt_get_status(uint16_t *interrupt_mask) +{ + uint8_t data[2]; + int ret = -1; + + ret = microp_i2c_read(MICROP_I2C_RCMD_GPI_INT_STATUS, data, 2); + if (ret < 0) { + pr_err("%s: read interrupt status fail\n", __func__); + return ret; + } + + *interrupt_mask = data[0]<<8 | data[1]; + return 0; +} + +static int microp_interrupt_enable( uint16_t interrupt_mask) { uint8_t data[2]; int ret = -1; data[0] = interrupt_mask >> 8; data[1] = interrupt_mask & 0xFF; - ret = i2c_write_block(client, MICROP_I2C_WCMD_GPI_INT_CTL_EN, data, 2); + ret = microp_i2c_write(MICROP_I2C_WCMD_GPI_INT_CTL_EN, data, 2); if (ret < 0) - dev_err(&client->dev, "%s: enable 0x%x interrupt failed\n", - __func__, interrupt_mask); + pr_err("%s: enable 0x%x interrupt failed\n", __func__, interrupt_mask); return ret; } -static int microp_interrupt_disable(struct i2c_client *client, uint16_t interrupt_mask) +static int microp_interrupt_disable(uint16_t interrupt_mask) { uint8_t data[2]; int ret = -1; data[0] = interrupt_mask >> 8; data[1] = interrupt_mask & 0xFF; - ret = i2c_write_block(client, MICROP_I2C_WCMD_GPI_INT_CTL_DIS, data, 2); + ret = microp_i2c_write(MICROP_I2C_WCMD_GPI_INT_CTL_DIS, data, 2); if (ret < 0) - dev_err(&client->dev, "%s: disable 0x%x interrupt failed\n", - __func__, interrupt_mask); + pr_err("%s: disable 0x%x interrupt failed\n", __func__, interrupt_mask); return ret; } @@ -351,6 +367,68 @@ int microp_gpo_disable(uint16_t interrupt_mask) } EXPORT_SYMBOL(microp_gpo_disable); +/* + * CM3602 Power for LS and Proximity +*/ +int __capella_cm3602_power(int on) +{ + int rc; + printk(KERN_DEBUG "%s: Turn the capella_cm3602 power %s\n", + __func__, (on) ? "on" : "off"); + if (on) { + rc = microp_gpo_enable(GPO_CM3602); + if (rc < 0) + return -EIO; + } else { + rc = microp_gpo_disable(GPO_CM3602); + if (rc < 0) + return -EIO; + } + return 0; +} + + +int capella_cm3602_power(int pwr_device, uint8_t enable) +{ + unsigned int old_status = 0; + uint16_t interrupts = 0; + int ret = 0, on = 0; + mutex_lock(&capella_cm3602_lock); + if(pwr_device==PS_PWR_ON) { // Switch the Proximity IRQ + if(enable) { + ret = microp_interrupt_get_status(&interrupts); + if (ret < 0) { + pr_err("%s: read interrupt status fail\n", __func__); + return ret; + } + interrupts |= IRQ_PROXIMITY; + ret = microp_interrupt_enable(interrupts); + } + else { + interrupts |= IRQ_PROXIMITY; + ret = microp_interrupt_disable(interrupts); + } + if (ret < 0) { + pr_err("%s: failed to enable gpi irqs\n", __func__); + return ret; + } + } + + old_status = als_power_control; + if (enable) + als_power_control |= pwr_device; + else + als_power_control &= ~pwr_device; + + on = als_power_control ? 1 : 0; + if (old_status == 0 && on) + ret = __capella_cm3602_power(1); + else if (!on) + ret = __capella_cm3602_power(0); + + mutex_unlock(&capella_cm3602_lock); + return ret; +} /* * Interrupt @@ -376,26 +454,25 @@ static void microp_i2c_intr_work_func(struct work_struct *work) struct i2c_client *client; struct microp_i2c_client_data *cdata; uint8_t data[3]; - uint16_t intr_status = 0, gpi_status = 0; + uint16_t intr_status = 0; int ret = 0; up_work = container_of(work, struct microp_i2c_work, work); client = up_work->client; cdata = i2c_get_clientdata(client); - ret = i2c_read_block(client, MICROP_I2C_RCMD_GPI_INT_STATUS, data, 2); + ret = microp_interrupt_get_status(&intr_status); if (ret < 0) { dev_err(&client->dev, "%s: read interrupt status fail\n", __func__); } - intr_status = data[0]<<8 | data[1]; ret = i2c_write_block(client, MICROP_I2C_WCMD_GPI_INT_STATUS_CLR, data, 2); if (ret < 0) { dev_err(&client->dev, "%s: clear interrupt status fail\n", __func__); } - pr_debug("intr_status=0x%02x\n", intr_status); + pr_info("intr_status=0x%02x\n", intr_status); if (intr_status & IRQ_PROXIMITY) { p_sensor_irq_handler(); @@ -413,10 +490,8 @@ static int microp_function_initialize(struct i2c_client *client) cdata = i2c_get_clientdata(client); - interrupts |= IRQ_PROXIMITY; - /* enable the interrupts */ - ret = microp_interrupt_enable(client, interrupts); + ret = microp_interrupt_enable(interrupts); if (ret < 0) { dev_err(&client->dev, "%s: failed to enable gpi irqs\n", __func__); diff --git a/arch/arm/mach-msm/board-htcleo-mmc.c b/arch/arm/mach-msm/board-htcleo-mmc.c index 03d2c7c3..a4f78f0c 100644 --- a/arch/arm/mach-msm/board-htcleo-mmc.c +++ b/arch/arm/mach-msm/board-htcleo-mmc.c @@ -241,20 +241,15 @@ int htcleo_wifi_power(int on) if (on) { config_gpio_table(wifi_on_gpio_table,ARRAY_SIZE(wifi_on_gpio_table)); mdelay(50); - pmic_glb_set_vreg(on, wlan_vreg_1); - pmic_glb_set_vreg(on, wlan_vreg_2); - pmic_glb_set_vreg(on, wlan_vreg_3); - mdelay(100); } else { config_gpio_table(wifi_off_gpio_table, ARRAY_SIZE(wifi_off_gpio_table)); mdelay(100); } + pmic_glb_set_vreg(on, wlan_vreg_3); - printk("%s: VREGS %d\n", __func__, on); mdelay(100); - printk("%s: GPIO %d\n", __func__, on); gpio_set_value(HTCLEO_GPIO_WIFI_SHUTDOWN_N, on); /* WIFI_SHUTDOWN */ - mdelay(1000); + mdelay(100); htcleo_wifi_power_state = on; return 0; diff --git a/arch/arm/mach-msm/board-htcleo-proximity.c b/arch/arm/mach-msm/board-htcleo-proximity.c index 7a940da2..0242e9ff 100644 --- a/arch/arm/mach-msm/board-htcleo-proximity.c +++ b/arch/arm/mach-msm/board-htcleo-proximity.c @@ -81,7 +81,7 @@ static int capella_cm3602_enable(struct capella_cm3602_data *data) input_report_abs(data->input_dev, ABS_DISTANCE, -1); input_sync(data->input_dev); - rc = microp_gpo_enable(GPO_PROXIMITY); + rc = capella_cm3602_power(PS_PWR_ON, 1); if (rc < 0) return -EIO; @@ -99,7 +99,7 @@ static int capella_cm3602_disable(struct capella_cm3602_data *data) return 0; } - rc = microp_gpo_disable(GPO_PROXIMITY); + rc = capella_cm3602_power(PS_PWR_ON, 0); if (rc < 0) return -EIO; diff --git a/arch/arm/mach-msm/board-htcleo-rfkill.c b/arch/arm/mach-msm/board-htcleo-rfkill.c deleted file mode 100644 index df0bbefc..00000000 --- a/arch/arm/mach-msm/board-htcleo-rfkill.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* Control bluetooth power for htcleo platform */ - -#include -#include -#include -#include -#include -#include -#include - -#include "gpio_chip.h" -#include "proc_comm.h" -#include "board-htcleo.h" - -#define HTC_RFKILL_DBG - -static struct rfkill *bt_rfk; -static const char bt_name[] = "bcm4329"; -static int pre_state; - -static uint32_t htcleo_bt_init_table[] = { - /* BT_RTS */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_8MA), - /* BT_CTS */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, - 0, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_RX */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, - 0, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_TX */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_8MA), - - /* BT_SHUTDOWN_N */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_SHUTDOWN_N, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_4MA), - /* BT_RESET_N */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_RESET_N, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_4MA), - - /* BT_HOST_WAKE */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, - 0, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_4MA), - /* BT_CHIP_WAKE */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_4MA), -}; - -static uint32_t htcleo_bt_on_table[] = { - /* BT_RTS */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, - 2, - GPIO_OUTPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_CTS */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, - 2, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_RX */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, - 2, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_TX */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, - 2, - GPIO_OUTPUT, - GPIO_PULL_UP, - GPIO_8MA), - - /* BT_HOST_WAKE */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, - 0, - GPIO_INPUT, - GPIO_NO_PULL, - GPIO_4MA), - /* BT_CHIP_WAKE */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_4MA), -}; - -static uint32_t htcleo_bt_off_table[] = { - /* BT_RTS */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_8MA), - /* BT_CTS */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, - 0, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_RX */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, - 0, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_8MA), - /* BT_TX */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_8MA), - - /* BT_HOST_WAKE */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, - 0, - GPIO_INPUT, - GPIO_PULL_UP, - GPIO_4MA), - /* BT_CHIP_WAKE */ - PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, - 0, - GPIO_OUTPUT, - GPIO_NO_PULL, - GPIO_4MA), -}; - -static void config_bt_table(uint32_t *table, int len) -{ - int n; - unsigned id; - for (n = 0; n < len; n++) { - id = table[n]; - msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0); - } -} - -static void htcleo_config_bt_init(void) -{ - /* set bt initial configuration*/ - config_bt_table(htcleo_bt_init_table, - ARRAY_SIZE(htcleo_bt_init_table)); - /* BT_RESET_N */ - gpio_configure(HTCLEO_GPIO_BT_RESET_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - mdelay(5); - - /* BT_SHUTDOWN_N */ - gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); - /* BT_RESET_N */ - gpio_configure(HTCLEO_GPIO_BT_RESET_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); - mdelay(15); - - /* BT_RESET_N */ - gpio_configure(HTCLEO_GPIO_BT_RESET_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - /* BT_SHUTDOWN_N */ - gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - - /* BT_RTS */ - gpio_configure(HTCLEO_GPIO_BT_UART1_RTS, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - /* BT_TX */ - gpio_configure(HTCLEO_GPIO_BT_UART1_TX, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - - /* BT_CHIP_WAKE */ - gpio_configure(HTCLEO_GPIO_BT_CHIP_WAKE, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); -} - -static void htcleo_config_bt_on(void) -{ - - #ifdef HTC_RFKILL_DBG - printk(KERN_INFO "-- RK ON --\n"); - #endif - - /* set bt on configuration*/ - config_bt_table(htcleo_bt_on_table, - ARRAY_SIZE(htcleo_bt_on_table)); - mdelay(5); - /* BT_SHUTDOWN_N */ - gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); - /* BT_RESET_N */ - gpio_configure(HTCLEO_GPIO_BT_RESET_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); - mdelay(5); - - /* BT_CHIP_WAKE */ - gpio_configure(HTCLEO_GPIO_BT_CHIP_WAKE, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); -} - -static void htcleo_config_bt_off(void) -{ - #ifdef HTC_RFKILL_DBG - printk(KERN_INFO "-- RK OFF --\n"); - #endif - - /* BT_RESET_N */ - gpio_configure(HTCLEO_GPIO_BT_RESET_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - /* BT_SHUTDOWN_N */ - gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - - config_bt_table(htcleo_bt_off_table, - ARRAY_SIZE(htcleo_bt_off_table)); - mdelay(5); - - /* BT_RTS */ - gpio_configure(HTCLEO_GPIO_BT_UART1_RTS, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - /* BT_TX */ - gpio_configure(HTCLEO_GPIO_BT_UART1_TX, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); - - /* BT_CHIP_WAKE */ - gpio_configure(HTCLEO_GPIO_BT_CHIP_WAKE, - GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); -} - -static int bluetooth_set_power(void *data, bool blocked) -{ - if (pre_state == blocked) { - #ifdef HTC_RFKILL_DBG - printk(KERN_INFO "-- SAME ST --\n"); - #endif - return 0; - } else - pre_state = blocked; - - if (!blocked) - htcleo_config_bt_on(); - else - htcleo_config_bt_off(); - - return 0; -} - -static struct rfkill_ops htcleo_rfkill_ops = { - .set_block = bluetooth_set_power, -}; - -static int htcleo_rfkill_probe(struct platform_device *pdev) -{ - int rc = 0; - bool default_state = true; /* off */ - - htcleo_config_bt_init(); /* bt gpio initial config */ - - bluetooth_set_power(NULL, default_state); - - bt_rfk = rfkill_alloc(bt_name, &pdev->dev, RFKILL_TYPE_BLUETOOTH, - &htcleo_rfkill_ops, NULL); - if (!bt_rfk) { - rc = -ENOMEM; - goto err_rfkill_reset; - } - - rfkill_set_states(bt_rfk, default_state, false); - - /* userspace cannot take exclusive control */ - rc = rfkill_register(bt_rfk); - if (rc) - goto err_rfkill_reg; - - return 0; - -err_rfkill_reg: - rfkill_destroy(bt_rfk); -err_rfkill_reset: - return rc; -} - -static int htcleo_rfkill_remove(struct platform_device *dev) -{ - rfkill_unregister(bt_rfk); - rfkill_destroy(bt_rfk); - - return 0; -} - -static struct platform_driver htcleo_rfkill_driver = { - .probe = htcleo_rfkill_probe, - .remove = htcleo_rfkill_remove, - .driver = { - .name = "htcleo_rfkill", - .owner = THIS_MODULE, - }, -}; - -static int __init htcleo_rfkill_init(void) -{ - pre_state = -1; - if (!machine_is_htcleo()) - return 0; - - return platform_driver_register(&htcleo_rfkill_driver); -} - -static void __exit htcleo_rfkill_exit(void) -{ - platform_driver_unregister(&htcleo_rfkill_driver); -} - -module_init(htcleo_rfkill_init); -module_exit(htcleo_rfkill_exit); -MODULE_DESCRIPTION("htcleo rfkill"); -MODULE_AUTHOR("Nick Pelly "); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index 614c01c4..57e10d97 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -60,10 +60,16 @@ #include "proc_comm.h" #include "dex_comm.h" +#define ATAG_MAGLDR_BOOT 0x4C47414D +struct tag_magldr_entry +{ + _Bool fNoNandBoot; +}; + extern int __init htcleo_init_mmc(unsigned debug_uart); extern void __init htcleo_audio_init(void); extern unsigned char *get_bt_bd_ram(void); -static unsigned int nand_boot = 1; +static unsigned int nand_boot = 0; /////////////////////////////////////////////////////////////////////// @@ -74,13 +80,14 @@ int htcleo_is_nand_boot(void) return nand_boot; } -static int __init board_nandboot_setup(char *bootconfig) +static int __init parse_tag_nand_boot(const struct tag *tag) { - if (!strncmp(bootconfig, "0", 1)) - nand_boot=0; - return 1; + struct tag_magldr_entry *mentry = (struct tag_magldr_entry *)(&tag->u); + nand_boot = !(unsigned int)mentry->fNoNandBoot; + pr_info("Nand Boot: %d\n", nand_boot); + return 0; } -__setup("nand_boot=", board_nandboot_setup); +__tagtable(ATAG_MAGLDR_BOOT, parse_tag_nand_boot); /////////////////////////////////////////////////////////////////////// @@ -333,14 +340,6 @@ unsigned htcleo_get_vbus_state(void) #endif -static struct platform_device htcleo_rfkill = { - .name = "htcleo_rfkill", - .id = -1, -}; - - - - /////////////////////////////////////////////////////////////////////// // Flashlight /////////////////////////////////////////////////////////////////////// @@ -460,6 +459,8 @@ static int flashlight_control(int mode) static struct camera_flash_cfg msm_camera_sensor_flash_cfg = { .camera_flash = flashlight_control, .num_flash_levels = FLASHLIGHT_NUM, + .low_temp_limit = 5, + .low_cap_limit = 15, }; static struct msm_camera_sensor_info msm_camera_sensor_s5k3e2fx_data = @@ -484,6 +485,61 @@ static struct platform_device msm_camera_sensor_s5k3e2fx = }, }; +/////////////////////////////////////////////////////////////////////// +// bluetooth +/////////////////////////////////////////////////////////////////////// +static char bdaddress[20]; +static void bt_export_bd_address(void) + { + unsigned char cTemp[6]; + + memcpy(cTemp, get_bt_bd_ram(), 6); + sprintf(bdaddress, "%02x:%02x:%02x:%02x:%02x:%02x", cTemp[0], cTemp[1], cTemp[2], cTemp[3], cTemp[4], cTemp[5]); + pr_info("BD_ADDRESS=%s\n", bdaddress); +} + +module_param_string(bdaddress, bdaddress, sizeof(bdaddress), S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(bdaddress, "BT MAC ADDRESS"); + +static uint32_t bt_gpio_table[] = +{ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, 2, GPIO_INPUT, GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, 2, GPIO_INPUT, GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, 2, GPIO_OUTPUT,GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_RESET_N, 0, GPIO_OUTPUT,GPIO_PULL_DOWN, GPIO_4MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_SHUTDOWN_N, 0, GPIO_OUTPUT,GPIO_PULL_DOWN, GPIO_4MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, 0, GPIO_OUTPUT,GPIO_PULL_DOWN, GPIO_4MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, 0, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_4MA), +}; + +#ifdef CONFIG_SERIAL_MSM_HS +static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = +{ + /* Chip to Device */ + .rx_wakeup_irq = MSM_GPIO_TO_INT(HTCLEO_GPIO_BT_HOST_WAKE), + .inject_rx_on_wakeup = 0, + .cpu_lock_supported = 0, + + /* for bcm */ + .bt_wakeup_pin_supported = 1, + .bt_wakeup_pin = HTCLEO_GPIO_BT_CHIP_WAKE, + .host_wakeup_pin = HTCLEO_GPIO_BT_HOST_WAKE, + +}; +#endif + +static void __init htcleo_bt_init(void) +{ + config_gpio_table(bt_gpio_table, ARRAY_SIZE(bt_gpio_table)); +} + + +static struct platform_device htcleo_rfkill = +{ + .name = "htcleo_rfkill", + .id = -1, +}; /////////////////////////////////////////////////////////////////////// // KGSL (HW3D support)#include @@ -538,7 +594,7 @@ static struct platform_device msm_kgsl_device = // Memory /////////////////////////////////////////////////////////////////////// -static struct android_pmem_platform_data android_pmem_pdata = { +static struct android_pmem_platform_data mdp_pmem_pdata = { .name = "pmem", .no_allocator = 0, .cached = 1, @@ -550,19 +606,20 @@ static struct android_pmem_platform_data android_pmem_adsp_pdata = { .cached = 1, }; -static struct android_pmem_platform_data android_pmem_camera_pdata = { - .name = "pmem_camera", - .start = MSM_PMEM_CAMERA_BASE, - .size = MSM_PMEM_CAMERA_SIZE, - .no_allocator = 1, + +static struct android_pmem_platform_data android_pmem_venc_pdata = { + .name = "pmem_venc", + .start = MSM_PMEM_VENC_BASE, + .size = MSM_PMEM_VENC_SIZE, + .no_allocator = 0, .cached = 1, }; -static struct platform_device android_pmem_device = { +static struct platform_device android_pmem_mdp_device = { .name = "android_pmem", .id = 0, .dev = { - .platform_data = &android_pmem_pdata + .platform_data = &mdp_pmem_pdata }, }; @@ -574,13 +631,14 @@ static struct platform_device android_pmem_adsp_device = { }, }; -static struct platform_device android_pmem_camera_device = { +static struct platform_device android_pmem_venc_device = { .name = "android_pmem", - .id = 6, + .id = 5, .dev = { - .platform_data = &android_pmem_camera_pdata, + .platform_data = &android_pmem_venc_pdata, }, }; + /////////////////////////////////////////////////////////////////////// // RAM-Console /////////////////////////////////////////////////////////////////////// @@ -634,9 +692,9 @@ static struct platform_device *devices[] __initdata = &msm_device_smd, &htcleo_rfkill, &msm_device_rtc, - &android_pmem_device, + &android_pmem_mdp_device, &android_pmem_adsp_device, - &android_pmem_camera_device, + &android_pmem_venc_device, &msm_device_i2c, &msm_kgsl_device, &msm_camera_sensor_s5k3e2fx, @@ -646,9 +704,6 @@ static struct platform_device *devices[] __initdata = &htc_headset_mgr, &htc_headset_gpio, }; - - - /////////////////////////////////////////////////////////////////////// // Vibrator /////////////////////////////////////////////////////////////////////// @@ -729,6 +784,16 @@ static void do_grp_reset(void) { writel(0x20000, MSM_CLK_CTL_BASE + 0x214); } + +static void do_sdc1_reset(void) +{ + volatile uint32_t* sdc1_clk = MSM_CLK_CTL_BASE + 0x218; + + *sdc1_clk |= (1 << 9); + mdelay(1); + *sdc1_clk &= ~(1 << 9); +} + /////////////////////////////////////////////////////////////////////// // Init /////////////////////////////////////////////////////////////////////// @@ -743,6 +808,7 @@ static void __init htcleo_init(void) msm_hw_reset_hook = htcleo_reset; do_grp_reset(); + do_sdc1_reset(); msm_acpu_clock_init(&htcleo_clock_data); @@ -767,29 +833,14 @@ static void __init htcleo_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); - #ifdef CONFIG_SERIAL_MSM_HS -static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = { - .rx_wakeup_irq = MSM_GPIO_TO_INT(HTCLEO_GPIO_BT_HOST_WAKE), /*Chip to Device*/ - .inject_rx_on_wakeup = 0, - .cpu_lock_supported = 0, - - /* for bcm */ - .bt_wakeup_pin_supported = 1, - .bt_wakeup_pin = HTCLEO_GPIO_BT_CHIP_WAKE, - .host_wakeup_pin = HTCLEO_GPIO_BT_HOST_WAKE, -}; -#endif - -#ifdef CONFIG_SERIAL_MSM_HS - msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata; - msm_device_uart_dm1.name = "msm_serial_hs_bcm"; /* for bcm */ - msm_device_uart_dm1.resource[3].end = 6; + msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata; + msm_device_uart_dm1.name = "msm_serial_hs_bcm"; /* for bcm */ + msm_device_uart_dm1.resource[3].end = 6; #endif i2c_register_board_info(0, base_i2c_devices, ARRAY_SIZE(base_i2c_devices)); - #ifdef CONFIG_USB_ANDROID htcleo_add_usb_devices(); #endif @@ -797,6 +848,8 @@ static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = { htcleo_init_mmc(0); platform_device_register(&htcleo_timed_gpios); + bt_export_bd_address(); + htcleo_bt_init(); htcleo_audio_init(); #ifdef CONFIG_USB_ANDROID @@ -859,8 +912,8 @@ static void __init htcleo_allocate_memory_regions(void) size = pmem_sf_size; if (size) { addr = alloc_bootmem(size); - android_pmem_pdata.start = __pa(addr); - android_pmem_pdata.size = size; + mdp_pmem_pdata.start = __pa(addr); + mdp_pmem_pdata.size = size; pr_info("allocating %lu bytes at %p (%lx physical) for sf " "pmem arena\n", size, addr, __pa(addr)); } diff --git a/arch/arm/mach-msm/board-htcleo.h b/arch/arm/mach-msm/board-htcleo.h index cfa38e6f..ab9064f7 100644 --- a/arch/arm/mach-msm/board-htcleo.h +++ b/arch/arm/mach-msm/board-htcleo.h @@ -38,11 +38,11 @@ #define MSM_GPU_PHYS_SIZE 0x00800000 /* #define MSM_GPU_PHYS_SIZE 0x00300000 */ -#define MSM_PMEM_CAMERA_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE) -#define MSM_PMEM_CAMERA_SIZE 0x00C00000 +#define MSM_PMEM_VENC_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE) +#define MSM_PMEM_VENC_SIZE 0x00800000 -#define MSM_PMEM_SMIPOOL_BASE (MSM_PMEM_CAMERA_BASE + MSM_PMEM_CAMERA_SIZE) -#define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_GPU_PHYS_SIZE - MSM_FB_SIZE - MSM_PMEM_CAMERA_SIZE) +#define MSM_PMEM_SMIPOOL_BASE (MSM_PMEM_VENC_BASE + MSM_PMEM_VENC_SIZE) +#define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_GPU_PHYS_SIZE - MSM_FB_SIZE - MSM_PMEM_VENC_SIZE) /* End SMI region */ /* Begin EBI region */ diff --git a/arch/arm/mach-msm/htc_headset_gpio.c b/arch/arm/mach-msm/htc_headset_gpio.c index bc16e4e0..83e5daf8 100644 --- a/arch/arm/mach-msm/htc_headset_gpio.c +++ b/arch/arm/mach-msm/htc_headset_gpio.c @@ -393,7 +393,7 @@ static int audiojack_probe(struct platform_device *pdev) } ret = request_irq(pjack_info->irq_mic, - mic_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW, "mic_headset", NULL); + mic_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, "mic_headset", NULL); if (ret < 0) goto err_request_detect_irq; diff --git a/arch/arm/mach-msm/include/mach/board-htcleo-microp.h b/arch/arm/mach-msm/include/mach/board-htcleo-microp.h index 86f654ef..d136835c 100644 --- a/arch/arm/mach-msm/include/mach/board-htcleo-microp.h +++ b/arch/arm/mach-msm/include/mach/board-htcleo-microp.h @@ -112,20 +112,21 @@ struct microp_i2c_client_data { #define MICROP_I2C_WCMD_MOBEAM_SEND 0xB3 -#define IRQ_GSENSOR (1<<10) -#define IRQ_LSENSOR (1<<9) -#define IRQ_REMOTEKEY (1<<7) -#define IRQ_HEADSETIN (1<<2) -#define IRQ_PROXIMITY (1<<1) -#define IRQ_SDCARD (1<<0) +#define IRQ_GSENSOR (1<<10) +#define IRQ_LSENSOR (1<<9) +#define IRQ_REMOTEKEY (1<<7) +#define IRQ_HEADSETIN (1<<2) +#define IRQ_PROXIMITY (1<<1) +#define IRQ_SDCARD (1<<0) -#define READ_GPI_STATE_HPIN (1<<2) -#define READ_GPI_STATE_SDCARD (1<<0) +#define READ_GPI_STATE_HPIN (1<<2) +#define READ_GPI_STATE_SDCARD (1<<0) -#define GPO_PROXIMITY 0x3 +#define GPO_CM3602 0x3 +#define LS_PWR_ON (1 << 0) +#define PS_PWR_ON (1 << 1) int microp_i2c_read(uint8_t addr, uint8_t *data, int length); int microp_i2c_write(uint8_t addr, uint8_t *data, int length); -int microp_gpo_enable(uint16_t interrupt_mask); -int microp_gpo_disable(uint16_t interrupt_mask); +int capella_cm3602_power(int pwr_device, uint8_t enable); #endif diff --git a/drivers/media/video/msm/s5k3e2fx.c b/drivers/media/video/msm/s5k3e2fx.c index 9619fb16..a2ab9ba1 100644 --- a/drivers/media/video/msm/s5k3e2fx.c +++ b/drivers/media/video/msm/s5k3e2fx.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,11 @@ static uint16_t g_usModuleVersion; /*0: rev.4, 1: rev.5 */ #define GROUPED_PARAMETER_HOLD 0x01 #define GROUPED_PARAMETER_UPDATE 0x00 +/* Greenish in low light */ +#define REG_MASK_CORRUPTED_FRAMES 0x0105 +#define MASK 0x01 +#define NO_MASK 0x00 + /* PLL Registers */ #define REG_PRE_PLL_CLK_DIV 0x0305 #define REG_PLL_MULTIPLIER_MSB 0x0306 @@ -2094,6 +2100,27 @@ static int s5k3e2fx_setting(enum msm_s_reg_update rupdate, {0x3063, 0x16}, } }; + + /* Most registers are directly applied at next frame after + writing except shutter and analog gain. Shutter and gain are + applied at 2nd or 1st frame later depending on register + writing time. When the camera is switched from preview to + snapshot, the first frame may have wrong shutter/gain and + should be discarded. The register REG_MASK_CORRUPTED_FRAMES + can discard the frame that has wrong shutter/gain. But in + preview mode, the frames should not be dropped. Otherwise + the preview will not be smooth. */ + if (rt == S_RES_PREVIEW) { + /* Frames will be not discarded after exposure and gain are + written. */ + s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + REG_MASK_CORRUPTED_FRAMES, NO_MASK); + } else { + /* Solve greenish in lowlight. Prevent corrupted frame */ + s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + REG_MASK_CORRUPTED_FRAMES, MASK); + } + /* solve greenish: hold for both */ rc = s5k3e2fx_i2c_write_b( s5k3e2fx_client->addr, @@ -2416,9 +2443,6 @@ static int s5k3e2fx_probe_init_lens_correction( s5k3e2fx_i2c_write_table(&lc_setting[g_usModuleVersion][0], NUM_LC_REG); -+ /* Solve EVT5 greenish in lowlight, prevent corrupted frame*/ -+ s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x105,0x1); - /*20090811 separates the EVT4/EVT5 sensor init and LC setting end */ s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, S5K3E2FX_REG_MODE_SELECT,