Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/misc/lis3lv02d/lis3lv02d_spi.c

  1 /*
  2  * lis3lv02d_spi - SPI glue layer for lis3lv02d
  3  *
  4  * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
  5  *
  6  *  This program is free software; you can redistribute it and/or modify
  7  *  it under the terms of the GNU General Public License version 2 as
  8  *  publishhed by the Free Software Foundation.
  9  */
 10 
 11 #include <linux/module.h>
 12 #include <linux/kernel.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>
 19 #include <linux/of.h>
 20 #include <linux/of_platform.h>
 21 #include <linux/of_device.h>
 22 
 23 #include "lis3lv02d.h"
 24 
 25 #define DRV_NAME        "lis3lv02d_spi"
 26 #define LIS3_SPI_READ   0x80
 27 
 28 static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)
 29 {
 30         struct spi_device *spi = lis3->bus_priv;
 31         int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);
 32         if (ret < 0)
 33                 return -EINVAL;
 34 
 35         *v = (u8) ret;
 36         return 0;
 37 }
 38 
 39 static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)
 40 {
 41         u8 tmp[2] = { reg, val };
 42         struct spi_device *spi = lis3->bus_priv;
 43         return spi_write(spi, tmp, sizeof(tmp));
 44 }
 45 
 46 static int lis3_spi_init(struct lis3lv02d *lis3)
 47 {
 48         u8 reg;
 49         int ret;
 50 
 51         /* power up the device */
 52         ret = lis3->read(lis3, CTRL_REG1, &reg);
 53         if (ret < 0)
 54                 return ret;
 55 
 56         reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 57         return lis3->write(lis3, CTRL_REG1, reg);
 58 }
 59 
 60 static union axis_conversion lis3lv02d_axis_normal =
 61         { .as_array = { 1, 2, 3 } };
 62 
 63 #ifdef CONFIG_OF
 64 static struct of_device_id lis302dl_spi_dt_ids[] = {
 65         { .compatible = "st,lis302dl-spi" },
 66         {}
 67 };
 68 MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids);
 69 #endif
 70 
 71 static int lis302dl_spi_probe(struct spi_device *spi)
 72 {
 73         int ret;
 74 
 75         spi->bits_per_word = 8;
 76         spi->mode = SPI_MODE_0;
 77         ret = spi_setup(spi);
 78         if (ret < 0)
 79                 return ret;
 80 
 81         lis3_dev.bus_priv       = spi;
 82         lis3_dev.init           = lis3_spi_init;
 83         lis3_dev.read           = lis3_spi_read;
 84         lis3_dev.write          = lis3_spi_write;
 85         lis3_dev.irq            = spi->irq;
 86         lis3_dev.ac             = lis3lv02d_axis_normal;
 87         lis3_dev.pdata          = spi->dev.platform_data;
 88 
 89 #ifdef CONFIG_OF
 90         if (of_match_device(lis302dl_spi_dt_ids, &spi->dev)) {
 91                 lis3_dev.of_node = spi->dev.of_node;
 92                 ret = lis3lv02d_init_dt(&lis3_dev);
 93                 if (ret)
 94                         return ret;
 95         }
 96 #endif
 97         spi_set_drvdata(spi, &lis3_dev);
 98 
 99         return lis3lv02d_init_device(&lis3_dev);
100 }
101 
102 static int lis302dl_spi_remove(struct spi_device *spi)
103 {
104         struct lis3lv02d *lis3 = spi_get_drvdata(spi);
105         lis3lv02d_joystick_disable(lis3);
106         lis3lv02d_poweroff(lis3);
107 
108         return lis3lv02d_remove_fs(&lis3_dev);
109 }
110 
111 #ifdef CONFIG_PM_SLEEP
112 static int lis3lv02d_spi_suspend(struct device *dev)
113 {
114         struct spi_device *spi = to_spi_device(dev);
115         struct lis3lv02d *lis3 = spi_get_drvdata(spi);
116 
117         if (!lis3->pdata || !lis3->pdata->wakeup_flags)
118                 lis3lv02d_poweroff(&lis3_dev);
119 
120         return 0;
121 }
122 
123 static int lis3lv02d_spi_resume(struct device *dev)
124 {
125         struct spi_device *spi = to_spi_device(dev);
126         struct lis3lv02d *lis3 = spi_get_drvdata(spi);
127 
128         if (!lis3->pdata || !lis3->pdata->wakeup_flags)
129                 lis3lv02d_poweron(lis3);
130 
131         return 0;
132 }
133 #endif
134 
135 static SIMPLE_DEV_PM_OPS(lis3lv02d_spi_pm, lis3lv02d_spi_suspend,
136                          lis3lv02d_spi_resume);
137 
138 static struct spi_driver lis302dl_spi_driver = {
139         .driver  = {
140                 .name   = DRV_NAME,
141                 .owner  = THIS_MODULE,
142                 .pm     = &lis3lv02d_spi_pm,
143                 .of_match_table = of_match_ptr(lis302dl_spi_dt_ids),
144         },
145         .probe  = lis302dl_spi_probe,
146         .remove = lis302dl_spi_remove,
147 };
148 
149 module_spi_driver(lis302dl_spi_driver);
150 
151 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
152 MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
153 MODULE_LICENSE("GPL");
154 MODULE_ALIAS("spi:" DRV_NAME);
155 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us