linux/drivers/staging/iio/magnetometer/hmc5843.c
<<
>>
Prefs
   1/*  Copyright (C) 2010 Texas Instruments
   2    Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
   3    Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
   4
   5    This program is free software; you can redistribute it and/or modify
   6    it under the terms of the GNU General Public License as published by
   7    the Free Software Foundation; either version 2 of the License, or
   8    (at your option) any later version.
   9
  10    This program is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU General Public License for more details.
  14
  15    You should have received a copy of the GNU General Public License
  16    along with this program; if not, write to the Free Software
  17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18*/
  19
  20#include <linux/module.h>
  21#include <linux/init.h>
  22#include <linux/i2c.h>
  23#include <linux/slab.h>
  24#include <linux/types.h>
  25#include "../iio.h"
  26#include "../sysfs.h"
  27#include "magnet.h"
  28
  29#define HMC5843_I2C_ADDRESS                     0x1E
  30
  31#define HMC5843_CONFIG_REG_A                    0x00
  32#define HMC5843_CONFIG_REG_B                    0x01
  33#define HMC5843_MODE_REG                        0x02
  34#define HMC5843_DATA_OUT_X_MSB_REG              0x03
  35#define HMC5843_DATA_OUT_X_LSB_REG              0x04
  36#define HMC5843_DATA_OUT_Y_MSB_REG              0x05
  37#define HMC5843_DATA_OUT_Y_LSB_REG              0x06
  38#define HMC5843_DATA_OUT_Z_MSB_REG              0x07
  39#define HMC5843_DATA_OUT_Z_LSB_REG              0x08
  40#define HMC5843_STATUS_REG                      0x09
  41#define HMC5843_ID_REG_A                        0x0A
  42#define HMC5843_ID_REG_B                        0x0B
  43#define HMC5843_ID_REG_C                        0x0C
  44
  45#define HMC5843_ID_REG_LENGTH                   0x03
  46#define HMC5843_ID_STRING                       "H43"
  47
  48/*
  49 * Range settings in  (+-)Ga
  50 * */
  51#define RANGE_GAIN_OFFSET                       0x05
  52
  53#define RANGE_0_7                               0x00
  54#define RANGE_1_0                               0x01 /* default */
  55#define RANGE_1_5                               0x02
  56#define RANGE_2_0                               0x03
  57#define RANGE_3_2                               0x04
  58#define RANGE_3_8                               0x05
  59#define RANGE_4_5                               0x06
  60#define RANGE_6_5                               0x07 /* Not recommended */
  61
  62/*
  63 * Device status
  64 */
  65#define DATA_READY                              0x01
  66#define DATA_OUTPUT_LOCK                        0x02
  67#define VOLTAGE_REGULATOR_ENABLED               0x04
  68
  69/*
  70 * Mode register configuration
  71 */
  72#define MODE_CONVERSION_CONTINUOUS              0x00
  73#define MODE_CONVERSION_SINGLE                  0x01
  74#define MODE_IDLE                               0x02
  75#define MODE_SLEEP                              0x03
  76
  77/* Minimum Data Output Rate in 1/10 Hz  */
  78#define RATE_OFFSET                             0x02
  79#define RATE_BITMASK                            0x1C
  80#define RATE_5                                  0x00
  81#define RATE_10                                 0x01
  82#define RATE_20                                 0x02
  83#define RATE_50                                 0x03
  84#define RATE_100                                0x04
  85#define RATE_200                                0x05
  86#define RATE_500                                0x06
  87#define RATE_NOT_USED                           0x07
  88
  89/*
  90 * Device Configutration
  91 */
  92#define CONF_NORMAL                             0x00
  93#define CONF_POSITIVE_BIAS                      0x01
  94#define CONF_NEGATIVE_BIAS                      0x02
  95#define CONF_NOT_USED                           0x03
  96#define MEAS_CONF_MASK                          0x03
  97
  98static const char *regval_to_scale[] = {
  99        "0.0000006173",
 100        "0.0000007692",
 101        "0.0000010309",
 102        "0.0000012821",
 103        "0.0000018868",
 104        "0.0000021739",
 105        "0.0000025641",
 106        "0.0000035714",
 107};
 108static const int regval_to_input_field_mg[] = {
 109        700,
 110        1000,
 111        1500,
 112        2000,
 113        3200,
 114        3800,
 115        4500,
 116        6500
 117};
 118static const char *regval_to_samp_freq[] = {
 119        "0.5",
 120        "1",
 121        "2",
 122        "5",
 123        "10",
 124        "20",
 125        "50",
 126};
 127
 128/* Addresses to scan: 0x1E */
 129static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
 130                                                        I2C_CLIENT_END };
 131
 132/* Each client has this additional data */
 133struct hmc5843_data {
 134        struct iio_dev  *indio_dev;
 135        struct mutex lock;
 136        u8              rate;
 137        u8              meas_conf;
 138        u8              operating_mode;
 139        u8              range;
 140};
 141
 142static void hmc5843_init_client(struct i2c_client *client);
 143
 144static s32 hmc5843_configure(struct i2c_client *client,
 145                                       u8 operating_mode)
 146{
 147        /* The lower two bits contain the current conversion mode */
 148        return i2c_smbus_write_byte_data(client,
 149                                        HMC5843_MODE_REG,
 150                                        (operating_mode & 0x03));
 151}
 152
 153/* Return the measurement value from the  specified channel */
 154static ssize_t hmc5843_read_measurement(struct device *dev,
 155                struct device_attribute *attr,
 156                char *buf)
 157{
 158        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 159        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 160        s16 coordinate_val;
 161        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 162        struct hmc5843_data *data = indio_dev->dev_data;
 163        s32 result;
 164
 165        mutex_lock(&data->lock);
 166
 167        result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
 168        while (!(result & DATA_READY))
 169                result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
 170
 171        result = i2c_smbus_read_word_data(client, this_attr->address);
 172        mutex_unlock(&data->lock);
 173        if (result < 0)
 174                return -EINVAL;
 175
 176        coordinate_val  = (s16)swab16((u16)result);
 177        return sprintf(buf, "%d\n", coordinate_val);
 178}
 179static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
 180                HMC5843_DATA_OUT_X_MSB_REG);
 181static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
 182                HMC5843_DATA_OUT_Y_MSB_REG);
 183static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
 184                HMC5843_DATA_OUT_Z_MSB_REG);
 185
 186/*
 187 * From the datasheet
 188 * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
 189 * device continuously performs conversions an places the result in the
 190 * data register.
 191 *
 192 * 1 - Single-Conversion Mode : device performs a single measurement,
 193 *  sets RDY high and returned to sleep mode
 194 *
 195 * 2 - Idle Mode :  Device is placed in idle mode.
 196 *
 197 * 3 - Sleep Mode. Device is placed in sleep mode.
 198 *
 199 */
 200static ssize_t hmc5843_show_operating_mode(struct device *dev,
 201                                        struct device_attribute *attr,
 202                                        char *buf)
 203{
 204        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 205        struct hmc5843_data *data = indio_dev->dev_data;
 206        return sprintf(buf, "%d\n", data->operating_mode);
 207}
 208
 209static ssize_t hmc5843_set_operating_mode(struct device *dev,
 210                                struct device_attribute *attr,
 211                                const char *buf,
 212                                size_t count)
 213{
 214        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 215        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 216        struct hmc5843_data *data = indio_dev->dev_data;
 217        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 218        unsigned long operating_mode = 0;
 219        s32 status;
 220        int error;
 221        mutex_lock(&data->lock);
 222        error = strict_strtoul(buf, 10, &operating_mode);
 223        if (error) {
 224                count = error;
 225                goto exit;
 226        }
 227        dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
 228        if (operating_mode > MODE_SLEEP) {
 229                count = -EINVAL;
 230                goto exit;
 231        }
 232
 233        status = i2c_smbus_write_byte_data(client, this_attr->address,
 234                                        operating_mode);
 235        if (status) {
 236                count = -EINVAL;
 237                goto exit;
 238        }
 239        data->operating_mode = operating_mode;
 240
 241exit:
 242        mutex_unlock(&data->lock);
 243        return count;
 244}
 245static IIO_DEVICE_ATTR(operating_mode,
 246                        S_IWUSR | S_IRUGO,
 247                        hmc5843_show_operating_mode,
 248                        hmc5843_set_operating_mode,
 249                        HMC5843_MODE_REG);
 250
 251/*
 252 * API for setting the measurement configuration to
 253 * Normal, Positive bias and Negative bias
 254 * From the datasheet
 255 *
 256 * Normal measurement configuration (default): In normal measurement
 257 * configuration the device follows normal measurement flow. Pins BP and BN
 258 * are left floating and high impedance.
 259 *
 260 * Positive bias configuration: In positive bias configuration, a positive
 261 * current is forced across the resistive load on pins BP and BN.
 262 *
 263 * Negative bias configuration. In negative bias configuration, a negative
 264 * current is forced across the resistive load on pins BP and BN.
 265 *
 266 */
 267static s32 hmc5843_set_meas_conf(struct i2c_client *client,
 268                                      u8 meas_conf)
 269{
 270        struct hmc5843_data *data = i2c_get_clientdata(client);
 271        u8 reg_val;
 272        reg_val = (meas_conf & MEAS_CONF_MASK) |  (data->rate << RATE_OFFSET);
 273        return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
 274}
 275
 276static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
 277                                                struct device_attribute *attr,
 278                                                char *buf)
 279{
 280        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 281        struct hmc5843_data *data = indio_dev->dev_data;
 282        return sprintf(buf, "%d\n", data->meas_conf);
 283}
 284
 285static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
 286                                                struct device_attribute *attr,
 287                                                const char *buf,
 288                                                size_t count)
 289{
 290        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 291        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 292        struct hmc5843_data *data = i2c_get_clientdata(client);
 293        unsigned long meas_conf = 0;
 294        int error = strict_strtoul(buf, 10, &meas_conf);
 295        if (error)
 296                return error;
 297        mutex_lock(&data->lock);
 298
 299        dev_dbg(dev, "set mode to %lu\n", meas_conf);
 300        if (hmc5843_set_meas_conf(client, meas_conf)) {
 301                count = -EINVAL;
 302                goto exit;
 303        }
 304        data->meas_conf = meas_conf;
 305
 306exit:
 307        mutex_unlock(&data->lock);
 308        return count;
 309}
 310static IIO_DEVICE_ATTR(meas_conf,
 311                        S_IWUSR | S_IRUGO,
 312                        hmc5843_show_measurement_configuration,
 313                        hmc5843_set_measurement_configuration,
 314                        0);
 315
 316/*
 317 * From Datasheet
 318 * The table shows the minimum data output
 319 * Value        | Minimum data output rate(Hz)
 320 * 0            | 0.5
 321 * 1            | 1
 322 * 2            | 2
 323 * 3            | 5
 324 * 4            | 10 (default)
 325 * 5            | 20
 326 * 6            | 50
 327 * 7            | Not used
 328 */
 329static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
 330
 331static s32 hmc5843_set_rate(struct i2c_client *client,
 332                                u8 rate)
 333{
 334        struct hmc5843_data *data = i2c_get_clientdata(client);
 335        u8 reg_val;
 336
 337        reg_val = (data->meas_conf) |  (rate << RATE_OFFSET);
 338        if (rate >= RATE_NOT_USED) {
 339                dev_err(&client->dev,
 340                        "This data output rate is not supported \n");
 341                return -EINVAL;
 342        }
 343        return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
 344}
 345
 346static ssize_t set_sampling_frequency(struct device *dev,
 347                                        struct device_attribute *attr,
 348                                        const char *buf, size_t count)
 349{
 350
 351        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 352        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 353        struct hmc5843_data *data = indio_dev->dev_data;
 354        unsigned long rate = 0;
 355
 356        if (strncmp(buf, "0.5" , 3) == 0)
 357                rate = RATE_5;
 358        else if (strncmp(buf, "1" , 1) == 0)
 359                rate = RATE_10;
 360        else if (strncmp(buf, "2", 1) == 0)
 361                rate = RATE_20;
 362        else if (strncmp(buf, "5", 1) == 0)
 363                rate = RATE_50;
 364        else if (strncmp(buf, "10", 2) == 0)
 365                rate = RATE_100;
 366        else if (strncmp(buf, "20" , 2) == 0)
 367                rate = RATE_200;
 368        else if (strncmp(buf, "50" , 2) == 0)
 369                rate = RATE_500;
 370        else
 371                return -EINVAL;
 372
 373        mutex_lock(&data->lock);
 374        dev_dbg(dev, "set rate to %lu\n", rate);
 375        if (hmc5843_set_rate(client, rate)) {
 376                count = -EINVAL;
 377                goto exit;
 378        }
 379        data->rate = rate;
 380
 381exit:
 382        mutex_unlock(&data->lock);
 383        return count;
 384}
 385
 386static ssize_t show_sampling_frequency(struct device *dev,
 387                        struct device_attribute *attr, char *buf)
 388{
 389        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 390        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 391        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 392        s32 rate;
 393
 394        rate = i2c_smbus_read_byte_data(client,  this_attr->address);
 395        if (rate < 0)
 396                return rate;
 397        rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
 398        return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
 399}
 400static IIO_DEVICE_ATTR(sampling_frequency,
 401                        S_IWUSR | S_IRUGO,
 402                        show_sampling_frequency,
 403                        set_sampling_frequency,
 404                        HMC5843_CONFIG_REG_A);
 405
 406/*
 407 * From Datasheet
 408 *      Nominal gain settings
 409 * Value        | Sensor Input Field Range(Ga)  | Gain(counts/ milli-gauss)
 410 *0             |(+-)0.7                        |1620
 411 *1             |(+-)1.0                        |1300
 412 *2             |(+-)1.5                        |970
 413 *3             |(+-)2.0                        |780
 414 *4             |(+-)3.2                        |530
 415 *5             |(+-)3.8                        |460
 416 *6             |(+-)4.5                        |390
 417 *7             |(+-)6.5                        |280
 418 */
 419static ssize_t show_range(struct device *dev,
 420                                struct device_attribute *attr,
 421                                char *buf)
 422{
 423        u8 range;
 424        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 425        struct hmc5843_data *data = indio_dev->dev_data;
 426
 427        range = data->range;
 428        return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
 429}
 430
 431static ssize_t set_range(struct device *dev,
 432                        struct device_attribute *attr,
 433                        const char *buf,
 434                        size_t count)
 435{
 436        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 437        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 438        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 439        struct hmc5843_data *data = indio_dev->dev_data;
 440        unsigned long range = 0;
 441        int error;
 442        mutex_lock(&data->lock);
 443        error = strict_strtoul(buf, 10, &range);
 444        if (error) {
 445                count = error;
 446                goto exit;
 447        }
 448        dev_dbg(dev, "set range to %lu\n", range);
 449
 450        if (range > RANGE_6_5) {
 451                count = -EINVAL;
 452                goto exit;
 453        }
 454
 455        data->range = range;
 456        range = range << RANGE_GAIN_OFFSET;
 457        if (i2c_smbus_write_byte_data(client, this_attr->address, range))
 458                count = -EINVAL;
 459
 460exit:
 461        mutex_unlock(&data->lock);
 462        return count;
 463
 464}
 465static IIO_DEVICE_ATTR(magn_range,
 466                        S_IWUSR | S_IRUGO,
 467                        show_range,
 468                        set_range,
 469                        HMC5843_CONFIG_REG_B);
 470
 471static ssize_t show_scale(struct device *dev,
 472                        struct device_attribute *attr,
 473                        char *buf)
 474{
 475        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 476        struct hmc5843_data *data = indio_dev->dev_data;
 477        return strlen(strcpy(buf, regval_to_scale[data->range]));
 478}
 479static IIO_DEVICE_ATTR(magn_scale,
 480                        S_IRUGO,
 481                        show_scale,
 482                        NULL , 0);
 483
 484static struct attribute *hmc5843_attributes[] = {
 485        &iio_dev_attr_meas_conf.dev_attr.attr,
 486        &iio_dev_attr_operating_mode.dev_attr.attr,
 487        &iio_dev_attr_sampling_frequency.dev_attr.attr,
 488        &iio_dev_attr_magn_range.dev_attr.attr,
 489        &iio_dev_attr_magn_scale.dev_attr.attr,
 490        &iio_dev_attr_magn_x_raw.dev_attr.attr,
 491        &iio_dev_attr_magn_y_raw.dev_attr.attr,
 492        &iio_dev_attr_magn_z_raw.dev_attr.attr,
 493        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 494        NULL
 495};
 496
 497static const struct attribute_group hmc5843_group = {
 498        .attrs = hmc5843_attributes,
 499};
 500
 501static int hmc5843_detect(struct i2c_client *client,
 502                          struct i2c_board_info *info)
 503{
 504        unsigned char id_str[HMC5843_ID_REG_LENGTH];
 505
 506        if (client->addr != HMC5843_I2C_ADDRESS)
 507                return -ENODEV;
 508
 509        if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
 510                                HMC5843_ID_REG_LENGTH, id_str)
 511                        != HMC5843_ID_REG_LENGTH)
 512                return -ENODEV;
 513
 514        if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
 515                return -ENODEV;
 516
 517        return 0;
 518}
 519
 520/* Called when we have found a new HMC5843. */
 521static void hmc5843_init_client(struct i2c_client *client)
 522{
 523        struct hmc5843_data *data = i2c_get_clientdata(client);
 524        hmc5843_set_meas_conf(client, data->meas_conf);
 525        hmc5843_set_rate(client, data->rate);
 526        hmc5843_configure(client, data->operating_mode);
 527        i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
 528        mutex_init(&data->lock);
 529        pr_info("HMC5843 initialized\n");
 530}
 531
 532static int hmc5843_probe(struct i2c_client *client,
 533                         const struct i2c_device_id *id)
 534{
 535        struct hmc5843_data *data;
 536        int err = 0;
 537
 538        data = kzalloc(sizeof(struct hmc5843_data), GFP_KERNEL);
 539        if (!data) {
 540                err = -ENOMEM;
 541                goto exit;
 542        }
 543
 544        /* default settings at probe */
 545
 546        data->meas_conf = CONF_NORMAL;
 547        data->range = RANGE_1_0;
 548        data->operating_mode = MODE_CONVERSION_CONTINUOUS;
 549
 550        i2c_set_clientdata(client, data);
 551
 552        /* Initialize the HMC5843 chip */
 553        hmc5843_init_client(client);
 554
 555        data->indio_dev = iio_allocate_device();
 556        if (!data->indio_dev) {
 557                err = -ENOMEM;
 558                goto exit_free1;
 559        }
 560        data->indio_dev->attrs = &hmc5843_group;
 561        data->indio_dev->dev.parent = &client->dev;
 562        data->indio_dev->dev_data = (void *)(data);
 563        data->indio_dev->driver_module = THIS_MODULE;
 564        data->indio_dev->modes = INDIO_DIRECT_MODE;
 565        err = iio_device_register(data->indio_dev);
 566        if (err)
 567                goto exit_free2;
 568        return 0;
 569exit_free2:
 570        iio_free_device(data->indio_dev);
 571exit_free1:
 572        kfree(data);
 573exit:
 574        return err;
 575}
 576
 577static int hmc5843_remove(struct i2c_client *client)
 578{
 579        struct hmc5843_data *data = i2c_get_clientdata(client);
 580         /*  sleep mode to save power */
 581        hmc5843_configure(client, MODE_SLEEP);
 582        iio_device_unregister(data->indio_dev);
 583        kfree(i2c_get_clientdata(client));
 584        return 0;
 585}
 586
 587static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
 588{
 589        hmc5843_configure(client, MODE_SLEEP);
 590        return 0;
 591}
 592
 593static int hmc5843_resume(struct i2c_client *client)
 594{
 595        struct hmc5843_data *data = i2c_get_clientdata(client);
 596        hmc5843_configure(client, data->operating_mode);
 597        return 0;
 598}
 599
 600static const struct i2c_device_id hmc5843_id[] = {
 601        { "hmc5843", 0 },
 602        { }
 603};
 604
 605static struct i2c_driver hmc5843_driver = {
 606        .driver = {
 607                .name   = "hmc5843",
 608        },
 609        .id_table       = hmc5843_id,
 610        .probe          = hmc5843_probe,
 611        .remove         = hmc5843_remove,
 612        .detect         = hmc5843_detect,
 613        .address_list   = normal_i2c,
 614        .suspend        = hmc5843_suspend,
 615        .resume         = hmc5843_resume,
 616};
 617
 618static int __init hmc5843_init(void)
 619{
 620        return i2c_add_driver(&hmc5843_driver);
 621}
 622
 623static void __exit hmc5843_exit(void)
 624{
 625        i2c_del_driver(&hmc5843_driver);
 626}
 627
 628MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
 629MODULE_DESCRIPTION("HMC5843 driver");
 630MODULE_LICENSE("GPL");
 631
 632module_init(hmc5843_init);
 633module_exit(hmc5843_exit);
 634