Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * ADLX345/346 Three-Axis Digital Accelerometers (SPI Interface)
  3 *
  4 * Enter bugs at http://blackfin.uclinux.org/
  5 *
  6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
  7 * Licensed under the GPL-2 or later.
  8 */
  9
 10#include <linux/input.h>	/* BUS_SPI */
 11#include <linux/module.h>
 12#include <linux/spi/spi.h>
 13#include <linux/pm.h>
 14#include <linux/types.h>
 15#include "adxl34x.h"
 16
 17#define MAX_SPI_FREQ_HZ		5000000
 18#define MAX_FREQ_NO_FIFODELAY	1500000
 19#define ADXL34X_CMD_MULTB	(1 << 6)
 20#define ADXL34X_CMD_READ	(1 << 7)
 21#define ADXL34X_WRITECMD(reg)	(reg & 0x3F)
 22#define ADXL34X_READCMD(reg)	(ADXL34X_CMD_READ | (reg & 0x3F))
 23#define ADXL34X_READMB_CMD(reg) (ADXL34X_CMD_READ | ADXL34X_CMD_MULTB \
 24					| (reg & 0x3F))
 25
 26static int adxl34x_spi_read(struct device *dev, unsigned char reg)
 27{
 28	struct spi_device *spi = to_spi_device(dev);
 29	unsigned char cmd;
 30
 31	cmd = ADXL34X_READCMD(reg);
 32
 33	return spi_w8r8(spi, cmd);
 34}
 35
 36static int adxl34x_spi_write(struct device *dev,
 37			     unsigned char reg, unsigned char val)
 38{
 39	struct spi_device *spi = to_spi_device(dev);
 40	unsigned char buf[2];
 41
 42	buf[0] = ADXL34X_WRITECMD(reg);
 43	buf[1] = val;
 44
 45	return spi_write(spi, buf, sizeof(buf));
 46}
 47
 48static int adxl34x_spi_read_block(struct device *dev,
 49				  unsigned char reg, int count,
 50				  void *buf)
 51{
 52	struct spi_device *spi = to_spi_device(dev);
 53	ssize_t status;
 54
 55	reg = ADXL34X_READMB_CMD(reg);
 56	status = spi_write_then_read(spi, &reg, 1, buf, count);
 57
 58	return (status < 0) ? status : 0;
 59}
 60
 61static const struct adxl34x_bus_ops adxl34x_spi_bops = {
 62	.bustype	= BUS_SPI,
 63	.write		= adxl34x_spi_write,
 64	.read		= adxl34x_spi_read,
 65	.read_block	= adxl34x_spi_read_block,
 66};
 67
 68static int __devinit adxl34x_spi_probe(struct spi_device *spi)
 69{
 70	struct adxl34x *ac;
 71
 72	/* don't exceed max specified SPI CLK frequency */
 73	if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
 74		dev_err(&spi->dev, "SPI CLK %d Hz too fast\n", spi->max_speed_hz);
 75		return -EINVAL;
 76	}
 77
 78	ac = adxl34x_probe(&spi->dev, spi->irq,
 79			   spi->max_speed_hz > MAX_FREQ_NO_FIFODELAY,
 80			   &adxl34x_spi_bops);
 81
 82	if (IS_ERR(ac))
 83		return PTR_ERR(ac);
 84
 85	spi_set_drvdata(spi, ac);
 86
 87	return 0;
 88}
 89
 90static int __devexit adxl34x_spi_remove(struct spi_device *spi)
 91{
 92	struct adxl34x *ac = dev_get_drvdata(&spi->dev);
 93
 94	return adxl34x_remove(ac);
 95}
 96
 97#ifdef CONFIG_PM
 98static int adxl34x_spi_suspend(struct device *dev)
 99{
100	struct spi_device *spi = to_spi_device(dev);
101	struct adxl34x *ac = dev_get_drvdata(&spi->dev);
102
103	adxl34x_suspend(ac);
104
105	return 0;
106}
107
108static int adxl34x_spi_resume(struct device *dev)
109{
110	struct spi_device *spi = to_spi_device(dev);
111	struct adxl34x *ac = dev_get_drvdata(&spi->dev);
112
113	adxl34x_resume(ac);
114
115	return 0;
116}
117#endif
118
119static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend,
120			 adxl34x_spi_resume);
121
122static struct spi_driver adxl34x_driver = {
123	.driver = {
124		.name = "adxl34x",
125		.bus = &spi_bus_type,
126		.owner = THIS_MODULE,
127		.pm = &adxl34x_spi_pm,
128	},
129	.probe   = adxl34x_spi_probe,
130	.remove  = __devexit_p(adxl34x_spi_remove),
131};
132
133static int __init adxl34x_spi_init(void)
134{
135	return spi_register_driver(&adxl34x_driver);
136}
137module_init(adxl34x_spi_init);
138
139static void __exit adxl34x_spi_exit(void)
140{
141	spi_unregister_driver(&adxl34x_driver);
142}
143module_exit(adxl34x_spi_exit);
144
145MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
146MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer SPI Bus Driver");
147MODULE_LICENSE("GPL");
v3.5.6
  1/*
  2 * ADLX345/346 Three-Axis Digital Accelerometers (SPI Interface)
  3 *
  4 * Enter bugs at http://blackfin.uclinux.org/
  5 *
  6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
  7 * Licensed under the GPL-2 or later.
  8 */
  9
 10#include <linux/input.h>	/* BUS_SPI */
 11#include <linux/module.h>
 12#include <linux/spi/spi.h>
 13#include <linux/pm.h>
 14#include <linux/types.h>
 15#include "adxl34x.h"
 16
 17#define MAX_SPI_FREQ_HZ		5000000
 18#define MAX_FREQ_NO_FIFODELAY	1500000
 19#define ADXL34X_CMD_MULTB	(1 << 6)
 20#define ADXL34X_CMD_READ	(1 << 7)
 21#define ADXL34X_WRITECMD(reg)	(reg & 0x3F)
 22#define ADXL34X_READCMD(reg)	(ADXL34X_CMD_READ | (reg & 0x3F))
 23#define ADXL34X_READMB_CMD(reg) (ADXL34X_CMD_READ | ADXL34X_CMD_MULTB \
 24					| (reg & 0x3F))
 25
 26static int adxl34x_spi_read(struct device *dev, unsigned char reg)
 27{
 28	struct spi_device *spi = to_spi_device(dev);
 29	unsigned char cmd;
 30
 31	cmd = ADXL34X_READCMD(reg);
 32
 33	return spi_w8r8(spi, cmd);
 34}
 35
 36static int adxl34x_spi_write(struct device *dev,
 37			     unsigned char reg, unsigned char val)
 38{
 39	struct spi_device *spi = to_spi_device(dev);
 40	unsigned char buf[2];
 41
 42	buf[0] = ADXL34X_WRITECMD(reg);
 43	buf[1] = val;
 44
 45	return spi_write(spi, buf, sizeof(buf));
 46}
 47
 48static int adxl34x_spi_read_block(struct device *dev,
 49				  unsigned char reg, int count,
 50				  void *buf)
 51{
 52	struct spi_device *spi = to_spi_device(dev);
 53	ssize_t status;
 54
 55	reg = ADXL34X_READMB_CMD(reg);
 56	status = spi_write_then_read(spi, &reg, 1, buf, count);
 57
 58	return (status < 0) ? status : 0;
 59}
 60
 61static const struct adxl34x_bus_ops adxl34x_spi_bops = {
 62	.bustype	= BUS_SPI,
 63	.write		= adxl34x_spi_write,
 64	.read		= adxl34x_spi_read,
 65	.read_block	= adxl34x_spi_read_block,
 66};
 67
 68static int __devinit adxl34x_spi_probe(struct spi_device *spi)
 69{
 70	struct adxl34x *ac;
 71
 72	/* don't exceed max specified SPI CLK frequency */
 73	if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
 74		dev_err(&spi->dev, "SPI CLK %d Hz too fast\n", spi->max_speed_hz);
 75		return -EINVAL;
 76	}
 77
 78	ac = adxl34x_probe(&spi->dev, spi->irq,
 79			   spi->max_speed_hz > MAX_FREQ_NO_FIFODELAY,
 80			   &adxl34x_spi_bops);
 81
 82	if (IS_ERR(ac))
 83		return PTR_ERR(ac);
 84
 85	spi_set_drvdata(spi, ac);
 86
 87	return 0;
 88}
 89
 90static int __devexit adxl34x_spi_remove(struct spi_device *spi)
 91{
 92	struct adxl34x *ac = dev_get_drvdata(&spi->dev);
 93
 94	return adxl34x_remove(ac);
 95}
 96
 97#ifdef CONFIG_PM
 98static int adxl34x_spi_suspend(struct device *dev)
 99{
100	struct spi_device *spi = to_spi_device(dev);
101	struct adxl34x *ac = dev_get_drvdata(&spi->dev);
102
103	adxl34x_suspend(ac);
104
105	return 0;
106}
107
108static int adxl34x_spi_resume(struct device *dev)
109{
110	struct spi_device *spi = to_spi_device(dev);
111	struct adxl34x *ac = dev_get_drvdata(&spi->dev);
112
113	adxl34x_resume(ac);
114
115	return 0;
116}
117#endif
118
119static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend,
120			 adxl34x_spi_resume);
121
122static struct spi_driver adxl34x_driver = {
123	.driver = {
124		.name = "adxl34x",
 
125		.owner = THIS_MODULE,
126		.pm = &adxl34x_spi_pm,
127	},
128	.probe   = adxl34x_spi_probe,
129	.remove  = __devexit_p(adxl34x_spi_remove),
130};
131
132module_spi_driver(adxl34x_driver);
 
 
 
 
 
 
 
 
 
 
133
134MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
135MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer SPI Bus Driver");
136MODULE_LICENSE("GPL");