From 5e8c7c54a9b297dae0081dd19a7bb94e23040a3d Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Tue, 18 May 2010 14:51:13 +0100 Subject: linux-moblin: add 2.6.33.2 kernel from MeeGo 1.0 Signed-off-by: Joshua Lock --- ...34-moorestown-analog-accelerometer-driver.patch | 462 +++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100644 meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-analog-accelerometer-driver.patch (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-analog-accelerometer-driver.patch') diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-analog-accelerometer-driver.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-analog-accelerometer-driver.patch new file mode 100644 index 000000000..c8264db69 --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-analog-accelerometer-driver.patch @@ -0,0 +1,462 @@ +Index: linux-2.6.33/drivers/hwmon/Kconfig +=================================================================== +--- linux-2.6.33.orig/drivers/hwmon/Kconfig ++++ linux-2.6.33/drivers/hwmon/Kconfig +@@ -63,6 +63,13 @@ config SENSORS_EMC1403 + Threshold values can be configured using sysfs. + Data from the different diode are accessible via sysfs. + ++config SENSORS_MRST_ANALOG_ACCEL ++ tristate "Moorestown Analog Accelerometer" ++ depends on LNW_IPC ++ help ++ If you say yes here you get support for the Analog Accelerometer Devices ++ x y Z data can be accessed via sysfs. ++ + config HWMON_DEBUG_CHIP + bool "Hardware Monitoring Chip debugging messages" + default n +Index: linux-2.6.33/drivers/hwmon/Makefile +=================================================================== +--- linux-2.6.33.orig/drivers/hwmon/Makefile ++++ linux-2.6.33/drivers/hwmon/Makefile +@@ -103,6 +103,7 @@ obj-$(CONFIG_SENSORS_ISL29020) += isl290 + obj-$(CONFIG_SENSORS_HMC6352) += hmc6352.o + obj-$(CONFIG_SENSORS_LIS331DL) += lis331dl.o + obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o ++obj-$(CONFIG_SENSORS_MRST_ANALOG_ACCEL) += mrst_analog_accel.o + + ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) + EXTRA_CFLAGS += -DDEBUG +Index: linux-2.6.33/drivers/hwmon/mrst_analog_accel.c +=================================================================== +--- /dev/null ++++ linux-2.6.33/drivers/hwmon/mrst_analog_accel.c +@@ -0,0 +1,381 @@ ++/* ++ * mrst_analog_accel.c - Intel analog accelerometer driver for Moorestown ++ * ++ * Copyright (C) 2009 Intel Corp ++ * ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Ramesh Agarwal"); ++MODULE_DESCRIPTION("Intel Moorestown Analog Accelerometer Driver"); ++MODULE_LICENSE("GPL v2"); ++ ++/* PMIC ADC INTERRUPT REGISTERS */ ++#define PMIC_ADC_ACC_REG_ADCINT 0x5F /*ADC interrupt register */ ++#define PMIC_ADC_ACC_REG_MADCINT 0x60 /*ADC interrupt mask register */ ++ ++/* PMIC ADC CONTROL REGISTERS */ ++#define PMIC_ADC_ACC_REG_ADCCNTL1 0x61 /*ADC control register */ ++#define PMIC_ADC_ACC_REG_ADCCNTL2 0x62 /*ADC gain regs channel 10-17 */ ++#define PMIC_ADC_ACC_REG_ADCCNTL3 0x63 /*ADC gain regs channel 18-21 */ ++ ++/* PMIC Data Register base */ ++#define PMIC_ADC_DATA_REG_BASE 0x64 ++ ++/* PMIC Channel Mapping Register base */ ++#define PMIC_ADC_MAPPING_BASE 0xA4 ++ ++/* Number of PMIC sample registers */ ++#define PMIC_ADC_REG_MAX 32 /* Max no of available channel */ ++ ++#define PMIC_ADC_X_REG_HIGH(index) (PMIC_ADC_DATA_REG_BASE \ ++ + (index * 2)) ++#define PMIC_ADC_X_REG_LOW(index) (PMIC_ADC_DATA_REG_BASE \ ++ + (index * 2) + 1) ++#define PMIC_ADC_Y_REG_HIGH(index) (PMIC_ADC_DATA_REG_BASE \ ++ + (index * 2) + 2) ++#define PMIC_ADC_Y_REG_LOW(index) (PMIC_ADC_DATA_REG_BASE \ ++ + (index * 2) + 3) ++#define PMIC_ADC_Z_REG_HIGH(index) (PMIC_ADC_DATA_REG_BASE \ ++ + (index * 2) + 4) ++#define PMIC_ADC_Z_REG_LOW(index) (PMIC_ADC_DATA_REG_BASE \ ++ + (index * 2) + 5) ++ ++/* Number of registers to read at a time */ ++#define REG_READ_PER_IPC 4 /* Read 4 at a time although the */ ++ /* IPC will support max 5 */ ++ ++#define END_OF_CHANNEL_VALUE 0x1F /* Used to indicate the last */ ++ /* channel being used */ ++ ++/* PMIC ADC channels for Accelero Meter */ ++#define PMIC_ADC_ACC_ADC_ACC_CH14 0xE ++#define PMIC_ADC_ACC_ADC_ACC_CH15 0xF ++#define PMIC_ADC_ACC_ADC_ACC_CH16 0x10 ++ ++static unsigned int mrst_analog_reg_idx; ++ ++/* Use IPC to read the value of the register and display ++ * X value ++ */ ++static ssize_t ++mrst_analog_accel_x_axis_data_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ unsigned int ret_val; ++ struct ipc_pmic_reg_data ipc_data; ++ ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_data.num_entries = 2; ++ ipc_data.pmic_reg_data[0].register_address = ++ PMIC_ADC_X_REG_HIGH(mrst_analog_reg_idx); /* X Higher 8 bits */ ++ ipc_data.pmic_reg_data[1].register_address = ++ PMIC_ADC_X_REG_LOW(mrst_analog_reg_idx); /* X lower 3 bits */ ++ if (ipc_pmic_register_read(&ipc_data) != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC reg read using IPC failed\n"); ++ return -1; ++ } ++ ret_val = ipc_data.pmic_reg_data[0].value << 3; /* X higher 8 bits */ ++ /* lower 3 bits */ ++ ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07); ++ return sprintf(buf, "%d\n", ret_val); ++} ++ ++/* Use IPC to read the value of the register and display ++ * Y value */ ++static ssize_t ++mrst_analog_accel_y_axis_data_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ unsigned int ret_val; ++ struct ipc_pmic_reg_data ipc_data; ++ ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_data.num_entries = 2; ++ ipc_data.pmic_reg_data[0].register_address = ++ PMIC_ADC_Y_REG_HIGH(mrst_analog_reg_idx); /* Y higher 8 bits */ ++ ipc_data.pmic_reg_data[1].register_address = ++ PMIC_ADC_Y_REG_LOW(mrst_analog_reg_idx); /* Y lower 3 bits */ ++ if (ipc_pmic_register_read(&ipc_data) != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC reg read using IPC failed\n"); ++ return -1; ++ } ++ ret_val = ipc_data.pmic_reg_data[0].value << 3; /* Y higher 8 bits */ ++ /* Y lower 3 bits */ ++ ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07); ++ return sprintf(buf, "%d\n", ret_val); ++} ++ ++/* Use IPC to read the value of the register and display ++ * Z value */ ++static ssize_t ++mrst_analog_accel_z_axis_data_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ unsigned int ret_val; ++ struct ipc_pmic_reg_data ipc_data; ++ ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_data.num_entries = 2; ++ ipc_data.pmic_reg_data[0].register_address = ++ PMIC_ADC_Z_REG_HIGH(mrst_analog_reg_idx); ++ ipc_data.pmic_reg_data[1].register_address = ++ PMIC_ADC_Z_REG_LOW(mrst_analog_reg_idx); /* Z lower 3 bits */ ++ if (ipc_pmic_register_read(&ipc_data) != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC reg read using IPC failed\n"); ++ return -1; ++ } ++ ret_val = ipc_data.pmic_reg_data[0].value << 3; /* Z higher 8 bits */ ++ /* Z lower 3 bits */ ++ ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07); ++ return sprintf(buf, "%d\n", ret_val); ++} ++ ++ ++static DEVICE_ATTR(acc_x_axis, S_IRUGO, ++ mrst_analog_accel_x_axis_data_show, NULL); ++static DEVICE_ATTR(acc_y_axis, S_IRUGO, ++ mrst_analog_accel_y_axis_data_show, NULL); ++static DEVICE_ATTR(acc_z_axis, S_IRUGO, ++ mrst_analog_accel_z_axis_data_show, NULL); ++ ++static struct attribute *mid_att_acc[] = { ++ &dev_attr_acc_x_axis.attr, ++ &dev_attr_acc_y_axis.attr, ++ &dev_attr_acc_z_axis.attr, ++ NULL ++}; ++ ++static struct attribute_group m_analog_gr = { ++ .name = "mrst_analog_accel", ++ .attrs = mid_att_acc ++}; ++ ++static int ++mrst_analog_accel_initialize(void) ++{ ++ struct ipc_pmic_mod_reg_data ipc_mod_data; ++ struct ipc_pmic_reg_data ipc_data; ++ u8 retval = 0; ++ u8 mad_cntrl = 0; /* MADCINT register value */ ++ u8 adc_cntrl2 = 0; /* ADCCNTL2 register value */ ++ int i, j; ++ ++ /* Initialize the register index to use to be zero */ ++ mrst_analog_reg_idx = 0; ++ ++ /* check if the ADC is enabled or not ++ * Read ADCCNTL1 registers */ ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_data.num_entries = 1; ++ ipc_data.pmic_reg_data[0].register_address = ++ PMIC_ADC_ACC_REG_ADCCNTL1; ++ ipc_data.pmic_reg_data[0].value = 0; ++ ++ retval = ipc_pmic_register_read(&ipc_data); ++ if (retval != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC register read failed\n"); ++ return retval; ++ } ++ ++ adc_cntrl2 = ipc_data.pmic_reg_data[0].value; ++ ++ if ((adc_cntrl2 >> 7) & 0x1) { ++ /* If the ADC is enabled find the set of registers to use ++ ** Loop through the channel mapping register to find out the ++ ** first free one ++ */ ++ for (i = 0; ++ (i < PMIC_ADC_REG_MAX) && (mrst_analog_reg_idx == 0); ++ i += REG_READ_PER_IPC) { ++ ++ ipc_data.num_entries = REG_READ_PER_IPC; ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ++ /* Reading 4 regs at a time instead of reading each ++ * reg one by one since IPC is an expensive operation ++ */ ++ for (j = 0; j < REG_READ_PER_IPC; j++) { ++ ipc_data.pmic_reg_data[j].register_address = ++ PMIC_ADC_MAPPING_BASE + i + j; ++ ipc_data.pmic_reg_data[j].value = 0; ++ } ++ retval = ipc_pmic_register_read(&ipc_data); ++ if (retval != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC regs read failed\n"); ++ return retval; ++ } ++ for (j = 0; j < REG_READ_PER_IPC; j++) { ++ if (ipc_data.pmic_reg_data[j].value ++ == END_OF_CHANNEL_VALUE) { ++ mrst_analog_reg_idx = i + j; ++ break; ++ } ++ } ++ } ++ } ++ /* Check to see if there are enough registers to map the channel */ ++ if ((mrst_analog_reg_idx + 3) >= PMIC_ADC_REG_MAX) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:Not enough regs to map the channels\n"); ++ return -1; ++ } ++ ++ /* Update the mapping registers for the accelerometer*/ ++ ipc_data.num_entries = 4; ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_data.pmic_reg_data[0].register_address = ++ PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx; ++ ipc_data.pmic_reg_data[0].value = PMIC_ADC_ACC_ADC_ACC_CH14; ++ ++ ipc_data.pmic_reg_data[1].register_address = ++ PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx + 1; ++ ipc_data.pmic_reg_data[1].value = PMIC_ADC_ACC_ADC_ACC_CH15; ++ ++ ipc_data.pmic_reg_data[2].register_address = ++ PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx + 2; ++ ipc_data.pmic_reg_data[2].value = PMIC_ADC_ACC_ADC_ACC_CH16; ++ ++ ipc_data.pmic_reg_data[3].register_address = ++ PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx + 3 ; ++ ipc_data.pmic_reg_data[3].value = END_OF_CHANNEL_VALUE; ++ ++ retval = ipc_pmic_register_write(&ipc_data, FALSE); ++ if (retval != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC reg write failed\n"); ++ return retval; ++ } ++ ++ /* If the ADC was not enabled, enable it now */ ++ if (!(adc_cntrl2 >> 7) & 0x1) { ++ /* Mask the round robin completion interrupt */ ++ ipc_mod_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_mod_data.num_entries = 1; ++ mad_cntrl = 0x01; ++ ipc_mod_data.pmic_mod_reg_data[0].register_address = ++ PMIC_ADC_ACC_REG_MADCINT; ++ ipc_mod_data.pmic_mod_reg_data[0].value = mad_cntrl; ++ ipc_mod_data.pmic_mod_reg_data[0].bit_map = 0x01; ++ ++ retval = ipc_pmic_register_read_modify(&ipc_mod_data); ++ if (retval != 0) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:PMIC reg modify failed\n"); ++ return retval; ++ } ++ ++ adc_cntrl2 = 0xc6; /*27ms delay,start round robin, ++ enable full power */ ++ ipc_data.ioc = FALSE; /* No need to generate MSI */ ++ ipc_data.num_entries = 1; ++ ipc_data.pmic_reg_data[0].register_address = ++ PMIC_ADC_ACC_REG_ADCCNTL1; ++ ipc_data.pmic_reg_data[0].value = adc_cntrl2; ++ retval = ipc_pmic_register_write(&ipc_data, FALSE); ++ if (retval != 0) ++ return retval; ++ } ++ return retval; ++} ++ ++static struct platform_device *mrst_analog_accel_pdev; ++static struct device *mrst_analog_accel_hwmon; ++ ++static int ++mrst_analog_accel_unregister(void) ++{ ++ ++ printk(KERN_ALERT "\nStart Exit\n\n"); ++ sysfs_remove_group(&mrst_analog_accel_hwmon->kobj, &m_analog_gr); ++ hwmon_device_unregister(mrst_analog_accel_hwmon); ++ platform_device_unregister(mrst_analog_accel_pdev); ++ printk(KERN_ALERT "\n\nEnd Exit\n"); ++ return 0; ++} ++ ++ ++static int __init ++mrst_analog_accel_module_init(void) ++{ ++ int retval = 0; ++ ++ mrst_analog_accel_pdev = ++ platform_device_register_simple("mrst_analog_accel", ++ 0, NULL, 0); ++ if (IS_ERR(mrst_analog_accel_pdev)) { ++ retval = PTR_ERR(mrst_analog_accel_pdev); ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:Registration with the platform failed\n"); ++ goto accelero_reg_failed; ++ } ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:Registered with the platform\n"); ++ ++ retval = mrst_analog_accel_initialize(); ++ if (retval == 0) { ++ retval = sysfs_create_group(&mrst_analog_accel_pdev->dev.kobj, ++ &m_analog_gr); ++ if (retval) { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:device_create_file 1 failed\n"); ++ goto accelero_reg_failed; ++ } ++ mrst_analog_accel_hwmon = ++ hwmon_device_register(&mrst_analog_accel_pdev->dev); ++ if (IS_ERR(mrst_analog_accel_hwmon)) { ++ retval = PTR_ERR(mrst_analog_accel_hwmon); ++ mrst_analog_accel_hwmon = NULL; ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:Registration with hwmon failed\n"); ++ } ++ } else { ++ printk(KERN_ALERT ++ "\nmrst_analog_accel:Initialization failed: %d\n", retval); ++ } ++ ++accelero_reg_failed: ++ return retval; ++} ++ ++static void __exit ++mrst_analog_accel_module_exit(void) ++{ ++ ++ mrst_analog_accel_unregister(); ++} ++ ++module_init(mrst_analog_accel_module_init); ++module_exit(mrst_analog_accel_module_exit); +Index: linux-2.6.33/drivers/hwmon/lis331dl.c +=================================================================== +--- linux-2.6.33.orig/drivers/hwmon/lis331dl.c ++++ linux-2.6.33/drivers/hwmon/lis331dl.c +@@ -186,33 +186,10 @@ invarg: + return -EINVAL; + } + +-static ssize_t reboot_mem_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t count) +-{ +- struct i2c_client *client = to_i2c_client(dev); +- struct acclero_data *data = i2c_get_clientdata(client); +- unsigned int ret_val, set_val; +- unsigned long val; +- +- if (strict_strtoul(buf, 10, &val)) +- return -EINVAL; +- ret_val = i2c_smbus_read_byte_data(client, 0x21); +- if (val == ACCEL_MEMORY_REBOOT) { +- mutex_lock(&data->update_lock); +- set_val = (ret_val | (1 << 6)); /* setting the 6th bit */ +- i2c_write_current_data(client, 0x21, set_val); +- mutex_unlock(&data->update_lock); +- } else +- return -EINVAL; +- return count; +-} +- + static DEVICE_ATTR(data_rate, S_IRUGO | S_IWUSR, + data_rate_show, data_rate_store); + static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, + power_mode_show, power_mode_store); +-static DEVICE_ATTR(reboot_mem, S_IWUSR, NULL, +- reboot_mem_store); + static DEVICE_ATTR(x, S_IRUGO, x_pos_show, NULL); + static DEVICE_ATTR(y, S_IRUGO, y_pos_show, NULL); + static DEVICE_ATTR(z, S_IRUGO, z_pos_show, NULL); +@@ -221,7 +198,6 @@ static DEVICE_ATTR(curr_pos, S_IRUGO, xy + static struct attribute *mid_att_acclero[] = { + &dev_attr_data_rate.attr, + &dev_attr_power_state.attr, +- &dev_attr_reboot_mem.attr, + &dev_attr_x.attr, + &dev_attr_y.attr, + &dev_attr_z.attr, -- cgit v1.2.3