Path: blob/master/drivers/misc/lis3lv02d/lis3lv02d_spi.c
15111 views
/*1* lis3lv02d_spi - SPI glue layer for lis3lv02d2*3* Copyright (c) 2009 Daniel Mack <[email protected]>4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* publishhed by the Free Software Foundation.8*/910#include <linux/module.h>11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/err.h>14#include <linux/input.h>15#include <linux/interrupt.h>16#include <linux/workqueue.h>17#include <linux/spi/spi.h>18#include <linux/pm.h>1920#include "lis3lv02d.h"2122#define DRV_NAME "lis3lv02d_spi"23#define LIS3_SPI_READ 0x802425static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)26{27struct spi_device *spi = lis3->bus_priv;28int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);29if (ret < 0)30return -EINVAL;3132*v = (u8) ret;33return 0;34}3536static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)37{38u8 tmp[2] = { reg, val };39struct spi_device *spi = lis3->bus_priv;40return spi_write(spi, tmp, sizeof(tmp));41}4243static int lis3_spi_init(struct lis3lv02d *lis3)44{45u8 reg;46int ret;4748/* power up the device */49ret = lis3->read(lis3, CTRL_REG1, ®);50if (ret < 0)51return ret;5253reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;54return lis3->write(lis3, CTRL_REG1, reg);55}5657static union axis_conversion lis3lv02d_axis_normal =58{ .as_array = { 1, 2, 3 } };5960static int __devinit lis302dl_spi_probe(struct spi_device *spi)61{62int ret;6364spi->bits_per_word = 8;65spi->mode = SPI_MODE_0;66ret = spi_setup(spi);67if (ret < 0)68return ret;6970lis3_dev.bus_priv = spi;71lis3_dev.init = lis3_spi_init;72lis3_dev.read = lis3_spi_read;73lis3_dev.write = lis3_spi_write;74lis3_dev.irq = spi->irq;75lis3_dev.ac = lis3lv02d_axis_normal;76lis3_dev.pdata = spi->dev.platform_data;77spi_set_drvdata(spi, &lis3_dev);7879return lis3lv02d_init_device(&lis3_dev);80}8182static int __devexit lis302dl_spi_remove(struct spi_device *spi)83{84struct lis3lv02d *lis3 = spi_get_drvdata(spi);85lis3lv02d_joystick_disable();86lis3lv02d_poweroff(lis3);8788return lis3lv02d_remove_fs(&lis3_dev);89}9091#ifdef CONFIG_PM_SLEEP92static int lis3lv02d_spi_suspend(struct device *dev)93{94struct spi_device *spi = to_spi_device(dev);95struct lis3lv02d *lis3 = spi_get_drvdata(spi);9697if (!lis3->pdata || !lis3->pdata->wakeup_flags)98lis3lv02d_poweroff(&lis3_dev);99100return 0;101}102103static int lis3lv02d_spi_resume(struct device *dev)104{105struct spi_device *spi = to_spi_device(dev);106struct lis3lv02d *lis3 = spi_get_drvdata(spi);107108if (!lis3->pdata || !lis3->pdata->wakeup_flags)109lis3lv02d_poweron(lis3);110111return 0;112}113#endif114115static SIMPLE_DEV_PM_OPS(lis3lv02d_spi_pm, lis3lv02d_spi_suspend,116lis3lv02d_spi_resume);117118static struct spi_driver lis302dl_spi_driver = {119.driver = {120.name = DRV_NAME,121.owner = THIS_MODULE,122.pm = &lis3lv02d_spi_pm,123},124.probe = lis302dl_spi_probe,125.remove = __devexit_p(lis302dl_spi_remove),126};127128static int __init lis302dl_init(void)129{130return spi_register_driver(&lis302dl_spi_driver);131}132133static void __exit lis302dl_exit(void)134{135spi_unregister_driver(&lis302dl_spi_driver);136}137138module_init(lis302dl_init);139module_exit(lis302dl_exit);140141MODULE_AUTHOR("Daniel Mack <[email protected]>");142MODULE_DESCRIPTION("lis3lv02d SPI glue layer");143MODULE_LICENSE("GPL");144MODULE_ALIAS("spi:" DRV_NAME);145146147