diff options
Diffstat (limited to 'drivers')
37 files changed, 821 insertions, 506 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ea6f6325f9b..72bedad6bf8 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -418,8 +418,8 @@ config APPLICOM If unsure, say N. config SONYPI - tristate "Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)" - depends on EXPERIMENTAL && X86 && PCI && INPUT && !64BIT + tristate "Sony Vaio Programmable I/O Control Device support" + depends on X86 && PCI && INPUT && !64BIT ---help--- This driver enables access to the Sony Programmable I/O Control Device which can be found in many (all ?) Sony Vaio laptops. @@ -566,7 +566,7 @@ source "drivers/char/tpm/Kconfig" config TELCLOCK tristate "Telecom clock driver for ATCA SBC" - depends on EXPERIMENTAL && X86 + depends on X86 default n help The telecom clock device is specific to the MPCBL0010 and MPCBL0050 diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 33dc2298af7..3d6c0671e99 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -826,7 +826,7 @@ static int __init mmtimer_init(void) /* Allocate list of node ptrs to mmtimer_t's */ timers = kzalloc(sizeof(struct mmtimer_node)*maxn, GFP_KERNEL); - if (timers == NULL) { + if (!timers) { printk(KERN_ERR "%s: failed to allocate memory for device\n", MMTIMER_NAME); goto out3; @@ -848,7 +848,6 @@ static int __init mmtimer_init(void) return 0; out3: - kfree(timers); misc_deregister(&mmtimer_miscdev); out2: free_irq(SGI_MMTIMER_VECTOR, NULL); diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index 04a480f86c6..cfdfe493c6a 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c @@ -93,9 +93,9 @@ int button_del_callback (void (*callback) (void)) button_callback_list [lp].count = 0; callback_count--; return 0; - }; + } lp--; - }; + } return -EINVAL; } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 0a484b4a1b0..a6b8ddea222 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -891,6 +891,14 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) int work = 0; struct mgsl_icount *icount = &info->icount; + if (!tty) { + /* tty is not available anymore */ + issue_command(info, CHA, CMD_RXRESET); + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):rx_ready_async(tty=NULL)\n",__FILE__,__LINE__); + return; + } + if (tcd) { /* early termination, get FIFO count from RBCL register */ fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); @@ -980,7 +988,7 @@ static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty) else #endif { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1000,7 +1008,7 @@ static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty) if (!info->tx_active) return; } else { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1050,13 +1058,12 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); - if (info->port.flags & ASYNC_CTS_FLOW) { + if (tty && (info->port.flags & ASYNC_CTS_FLOW)) { if (tty->hw_stopped) { if (info->serial_signals & SerialSignal_CTS) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx start..."); - if (tty) - tty->hw_stopped = 0; + tty->hw_stopped = 0; tx_start(info, tty); info->pending_bh |= BH_TRANSMIT; return; @@ -1065,8 +1072,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) if (!(info->serial_signals & SerialSignal_CTS)) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx stop..."); - if (tty) - tty->hw_stopped = 1; + tty->hw_stopped = 1; tx_stop(info); } } diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 3fcf80ff12f..d0d824ebf2c 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -783,7 +783,8 @@ static int __init ppdev_init (void) err = PTR_ERR(ppdev_class); goto out_chrdev; } - if (parport_register_driver(&pp_driver)) { + err = parport_register_driver(&pp_driver); + if (err < 0) { printk (KERN_WARNING CHRDEV ": unable to register with parport\n"); goto out_class; } diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index af9437488b6..91470fdbab2 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -411,7 +411,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) case RTC_IRQP_READ: case RTC_IRQP_SET: return -EINVAL; - }; + } } #endif diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index ce29e7cce52..e95e0ab0bd8 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -784,8 +784,10 @@ static int __init tlclk_init(void) } tlclk_major = ret; alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); - if (!alarm_events) + if (!alarm_events) { + ret = -ENOMEM; goto out1; + } /* Read telecom clock IRQ number (Set by BIOS) */ if (!request_region(TLCLK_BASE, 8, "telco_clock")) { diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index cdf2f5451c7..060a672ebb7 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1941,7 +1941,17 @@ static int __init init(void) INIT_LIST_HEAD(&pdrvdata.consoles); INIT_LIST_HEAD(&pdrvdata.portdevs); - return register_virtio_driver(&virtio_console); + err = register_virtio_driver(&virtio_console); + if (err < 0) { + pr_err("Error %d registering virtio driver\n", err); + goto free; + } + return 0; +free: + if (pdrvdata.debugfs_dir) + debugfs_remove_recursive(pdrvdata.debugfs_dir); + class_destroy(pdrvdata.class); + return err; } static void __exit fini(void) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 98a442da892..99c73352c43 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -105,7 +105,7 @@ config ATMEL_TCB_CLKSRC_BLOCK config IBM_ASM tristate "Device driver for IBM RSA service processor" - depends on X86 && PCI && INPUT && EXPERIMENTAL + depends on X86 && PCI && INPUT ---help--- This option enables device driver support for in-band access to the IBM RSA (Condor) service processor in eServer xSeries systems. @@ -162,8 +162,8 @@ config SGI_IOC4 Otherwise say N. config TIFM_CORE - tristate "TI Flash Media interface support (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI + tristate "TI Flash Media interface support" + depends on PCI help If you want support for Texas Instruments(R) Flash Media adapters you should select this option and then also choose an appropriate @@ -178,8 +178,8 @@ config TIFM_CORE be called tifm_core. config TIFM_7XX1 - tristate "TI Flash Media PCI74xx/PCI76xx host adapter support (EXPERIMENTAL)" - depends on PCI && TIFM_CORE && EXPERIMENTAL + tristate "TI Flash Media PCI74xx/PCI76xx host adapter support" + depends on PCI && TIFM_CORE default TIFM_CORE help This option enables support for Texas Instruments(R) PCI74xx and @@ -192,7 +192,7 @@ config TIFM_7XX1 config ICS932S401 tristate "Integrated Circuits ICS932S401" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Integrated Circuits ICS932S401 clock control chips. @@ -398,7 +398,7 @@ config EP93XX_PWM config DS1682 tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for Dallas Semiconductor DS1682 Total Elapsed Time Recorder. diff --git a/drivers/misc/bmp085-i2c.c b/drivers/misc/bmp085-i2c.c index 9943971c13e..a4f33c995ea 100644 --- a/drivers/misc/bmp085-i2c.c +++ b/drivers/misc/bmp085-i2c.c @@ -57,12 +57,6 @@ static int bmp085_i2c_remove(struct i2c_client *client) return bmp085_remove(&client->dev); } -static const struct of_device_id bmp085_of_match[] = { - { .compatible = "bosch,bmp085", }, - { }, -}; -MODULE_DEVICE_TABLE(of, bmp085_of_match); - static const struct i2c_device_id bmp085_id[] = { { BMP085_NAME, 0 }, { "bmp180", 0 }, @@ -74,7 +68,6 @@ static struct i2c_driver bmp085_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = BMP085_NAME, - .of_match_table = bmp085_of_match }, .id_table = bmp085_id, .probe = bmp085_i2c_probe, diff --git a/drivers/misc/bmp085-spi.c b/drivers/misc/bmp085-spi.c index 78aaff9b523..5e982af9973 100644 --- a/drivers/misc/bmp085-spi.c +++ b/drivers/misc/bmp085-spi.c @@ -73,19 +73,8 @@ static struct spi_driver bmp085_spi_driver = { .remove = __devexit_p(bmp085_spi_remove) }; -static int __init bmp085_spi_init(void) -{ - return spi_register_driver(&bmp085_spi_driver); -} - -static void __exit bmp085_spi_exit(void) -{ - spi_unregister_driver(&bmp085_spi_driver); -} +module_spi_driver(bmp085_spi_driver); MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>"); MODULE_DESCRIPTION("BMP085 SPI bus driver"); MODULE_LICENSE("GPL"); - -module_init(bmp085_spi_init); -module_exit(bmp085_spi_exit); diff --git a/drivers/misc/c2port/Kconfig b/drivers/misc/c2port/Kconfig index 33ee834e1b8..0dd690e61d3 100644 --- a/drivers/misc/c2port/Kconfig +++ b/drivers/misc/c2port/Kconfig @@ -3,8 +3,7 @@ # menuconfig C2PORT - tristate "Silicon Labs C2 port support (EXPERIMENTAL)" - depends on EXPERIMENTAL + tristate "Silicon Labs C2 port support" default n help This option enables support for Silicon Labs C2 port used to @@ -22,7 +21,7 @@ menuconfig C2PORT if C2PORT config C2PORT_DURAMAR_2150 - tristate "C2 port support for Eurotech's Duramar 2150 (EXPERIMENTAL)" + tristate "C2 port support for Eurotech's Duramar 2150" depends on X86 default n help diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c index a2d25e4857e..eaddfe9db14 100644 --- a/drivers/misc/carma/carma-fpga-program.c +++ b/drivers/misc/carma/carma-fpga-program.c @@ -978,7 +978,6 @@ static int fpga_of_probe(struct platform_device *op) dev_set_drvdata(priv->dev, priv); dma_cap_zero(mask); dma_cap_set(DMA_MEMCPY, mask); - dma_cap_set(DMA_INTERRUPT, mask); dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SG, mask); diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 8c279da0741..0c43297ed9a 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -666,7 +666,7 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf) src = SYS_FPGA_BLOCK; tx = chan->device->device_prep_dma_memcpy(chan, dst, src, REG_BLOCK_SIZE, - DMA_PREP_INTERRUPT); + 0); if (!tx) { dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n"); return -ENOMEM; diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index 701edf65897..c9e695ea7c9 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -50,7 +50,7 @@ config EEPROM_LEGACY config EEPROM_MAX6875 tristate "Maxim MAX6874/5 power supply supervisor" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get read-only support for the user EEPROM of the Maxim MAX6874/5 EEPROM-programmable, quad power-supply diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 25003d6ceb5..4ed93dd5411 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -302,6 +302,61 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf, /*-------------------------------------------------------------------------*/ +static int at25_np_to_chip(struct device *dev, + struct device_node *np, + struct spi_eeprom *chip) +{ + u32 val; + + memset(chip, 0, sizeof(*chip)); + strncpy(chip->name, np->name, sizeof(chip->name)); + + if (of_property_read_u32(np, "size", &val) == 0 || + of_property_read_u32(np, "at25,byte-len", &val) == 0) { + chip->byte_len = val; + } else { + dev_err(dev, "Error: missing \"size\" property\n"); + return -ENODEV; + } + + if (of_property_read_u32(np, "pagesize", &val) == 0 || + of_property_read_u32(np, "at25,page-size", &val) == 0) { + chip->page_size = (u16)val; + } else { + dev_err(dev, "Error: missing \"pagesize\" property\n"); + return -ENODEV; + } + + if (of_property_read_u32(np, "at25,addr-mode", &val) == 0) { + chip->flags = (u16)val; + } else { + if (of_property_read_u32(np, "address-width", &val)) { + dev_err(dev, + "Error: missing \"address-width\" property\n"); + return -ENODEV; + } + switch (val) { + case 8: + chip->flags |= EE_ADDR1; + break; + case 16: + chip->flags |= EE_ADDR2; + break; + case 24: + chip->flags |= EE_ADDR3; + break; + default: + dev_err(dev, + "Error: bad \"address-width\" property: %u\n", + val); + return -ENODEV; + } + if (of_find_property(np, "read-only", NULL)) + chip->flags |= EE_READONLY; + } + return 0; +} + static int at25_probe(struct spi_device *spi) { struct at25_data *at25 = NULL; @@ -314,33 +369,11 @@ static int at25_probe(struct spi_device *spi) /* Chip description */ if (!spi->dev.platform_data) { if (np) { - u32 val; - - memset(&chip, 0, sizeof(chip)); - strncpy(chip.name, np->name, 10); - - err = of_property_read_u32(np, "at25,byte-len", &val); - if (err) { - dev_dbg(&spi->dev, "invalid chip dt description\n"); - goto fail; - } - chip.byte_len = val; - - err = of_property_read_u32(np, "at25,addr-mode", &val); - if (err) { - dev_dbg(&spi->dev, "invalid chip dt description\n"); - goto fail; - } - chip.flags = (u16)val; - - err = of_property_read_u32(np, "at25,page-size", &val); - if (err) { - dev_dbg(&spi->dev, "invalid chip dt description\n"); + err = at25_np_to_chip(&spi->dev, np, &chip); + if (err) goto fail; - } - chip.page_size = (u16)val; } else { - dev_dbg(&spi->dev, "no chip description\n"); + dev_err(&spi->dev, "Error: no chip description\n"); err = -ENODEV; goto fail; } diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 6df0da4085e..12ccdf94e4f 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -736,7 +736,14 @@ static void ilo_remove(struct pci_dev *pdev) free_irq(pdev->irq, ilo_hw); ilo_unmap_device(pdev, ilo_hw); pci_release_regions(pdev); - pci_disable_device(pdev); + /* + * pci_disable_device(pdev) used to be here. But this PCI device has + * two functions with interrupt lines connected to a single pin. The + * other one is a USB host controller. So when we disable the PIN here + * e.g. by rmmod hpilo, the controller stops working. It is because + * the interrupt link is disabled in ACPI since it is not refcounted + * yet. See acpi_pci_link_free_irq called from acpi_pci_irq_disable. + */ kfree(ilo_hw); ilo_hwdev[(minor / max_ccb)] = 0; } @@ -826,7 +833,7 @@ unmap: free_regions: pci_release_regions(pdev); disable: - pci_disable_device(pdev); +/* pci_disable_device(pdev); see comment in ilo_remove */ free: kfree(ilo_hw); out: diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index a981e2a42f9..4a87e5c0a32 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -39,6 +39,7 @@ #include <linux/miscdevice.h> #include <linux/pm_runtime.h> #include <linux/atomic.h> +#include <linux/of_device.h> #include "lis3lv02d.h" #define DRIVER_NAME "lis3lv02d" @@ -80,6 +81,15 @@ #define LIS3_SENSITIVITY_12B ((LIS3_ACCURACY * 1000) / 1024) #define LIS3_SENSITIVITY_8B (18 * LIS3_ACCURACY) +/* + * LIS331DLH spec says 1LSBs corresponds 4G/4096 -> 1LSB is 1000/1024 mG. + * Below macros defines sensitivity values for +/-2G. Dataout bits for + * +/-2G range is 12 bits so 4 bits adjustment must be done to get 12bit + * data from 16bit value. Currently this driver supports only 2G range. + */ +#define LIS3DLH_SENSITIVITY_2G ((LIS3_ACCURACY * 1000) / 1024) +#define SHIFT_ADJ_2G 4 + #define LIS3_DEFAULT_FUZZ_12B 3 #define LIS3_DEFAULT_FLAT_12B 3 #define LIS3_DEFAULT_FUZZ_8B 1 @@ -135,6 +145,19 @@ static s16 lis3lv02d_read_12(struct lis3lv02d *lis3, int reg) return (s16)((hi << 8) | lo); } +/* 12bits for 2G range, 13 bits for 4G range and 14 bits for 8G range */ +static s16 lis331dlh_read_data(struct lis3lv02d *lis3, int reg) +{ + u8 lo, hi; + int v; + + lis3->read(lis3, reg - 1, &lo); + lis3->read(lis3, reg, &hi); + v = (int) ((hi << 8) | lo); + + return (s16) v >> lis3->shift_adj; +} + /** * lis3lv02d_get_axis - For the given axis, give the value converted * @axis: 1,2,3 - can also be negative @@ -195,6 +218,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) static int lis3_12_rates[4] = {40, 160, 640, 2560}; static int lis3_8_rates[2] = {100, 400}; static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; +static int lis3_3dlh_rates[4] = {50, 100, 400, 1000}; /* ODR is Output Data Rate */ static int lis3lv02d_get_odr(struct lis3lv02d *lis3) @@ -267,7 +291,7 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); } - if (lis3->whoami == WAI_3DC) { + if ((lis3->whoami == WAI_3DC) || (lis3->whoami == WAI_3DLH)) { ctlreg = CTRL_REG4; selftest = CTRL4_ST0; } else { @@ -398,9 +422,17 @@ int lis3lv02d_poweron(struct lis3lv02d *lis3) lis3->read(lis3, CTRL_REG2, ®); if (lis3->whoami == WAI_12B) reg |= CTRL2_BDU | CTRL2_BOOT; + else if (lis3->whoami == WAI_3DLH) + reg |= CTRL2_BOOT_3DLH; else reg |= CTRL2_BOOT_8B; lis3->write(lis3, CTRL_REG2, reg); + + if (lis3->whoami == WAI_3DLH) { + lis3->read(lis3, CTRL_REG4, ®); + reg |= CTRL4_BDU; + lis3->write(lis3, CTRL_REG4, reg); + } } err = lis3lv02d_get_pwron_wait(lis3); @@ -912,6 +944,154 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3, } } +#ifdef CONFIG_OF +int lis3lv02d_init_dt(struct lis3lv02d *lis3) +{ + struct lis3lv02d_platform_data *pdata; + struct device_node *np = lis3->of_node; + u32 val; + + if (!lis3->of_node) + return 0; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + if (of_get_property(np, "st,click-single-x", NULL)) + pdata->click_flags |= LIS3_CLICK_SINGLE_X; + if (of_get_property(np, "st,click-double-x", NULL)) + pdata->click_flags |= LIS3_CLICK_DOUBLE_X; + + if (of_get_property(np, "st,click-single-y", NULL)) + pdata->click_flags |= LIS3_CLICK_SINGLE_Y; + if (of_get_property(np, "st,click-double-y", NULL)) + pdata->click_flags |= LIS3_CLICK_DOUBLE_Y; + + if (of_get_property(np, "st,click-single-z", NULL)) + pdata->click_flags |= LIS3_CLICK_SINGLE_Z; + if (of_get_property(np, "st,click-double-z", NULL)) + pdata->click_flags |= LIS3_CLICK_DOUBLE_Z; + + if (!of_property_read_u32(np, "st,click-threshold-x", &val)) + pdata->click_thresh_x = val; + if (!of_property_read_u32(np, "st,click-threshold-y", &val)) + pdata->click_thresh_y = val; + if (!of_property_read_u32(np, "st,click-threshold-z", &val)) + pdata->click_thresh_z = val; + + if (!of_property_read_u32(np, "st,click-time-limit", &val)) + pdata->click_time_limit = val; + if (!of_property_read_u32(np, "st,click-latency", &val)) + pdata->click_latency = val; + if (!of_property_read_u32(np, "st,click-window", &val)) + pdata->click_window = val; + + if (of_get_property(np, "st,irq1-disable", NULL)) + pdata->irq_cfg |= LIS3_IRQ1_DISABLE; + if (of_get_property(np, "st,irq1-ff-wu-1", NULL)) + pdata->irq_cfg |= LIS3_IRQ1_FF_WU_1; + if (of_get_property(np, "st,irq1-ff-wu-2", NULL)) + pdata->irq_cfg |= LIS3_IRQ1_FF_WU_2; + if (of_get_property(np, "st,irq1-data-ready", NULL)) + pdata->irq_cfg |= LIS3_IRQ1_DATA_READY; + if (of_get_property(np, "st,irq1-click", NULL)) + pdata->irq_cfg |= LIS3_IRQ1_CLICK; + + if (of_get_property(np, "st,irq2-disable", NULL)) + pdata->irq_cfg |= LIS3_IRQ2_DISABLE; + if (of_get_property(np, "st,irq2-ff-wu-1", NULL)) + pdata->irq_cfg |= LIS3_IRQ2_FF_WU_1; + if (of_get_property(np, "st,irq2-ff-wu-2", NULL)) + pdata->irq_cfg |= LIS3_IRQ2_FF_WU_2; + if (of_get_property(np, "st,irq2-data-ready", NULL)) + pdata->irq_cfg |= LIS3_IRQ2_DATA_READY; + if (of_get_property(np, "st,irq2-click", NULL)) + pdata->irq_cfg |= LIS3_IRQ2_CLICK; + + if (of_get_property(np, "st,irq-open-drain", NULL)) + pdata->irq_cfg |= LIS3_IRQ_OPEN_DRAIN; + if (of_get_property(np, "st,irq-active-low", NULL)) + pdata->irq_cfg |= LIS3_IRQ_ACTIVE_LOW; + + if (!of_property_read_u32(np, "st,wu-duration-1", &val)) + pdata->duration1 = val; + if (!of_property_read_u32(np, "st,wu-duration-2", &val)) + pdata->duration2 = val; + + if (of_get_property(np, "st,wakeup-x-lo", NULL)) + pdata->wakeup_flags |= LIS3_WAKEUP_X_LO; + if (of_get_property(np, "st,wakeup-x-hi", NULL)) + pdata->wakeup_flags |= LIS3_WAKEUP_X_HI; + if (of_get_property(np, "st,wakeup-y-lo", NULL)) + pdata->wakeup_flags |= LIS3_WAKEUP_Y_LO; + if (of_get_property(np, "st,wakeup-y-hi", NULL)) + pdata->wakeup_flags |= LIS3_WAKEUP_Y_HI; + if (of_get_property(np, "st,wakeup-z-lo", NULL)) + pdata->wakeup_flags |= LIS3_WAKEUP_Z_LO; + if (of_get_property(np, "st,wakeup-z-hi", NULL)) + pdata->wakeup_flags |= LIS3_WAKEUP_Z_HI; + + if (!of_property_read_u32(np, "st,highpass-cutoff-hz", &val)) { + switch (val) { + case 1: + pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_1HZ; + break; + case 2: + pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_2HZ; + break; + case 4: + pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_4HZ; + break; + case 8: + pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_8HZ; + break; + } + } + + if (of_get_property(np, "st,hipass1-disable", NULL)) + pdata->hipass_ctrl |= LIS3_HIPASS1_DISABLE; + if (of_get_property(np, "st,hipass2-disable", NULL)) + pdata->hipass_ctrl |= LIS3_HIPASS2_DISABLE; + + if (of_get_property(np, "st,axis-x", &val)) + pdata->axis_x = val; + if (of_get_property(np, "st,axis-y", &val)) + pdata->axis_y = val; + if (of_get_property(np, "st,axis-z", &val)) + pdata->axis_z = val; + + if (of_get_property(np, "st,default-rate", NULL)) + pdata->default_rate = val; + + if (of_get_property(np, "st,min-limit-x", &val)) + pdata->st_min_limits[0] = val; + if (of_get_property(np, "st,min-limit-y", &val)) + pdata->st_min_limits[1] = val; + if (of_get_property(np, "st,min-limit-z", &val)) + pdata->st_min_limits[2] = val; + + if (of_get_property(np, "st,max-limit-x", &val)) + pdata->st_max_limits[0] = val; + if (of_get_property(np, "st,max-limit-y", &val)) + pdata->st_max_limits[1] = val; + if (of_get_property(np, "st,max-limit-z", &val)) + pdata->st_max_limits[2] = val; + + + lis3->pdata = pdata; + + return 0; +} + +#else +int lis3lv02d_init_dt(struct lis3lv02d *lis3) +{ + return 0; +} +#endif +EXPORT_SYMBOL_GPL(lis3lv02d_init_dt); + /* * Initialise the accelerometer and the various subsystems. * Should be rather independent of the bus system. @@ -956,6 +1136,16 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3) lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; lis3->scale = LIS3_SENSITIVITY_8B; break; + case WAI_3DLH: + pr_info("16 bits lis331dlh sensor found\n"); + lis3->read_data = lis331dlh_read_data; + lis3->mdps_max_val = 2048; /* 12 bits for 2G */ + lis3->shift_adj = SHIFT_ADJ_2G; + lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; + lis3->odrs = lis3_3dlh_rates; + lis3->odr_mask = CTRL1_DR0 | CTRL1_DR1; + lis3->scale = LIS3DLH_SENSITIVITY_2G; + break; default: pr_err("unknown sensor type 0x%X\n", lis3->whoami); return -EINVAL; diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index 2b1482ad3f1..c439c827eea 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h @@ -26,12 +26,12 @@ /* * This driver tries to support the "digital" accelerometer chips from * STMicroelectronics such as LIS3LV02DL, LIS302DL, LIS3L02DQ, LIS331DL, - * LIS35DE, or LIS202DL. They are very similar in terms of programming, with - * almost the same registers. In addition to differing on physical properties, - * they differ on the number of axes (2/3), precision (8/12 bits), and special - * features (freefall detection, click...). Unfortunately, not all the - * differences can be probed via a register. - * They can be connected either via I²C or SPI. + * LIS331DLH, LIS35DE, or LIS202DL. They are very similar in terms of + * programming, with almost the same registers. In addition to differing + * on physical properties, they differ on the number of axes (2/3), + * precision (8/12 bits), and special features (freefall detection, + * click...). |