kxsd9.c (ab04f734b08a404550ba5f8391307bad2145acff) | kxsd9.c (0d1fb2d52d8b4a1124cb2db7d22c4131ad5805cf) |
---|---|
1/* 2 * kxsd9.c simple support for the Kionix KXSD9 3D 3 * accelerometer. 4 * 5 * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 7 unchanged lines hidden (view full) --- 16 * heavily optimized ring buffer access function. 17 */ 18 19#include <linux/device.h> 20#include <linux/kernel.h> 21#include <linux/sysfs.h> 22#include <linux/slab.h> 23#include <linux/module.h> | 1/* 2 * kxsd9.c simple support for the Kionix KXSD9 3D 3 * accelerometer. 4 * 5 * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 7 unchanged lines hidden (view full) --- 16 * heavily optimized ring buffer access function. 17 */ 18 19#include <linux/device.h> 20#include <linux/kernel.h> 21#include <linux/sysfs.h> 22#include <linux/slab.h> 23#include <linux/module.h> |
24 | 24#include <linux/regmap.h> |
25#include <linux/iio/iio.h> 26#include <linux/iio/sysfs.h> 27 28#include "kxsd9.h" 29 30#define KXSD9_REG_X 0x00 31#define KXSD9_REG_Y 0x02 32#define KXSD9_REG_Z 0x04 --- 8 unchanged lines hidden (view full) --- 41 42/** 43 * struct kxsd9_state - device related storage 44 * @transport: transport for the KXSD9 45 * @buf_lock: protect the rx and tx buffers. 46 * @us: spi device 47 **/ 48struct kxsd9_state { | 25#include <linux/iio/iio.h> 26#include <linux/iio/sysfs.h> 27 28#include "kxsd9.h" 29 30#define KXSD9_REG_X 0x00 31#define KXSD9_REG_Y 0x02 32#define KXSD9_REG_Z 0x04 --- 8 unchanged lines hidden (view full) --- 41 42/** 43 * struct kxsd9_state - device related storage 44 * @transport: transport for the KXSD9 45 * @buf_lock: protect the rx and tx buffers. 46 * @us: spi device 47 **/ 48struct kxsd9_state { |
49 struct kxsd9_transport *transport; | 49 struct regmap *map; |
50 struct mutex buf_lock; 51}; 52 53#define KXSD9_SCALE_2G "0.011978" 54#define KXSD9_SCALE_4G "0.023927" 55#define KXSD9_SCALE_6G "0.035934" 56#define KXSD9_SCALE_8G "0.047853" 57 58/* reverse order */ 59static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 }; 60 61static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) 62{ 63 int ret, i; 64 struct kxsd9_state *st = iio_priv(indio_dev); 65 bool foundit = false; | 50 struct mutex buf_lock; 51}; 52 53#define KXSD9_SCALE_2G "0.011978" 54#define KXSD9_SCALE_4G "0.023927" 55#define KXSD9_SCALE_6G "0.035934" 56#define KXSD9_SCALE_8G "0.047853" 57 58/* reverse order */ 59static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 }; 60 61static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) 62{ 63 int ret, i; 64 struct kxsd9_state *st = iio_priv(indio_dev); 65 bool foundit = false; |
66 unsigned int val; |
|
66 67 for (i = 0; i < 4; i++) 68 if (micro == kxsd9_micro_scales[i]) { 69 foundit = true; 70 break; 71 } 72 if (!foundit) 73 return -EINVAL; 74 75 mutex_lock(&st->buf_lock); | 67 68 for (i = 0; i < 4; i++) 69 if (micro == kxsd9_micro_scales[i]) { 70 foundit = true; 71 break; 72 } 73 if (!foundit) 74 return -EINVAL; 75 76 mutex_lock(&st->buf_lock); |
76 ret = st->transport->readreg(st->transport, 77 KXSD9_REG_CTRL_C); | 77 ret = regmap_read(st->map, 78 KXSD9_REG_CTRL_C, 79 &val); |
78 if (ret < 0) 79 goto error_ret; | 80 if (ret < 0) 81 goto error_ret; |
80 ret = st->transport->writereg(st->transport, 81 KXSD9_REG_CTRL_C, 82 (ret & ~KXSD9_FS_MASK) | i); | 82 ret = regmap_write(st->map, 83 KXSD9_REG_CTRL_C, 84 (val & ~KXSD9_FS_MASK) | i); |
83error_ret: 84 mutex_unlock(&st->buf_lock); 85 return ret; 86} 87 88static int kxsd9_read(struct iio_dev *indio_dev, u8 address) 89{ 90 int ret; 91 struct kxsd9_state *st = iio_priv(indio_dev); | 85error_ret: 86 mutex_unlock(&st->buf_lock); 87 return ret; 88} 89 90static int kxsd9_read(struct iio_dev *indio_dev, u8 address) 91{ 92 int ret; 93 struct kxsd9_state *st = iio_priv(indio_dev); |
94 __be16 raw_val; |
|
92 93 mutex_lock(&st->buf_lock); | 95 96 mutex_lock(&st->buf_lock); |
94 ret = st->transport->readval(st->transport, address); | 97 ret = regmap_bulk_read(st->map, address, &raw_val, sizeof(raw_val)); 98 if (ret) 99 goto out_fail_read; |
95 /* Only 12 bits are valid */ | 100 /* Only 12 bits are valid */ |
96 ret &= 0xfff0; | 101 ret = be16_to_cpu(raw_val) & 0xfff0; 102out_fail_read: |
97 mutex_unlock(&st->buf_lock); 98 return ret; 99} 100 101static IIO_CONST_ATTR(accel_scale_available, 102 KXSD9_SCALE_2G " " 103 KXSD9_SCALE_4G " " 104 KXSD9_SCALE_6G " " --- 23 unchanged lines hidden (view full) --- 128} 129 130static int kxsd9_read_raw(struct iio_dev *indio_dev, 131 struct iio_chan_spec const *chan, 132 int *val, int *val2, long mask) 133{ 134 int ret = -EINVAL; 135 struct kxsd9_state *st = iio_priv(indio_dev); | 103 mutex_unlock(&st->buf_lock); 104 return ret; 105} 106 107static IIO_CONST_ATTR(accel_scale_available, 108 KXSD9_SCALE_2G " " 109 KXSD9_SCALE_4G " " 110 KXSD9_SCALE_6G " " --- 23 unchanged lines hidden (view full) --- 134} 135 136static int kxsd9_read_raw(struct iio_dev *indio_dev, 137 struct iio_chan_spec const *chan, 138 int *val, int *val2, long mask) 139{ 140 int ret = -EINVAL; 141 struct kxsd9_state *st = iio_priv(indio_dev); |
142 unsigned int regval; |
|
136 137 switch (mask) { 138 case IIO_CHAN_INFO_RAW: 139 ret = kxsd9_read(indio_dev, chan->address); 140 if (ret < 0) 141 goto error_ret; 142 *val = ret; 143 ret = IIO_VAL_INT; 144 break; 145 case IIO_CHAN_INFO_SCALE: | 143 144 switch (mask) { 145 case IIO_CHAN_INFO_RAW: 146 ret = kxsd9_read(indio_dev, chan->address); 147 if (ret < 0) 148 goto error_ret; 149 *val = ret; 150 ret = IIO_VAL_INT; 151 break; 152 case IIO_CHAN_INFO_SCALE: |
146 ret = st->transport->readreg(st->transport, 147 KXSD9_REG_CTRL_C); | 153 ret = regmap_read(st->map, 154 KXSD9_REG_CTRL_C, 155 ®val); |
148 if (ret < 0) 149 goto error_ret; 150 *val = 0; | 156 if (ret < 0) 157 goto error_ret; 158 *val = 0; |
151 *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; | 159 *val2 = kxsd9_micro_scales[regval & KXSD9_FS_MASK]; |
152 ret = IIO_VAL_INT_PLUS_MICRO; 153 break; 154 } 155 156error_ret: 157 return ret; 158}; 159#define KXSD9_ACCEL_CHAN(axis) \ --- 19 unchanged lines hidden (view full) --- 179static const struct attribute_group kxsd9_attribute_group = { 180 .attrs = kxsd9_attributes, 181}; 182 183static int kxsd9_power_up(struct kxsd9_state *st) 184{ 185 int ret; 186 | 160 ret = IIO_VAL_INT_PLUS_MICRO; 161 break; 162 } 163 164error_ret: 165 return ret; 166}; 167#define KXSD9_ACCEL_CHAN(axis) \ --- 19 unchanged lines hidden (view full) --- 187static const struct attribute_group kxsd9_attribute_group = { 188 .attrs = kxsd9_attributes, 189}; 190 191static int kxsd9_power_up(struct kxsd9_state *st) 192{ 193 int ret; 194 |
187 ret = st->transport->writereg(st->transport, KXSD9_REG_CTRL_B, 0x40); | 195 ret = regmap_write(st->map, KXSD9_REG_CTRL_B, 0x40); |
188 if (ret) 189 return ret; | 196 if (ret) 197 return ret; |
190 return st->transport->writereg(st->transport, KXSD9_REG_CTRL_C, 0x9b); | 198 return regmap_write(st->map, KXSD9_REG_CTRL_C, 0x9b); |
191}; 192 193static const struct iio_info kxsd9_info = { 194 .read_raw = &kxsd9_read_raw, 195 .write_raw = &kxsd9_write_raw, 196 .attrs = &kxsd9_attribute_group, 197 .driver_module = THIS_MODULE, 198}; 199 200int kxsd9_common_probe(struct device *parent, | 199}; 200 201static const struct iio_info kxsd9_info = { 202 .read_raw = &kxsd9_read_raw, 203 .write_raw = &kxsd9_write_raw, 204 .attrs = &kxsd9_attribute_group, 205 .driver_module = THIS_MODULE, 206}; 207 208int kxsd9_common_probe(struct device *parent, |
201 struct kxsd9_transport *transport, | 209 struct regmap *map, |
202 const char *name) 203{ 204 struct iio_dev *indio_dev; 205 struct kxsd9_state *st; 206 int ret; 207 208 indio_dev = devm_iio_device_alloc(parent, sizeof(*st)); 209 if (!indio_dev) 210 return -ENOMEM; 211 212 st = iio_priv(indio_dev); | 210 const char *name) 211{ 212 struct iio_dev *indio_dev; 213 struct kxsd9_state *st; 214 int ret; 215 216 indio_dev = devm_iio_device_alloc(parent, sizeof(*st)); 217 if (!indio_dev) 218 return -ENOMEM; 219 220 st = iio_priv(indio_dev); |
213 st->transport = transport; | 221 st->map = map; |
214 215 mutex_init(&st->buf_lock); 216 indio_dev->channels = kxsd9_channels; 217 indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels); 218 indio_dev->name = name; 219 indio_dev->dev.parent = parent; 220 indio_dev->info = &kxsd9_info; 221 indio_dev->modes = INDIO_DIRECT_MODE; --- 26 unchanged lines hidden --- | 222 223 mutex_init(&st->buf_lock); 224 indio_dev->channels = kxsd9_channels; 225 indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels); 226 indio_dev->name = name; 227 indio_dev->dev.parent = parent; 228 indio_dev->info = &kxsd9_info; 229 indio_dev->modes = INDIO_DIRECT_MODE; --- 26 unchanged lines hidden --- |