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 mutex lock;
 135        u8              rate;
 136        u8              meas_conf;
 137        u8              operating_mode;
 138        u8              range;
 139};
 140
 141static void hmc5843_init_client(struct i2c_client *client);
 142
 143static s32 hmc5843_configure(struct i2c_client *client,
 144                                       u8 operating_mode)
 145{
 146        /* The lower two bits contain the current conversion mode */
 147        return i2c_smbus_write_byte_data(client,
 148                                        HMC5843_MODE_REG,
 149                                        (operating_mode & 0x03));
 150}
 151
 152/* Return the measurement value from the  specified channel */
 153static ssize_t hmc5843_read_measurement(struct device *dev,
 154                struct device_attribute *attr,
 155                char *buf)
 156{
 157        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 158        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 159        s16 coordinate_val;
 160        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 161        struct hmc5843_data *data = iio_priv(indio_dev);
 162        s32 result;
 163
 164        mutex_lock(&data->lock);
 165
 166        result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
 167        while (!(result & DATA_READY))
 168                result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
 169
 170        result = i2c_smbus_read_word_data(client, this_attr->address);
 171        mutex_unlock(&data->lock);
 172        if (result < 0)
 173                return -EINVAL;
 174
 175        coordinate_val  = (s16)swab16((u16)result);
 176        return sprintf(buf, "%d\n", coordinate_val);
 177}
 178static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
 179                HMC5843_DATA_OUT_X_MSB_REG);
 180static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
 181                HMC5843_DATA_OUT_Y_MSB_REG);
 182static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
 183                HMC5843_DATA_OUT_Z_MSB_REG);
 184
 185/*
 186 * From the datasheet
 187 * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
 188 * device continuously performs conversions an places the result in the
 189 * data register.
 190 *
 191 * 1 - Single-Conversion Mode : device performs a single measurement,
 192 *  sets RDY high and returned to sleep mode
 193 *
 194 * 2 - Idle Mode :  Device is placed in idle mode.
 195 *
 196 * 3 - Sleep Mode. Device is placed in sleep mode.
 197 *
 198 */
 199static ssize_t hmc5843_show_operating_mode(struct device *dev,
 200                                        struct device_attribute *attr,
 201                                        char *buf)
 202{
 203        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 204        struct hmc5843_data *data = iio_priv(indio_dev);
 205        return sprintf(buf, "%d\n", data->operating_mode);
 206}
 207
 208static ssize_t hmc5843_set_operating_mode(struct device *dev,
 209                                struct device_attribute *attr,
 210                                const char *buf,
 211                                size_t count)
 212{
 213        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 214        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 215        struct hmc5843_data *data = iio_priv(indio_dev);
 216        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 217        unsigned long operating_mode = 0;
 218        s32 status;
 219        int error;
 220        mutex_lock(&data->lock);
 221        error = strict_strtoul(buf, 10, &operating_mode);
 222        if (error) {
 223                count = error;
 224                goto exit;
 225        }
 226        dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
 227        if (operating_mode > MODE_SLEEP) {
 228                count = -EINVAL;
 229                goto exit;
 230        }
 231
 232        status = i2c_smbus_write_byte_data(client, this_attr->address,
 233                                        operating_mode);
 234        if (status) {
 235                count = -EINVAL;
 236                goto exit;
 237        }
 238        data->operating_mode = operating_mode;
 239
 240exit:
 241        mutex_unlock(&data->lock);
 242        return count;
 243}
 244static IIO_DEVICE_ATTR(operating_mode,
 245                        S_IWUSR | S_IRUGO,
 246                        hmc5843_show_operating_mode,
 247                        hmc5843_set_operating_mode,
 248                        HMC5843_MODE_REG);
 249
 250/*
 251 * API for setting the measurement configuration to
 252 * Normal, Positive bias and Negative bias
 253 * From the datasheet
 254 *
 255 * Normal measurement configuration (default): In normal measurement
 256 * configuration the device follows normal measurement flow. Pins BP and BN
 257 * are left floating and high impedance.
 258 *
 259 * Positive bias configuration: In positive bias configuration, a positive
 260 * current is forced across the resistive load on pins BP and BN.
 261 *
 262 * Negative bias configuration. In negative bias configuration, a negative
 263 * current is forced across the resistive load on pins BP and BN.
 264 *
 265 */
 266static s32 hmc5843_set_meas_conf(struct i2c_client *client,
 267                                      u8 meas_conf)
 268{
 269        struct hmc5843_data *data = i2c_get_clientdata(client);
 270        u8 reg_val;
 271        reg_val = (meas_conf & MEAS_CONF_MASK) |  (data->rate << RATE_OFFSET);
 272        return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
 273}
 274
 275static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
 276                                                struct device_attribute *attr,
 277                                                char *buf)
 278{
 279        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 280        struct hmc5843_data *data = iio_priv(indio_dev);
 281        return sprintf(buf, "%d\n", data->meas_conf);
 282}
 283
 284static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
 285                                                struct device_attribute *attr,
 286                                                const char *buf,
 287                                                size_t count)
 288{
 289        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 290        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 291        struct hmc5843_data *data = i2c_get_clientdata(client);
 292        unsigned long meas_conf = 0;
 293        int error = strict_strtoul(buf, 10, &meas_conf);
 294        if (error)
 295                return error;
 296        mutex_lock(&data->lock);
 297
 298        dev_dbg(dev, "set mode to %lu\n", meas_conf);
 299        if (hmc5843_set_meas_conf(client, meas_conf)) {
 300                count = -EINVAL;
 301                goto exit;
 302        }
 303        data->meas_conf = meas_conf;
 304
 305exit:
 306        mutex_unlock(&data->lock);
 307        return count;
 308}
 309static IIO_DEVICE_ATTR(meas_conf,
 310                        S_IWUSR | S_IRUGO,
 311                        hmc5843_show_measurement_configuration,
 312                        hmc5843_set_measurement_configuration,
 313                        0);
 314
 315/*
 316 * From Datasheet
 317 * The table shows the minimum data output
 318 * Value        | Minimum data output rate(Hz)
 319 * 0            | 0.5
 320 * 1            | 1
 321 * 2            | 2
 322 * 3            | 5
 323 * 4            | 10 (default)
 324 * 5            | 20
 325 * 6            | 50
 326 * 7            | Not used
 327 */
 328static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
 329
 330static s32 hmc5843_set_rate(struct i2c_client *client,
 331                                u8 rate)
 332{
 333        struct hmc5843_data *data = i2c_get_clientdata(client);
 334        u8 reg_val;
 335
 336        reg_val = (data->meas_conf) |  (rate << RATE_OFFSET);
 337        if (rate >= RATE_NOT_USED) {
 338                dev_err(&client->dev,
 339                        "This data output rate is not supported \n");
 340                return -EINVAL;
 341        }
 342        return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
 343}
 344
 345static ssize_t set_sampling_frequency(struct device *dev,
 346                                        struct device_attribute *attr,
 347                                        const char *buf, size_t count)
 348{
 349
 350        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 351        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 352        struct hmc5843_data *data = iio_priv(indio_dev);
 353        unsigned long rate = 0;
 354
 355        if (strncmp(buf, "0.5" , 3) == 0)
 356                rate = RATE_5;
 357        else if (strncmp(buf, "1" , 1) == 0)
 358                rate = RATE_10;
 359        else if (strncmp(buf, "2", 1) == 0)
 360                rate = RATE_20;
 361        else if (strncmp(buf, "5", 1) == 0)
 362                rate = RATE_50;
 363        else if (strncmp(buf, "10", 2) == 0)
 364                rate = RATE_100;
 365        else if (strncmp(buf, "20" , 2) == 0)
 366                rate = RATE_200;
 367        else if (strncmp(buf, "50" , 2) == 0)
 368                rate = RATE_500;
 369        else
 370                return -EINVAL;
 371
 372        mutex_lock(&data->lock);
 373        dev_dbg(dev, "set rate to %lu\n", rate);
 374        if (hmc5843_set_rate(client, rate)) {
 375                count = -EINVAL;
 376                goto exit;
 377        }
 378        data->rate = rate;
 379
 380exit:
 381        mutex_unlock(&data->lock);
 382        return count;
 383}
 384
 385static ssize_t show_sampling_frequency(struct device *dev,
 386                        struct device_attribute *attr, char *buf)
 387{
 388        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 389        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 390        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 391        s32 rate;
 392
 393        rate = i2c_smbus_read_byte_data(client,  this_attr->address);
 394        if (rate < 0)
 395                return rate;
 396        rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
 397        return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
 398}
 399static IIO_DEVICE_ATTR(sampling_frequency,
 400                        S_IWUSR | S_IRUGO,
 401                        show_sampling_frequency,
 402                        set_sampling_frequency,
 403                        HMC5843_CONFIG_REG_A);
 404
 405/*
 406 * From Datasheet
 407 *      Nominal gain settings
 408 * Value        | Sensor Input Field Range(Ga)  | Gain(counts/ milli-gauss)
 409 *0             |(+-)0.7                        |1620
 410 *1             |(+-)1.0                        |1300
 411 *2             |(+-)1.5                        |970
 412 *3             |(+-)2.0                        |780
 413 *4             |(+-)3.2                        |530
 414 *5             |(+-)3.8                        |460
 415 *6             |(+-)4.5                        |390
 416 *7             |(+-)6.5                        |280
 417 */
 418static ssize_t show_range(struct device *dev,
 419                                struct device_attribute *attr,
 420                                char *buf)
 421{
 422        u8 range;
 423        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 424        struct hmc5843_data *data = iio_priv(indio_dev);
 425
 426        range = data->range;
 427        return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
 428}
 429
 430static ssize_t set_range(struct device *dev,
 431                        struct device_attribute *attr,
 432                        const char *buf,
 433                        size_t count)
 434{
 435        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 436        struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
 437        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 438        struct hmc5843_data *data = iio_priv(indio_dev);
 439        unsigned long range = 0;
 440        int error;
 441        mutex_lock(&data->lock);
 442        error = strict_strtoul(buf, 10, &range);
 443        if (error) {
 444                count = error;
 445                goto exit;
 446        }
 447        dev_dbg(dev, "set range to %lu\n", range);
 448
 449        if (range > RANGE_6_5) {
 450                count = -EINVAL;
 451                goto exit;
 452        }
 453
 454        data->range = range;
 455        range = range << RANGE_GAIN_OFFSET;
 456        if (i2c_smbus_write_byte_data(client, this_attr->address, range))
 457                count = -EINVAL;
 458
 459exit:
 460        mutex_unlock(&data->lock);
 461        return count;
 462
 463}
 464static IIO_DEVICE_ATTR(magn_range,
 465                        S_IWUSR | S_IRUGO,
 466                        show_range,
 467                        set_range,
 468                        HMC5843_CONFIG_REG_B);
 469
 470static ssize_t show_scale(struct device *dev,
 471                        struct device_attribute *attr,
 472                        char *buf)
 473{
 474        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 475        struct hmc5843_data *data = iio_priv(indio_dev);
 476        return strlen(strcpy(buf, regval_to_scale[data->range]));
 477}
 478static IIO_DEVICE_ATTR(magn_scale,
 479                        S_IRUGO,
 480                        show_scale,
 481                        NULL , 0);
 482
 483static struct attribute *hmc5843_attributes[] = {
 484        &iio_dev_attr_meas_conf.dev_attr.attr,
 485        &iio_dev_attr_operating_mode.dev_attr.attr,
 486        &iio_dev_attr_sampling_frequency.dev_attr.attr,
 487        &iio_dev_attr_magn_range.dev_attr.attr,
 488        &iio_dev_attr_magn_scale.dev_attr.attr,
 489        &iio_dev_attr_magn_x_raw.dev_attr.attr,
 490        &iio_dev_attr_magn_y_raw.dev_attr.attr,
 491        &iio_dev_attr_magn_z_raw.dev_attr.attr,
 492        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 493        NULL
 494};
 495
 496static const struct attribute_group hmc5843_group = {
 497        .attrs = hmc5843_attributes,
 498};
 499
 500static int hmc5843_detect(struct i2c_client *client,
 501                          struct i2c_board_info *info)
 502{
 503        unsigned char id_str[HMC5843_ID_REG_LENGTH];
 504
 505        if (client->addr != HMC5843_I2C_ADDRESS)
 506                return -ENODEV;
 507
 508        if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
 509                                HMC5843_ID_REG_LENGTH, id_str)
 510                        != HMC5843_ID_REG_LENGTH)
 511                return -ENODEV;
 512
 513        if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
 514                return -ENODEV;
 515
 516        return 0;
 517}
 518
 519/* Called when we have found a new HMC5843. */
 520static void hmc5843_init_client(struct i2c_client *client)
 521{
 522        struct hmc5843_data *data = i2c_get_clientdata(client);
 523        hmc5843_set_meas_conf(client, data->meas_conf);
 524        hmc5843_set_rate(client, data->rate);
 525        hmc5843_configure(client, data->operating_mode);
 526        i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
 527        mutex_init(&data->lock);
 528        pr_info("HMC5843 initialized\n");
 529}
 530
 531static const struct iio_info hmc5843_info = {
 532        .attrs = &hmc5843_group,
 533        .driver_module = THIS_MODULE,
 534};
 535
 536static int hmc5843_probe(struct i2c_client *client,
 537                         const struct i2c_device_id *id)
 538{
 539        struct hmc5843_data *data;
 540        struct iio_dev *indio_dev;
 541        int err = 0;
 542
 543        indio_dev = iio_allocate_device(sizeof(*data));
 544        if (indio_dev == NULL) {
 545                err = -ENOMEM;
 546                goto exit;
 547        }
 548        data = iio_priv(indio_dev);
 549        /* default settings at probe */
 550
 551        data->meas_conf = CONF_NORMAL;
 552        data->range = RANGE_1_0;
 553        data->operating_mode = MODE_CONVERSION_CONTINUOUS;
 554
 555        i2c_set_clientdata(client, indio_dev);
 556
 557        /* Initialize the HMC5843 chip */
 558        hmc5843_init_client(client);
 559
 560        indio_dev->info = &hmc5843_info;
 561        indio_dev->dev.parent = &client->dev;
 562        indio_dev->modes = INDIO_DIRECT_MODE;
 563        err = iio_device_register(indio_dev);
 564        if (err)
 565                goto exit_free2;
 566        return 0;
 567exit_free2:
 568        iio_free_device(indio_dev);
 569exit:
 570        return err;
 571}
 572
 573static int hmc5843_remove(struct i2c_client *client)
 574{
 575        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 576         /*  sleep mode to save power */
 577        hmc5843_configure(client, MODE_SLEEP);
 578        iio_device_unregister(indio_dev);
 579
 580        return 0;
 581}
 582
 583static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
 584{
 585        hmc5843_configure(client, MODE_SLEEP);
 586        return 0;
 587}
 588
 589static int hmc5843_resume(struct i2c_client *client)
 590{
 591        struct hmc5843_data *data = i2c_get_clientdata(client);
 592        hmc5843_configure(client, data->operating_mode);
 593        return 0;
 594}
 595
 596static const struct i2c_device_id hmc5843_id[] = {
 597        { "hmc5843", 0 },
 598        { }
 599};
 600
 601static struct i2c_driver hmc5843_driver = {
 602        .driver = {
 603                .name   = "hmc5843",
 604        },
 605        .id_table       = hmc5843_id,
 606        .probe          = hmc5843_probe,
 607        .remove         = hmc5843_remove,
 608        .detect         = hmc5843_detect,
 609        .address_list   = normal_i2c,
 610        .suspend        = hmc5843_suspend,
 611        .resume         = hmc5843_resume,
 612};
 613
 614static int __init hmc5843_init(void)
 615{
 616        return i2c_add_driver(&hmc5843_driver);
 617}
 618
 619static void __exit hmc5843_exit(void)
 620{
 621        i2c_del_driver(&hmc5843_driver);
 622}
 623
 624MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
 625MODULE_DESCRIPTION("HMC5843 driver");
 626MODULE_LICENSE("GPL");
 627
 628module_init(hmc5843_init);
 629module_exit(hmc5843_exit);
 630