static int lis3_i2c_runtime_resume(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); struct lis3lv02d *lis3 = i2c_get_clientdata(client); lis3lv02d_poweron(lis3); return 0; }
static int lis3lv02d_spi_resume(struct spi_device *spi) { struct lis3lv02d *lis3 = spi_get_drvdata(spi); if (!lis3->pdata || !lis3->pdata->wakeup_flags) lis3lv02d_poweron(lis3); return 0; }
static int lis3lv02d_i2c_resume(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); struct lis3lv02d *lis3 = i2c_get_clientdata(client); if (!lis3->pdata || !lis3->pdata->wakeup_flags || pm_runtime_suspended(dev)) lis3lv02d_poweron(lis3); return 0; }
static int lis3lv02d_i2c_resume(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); struct lis3lv02d *lis3 = i2c_get_clientdata(client); /* * pm_runtime documentation says that devices should always * be powered on at resume. Pm_runtime turns them off after system * wide resume is complete. */ if (!lis3->pdata || !lis3->pdata->wakeup_flags || pm_runtime_suspended(dev)) lis3lv02d_poweron(lis3); return 0; }
/* * Initialise the accelerometer and the various subsystems. * Should be rather independent of the bus system. */ int lis3lv02d_init_device(struct lis3lv02d *dev) { int err; irq_handler_t thread_fn; int irq_flags = 0; dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); switch (dev->whoami) { case WAI_12B: pr_info("12 bits sensor found\n"); dev->read_data = lis3lv02d_read_12; dev->mdps_max_val = 2048; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; dev->odrs = lis3_12_rates; dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; dev->scale = LIS3_SENSITIVITY_12B; dev->regs = lis3_wai12_regs; dev->regs_size = ARRAY_SIZE(lis3_wai12_regs); break; case WAI_8B: pr_info("8 bits sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; dev->odrs = lis3_8_rates; dev->odr_mask = CTRL1_DR; dev->scale = LIS3_SENSITIVITY_8B; dev->regs = lis3_wai8_regs; dev->regs_size = ARRAY_SIZE(lis3_wai8_regs); break; case WAI_3DC: pr_info("8 bits 3DC sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; dev->odrs = lis3_3dc_rates; dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; dev->scale = LIS3_SENSITIVITY_8B; break; default: pr_err("unknown sensor type 0x%X\n", dev->whoami); return -EINVAL; } dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), sizeof(lis3_wai12_regs)), GFP_KERNEL); if (dev->reg_cache == NULL) { printk(KERN_ERR DRIVER_NAME "out of memory\n"); return -ENOMEM; } mutex_init(&dev->mutex); atomic_set(&dev->wake_thread, 0); lis3lv02d_add_fs(dev); lis3lv02d_poweron(dev); if (dev->pm_dev) { pm_runtime_set_active(dev->pm_dev); pm_runtime_enable(dev->pm_dev); } if (lis3lv02d_joystick_enable()) pr_err("joystick initialization failed\n"); /* passing in platform specific data is purely optional and only * used by the SPI transport layer at the moment */ if (dev->pdata) { struct lis3lv02d_platform_data *p = dev->pdata; if (dev->whoami == WAI_8B) lis3lv02d_8b_configure(dev, p); irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; dev->irq_cfg = p->irq_cfg; if (p->irq_cfg) dev->write(dev, CTRL_REG3, p->irq_cfg); if (p->default_rate) lis3lv02d_set_odr(p->default_rate); } /* bail if we did not get an IRQ from the bus layer */ if (!dev->irq) { pr_debug("No IRQ. Disabling /dev/freefall\n"); goto out; } /* * The sensor can generate interrupts for free-fall and direction * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep * the things simple and _fast_ we activate it only for free-fall, so * no need to read register (very slow with ACPI). For the same reason, * we forbid shared interrupts. * * IRQF_TRIGGER_RISING seems pointless on HP laptops because the * io-apic is not configurable (and generates a warning) but I keep it * in case of support for other hardware. */ if (dev->pdata && dev->whoami == WAI_8B) thread_fn = lis302dl_interrupt_thread1_8b; else thread_fn = NULL; err = request_threaded_irq(dev->irq, lis302dl_interrupt, thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT | irq_flags, DRIVER_NAME, &lis3_dev); if (err < 0) { pr_err("Cannot get IRQ\n"); goto out; } if (misc_register(&lis3lv02d_misc_device)) pr_err("misc_register failed\n"); out: return 0; }
/* * Initialise the accelerometer and the various subsystems. * Should be rather independent of the bus system. */ int lis3lv02d_init_device(struct lis3lv02d *dev) { dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); switch (dev->whoami) { case WAI_12B: printk(KERN_INFO DRIVER_NAME ": 12 bits sensor found\n"); dev->read_data = lis3lv02d_read_12; dev->mdps_max_val = 2048; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; dev->odrs = lis3_12_rates; dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; dev->scale = LIS3_SENSITIVITY_12B; break; case WAI_8B: printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n"); dev->read_data = lis3lv02d_read_8; dev->mdps_max_val = 128; dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; dev->odrs = lis3_8_rates; dev->odr_mask = CTRL1_DR; dev->scale = LIS3_SENSITIVITY_8B; break; default: printk(KERN_ERR DRIVER_NAME ": unknown sensor type 0x%X\n", dev->whoami); return -EINVAL; } mutex_init(&dev->mutex); lis3lv02d_add_fs(dev); lis3lv02d_poweron(dev); if (lis3lv02d_joystick_enable()) printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); /* passing in platform specific data is purely optional and only * used by the SPI transport layer at the moment */ if (dev->pdata) { struct lis3lv02d_platform_data *p = dev->pdata; if (p->click_flags && (dev->whoami == WAI_8B)) { dev->write(dev, CLICK_CFG, p->click_flags); dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); dev->write(dev, CLICK_LATENCY, p->click_latency); dev->write(dev, CLICK_WINDOW, p->click_window); dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); dev->write(dev, CLICK_THSY_X, (p->click_thresh_x & 0xf) | (p->click_thresh_y << 4)); } if (p->wakeup_flags && (dev->whoami == WAI_8B)) { dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); /* default to 2.5ms for now */ dev->write(dev, FF_WU_DURATION_1, 1); /* enable high pass filter for both free-fall units */ dev->write(dev, CTRL_REG2, HP_FF_WU1 | HP_FF_WU2); } if (p->irq_cfg) dev->write(dev, CTRL_REG3, p->irq_cfg); } /* bail if we did not get an IRQ from the bus layer */ if (!dev->irq) { printk(KERN_ERR DRIVER_NAME ": No IRQ. Disabling /dev/freefall\n"); goto out; } if (misc_register(&lis3lv02d_misc_device)) printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); out: return 0; }