linux/drivers/mfd/twl4030-madc.c
<<
>>
Prefs
   1/*
   2 *
   3 * TWL4030 MADC module driver-This driver monitors the real time
   4 * conversion of analog signals like battery temperature,
   5 * battery type, battery level etc.
   6 *
   7 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
   8 * J Keerthy <j-keerthy@ti.com>
   9 *
  10 * Based on twl4030-madc.c
  11 * Copyright (C) 2008 Nokia Corporation
  12 * Mikko Ylinen <mikko.k.ylinen@nokia.com>
  13 *
  14 * Amit Kucheria <amit.kucheria@canonical.com>
  15 *
  16 * This program is free software; you can redistribute it and/or
  17 * modify it under the terms of the GNU General Public License
  18 * version 2 as published by the Free Software Foundation.
  19 *
  20 * This program is distributed in the hope that it will be useful, but
  21 * WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  23 * General Public License for more details.
  24 *
  25 * You should have received a copy of the GNU General Public License
  26 * along with this program; if not, write to the Free Software
  27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  28 * 02110-1301 USA
  29 *
  30 */
  31
  32#include <linux/init.h>
  33#include <linux/device.h>
  34#include <linux/interrupt.h>
  35#include <linux/kernel.h>
  36#include <linux/delay.h>
  37#include <linux/platform_device.h>
  38#include <linux/slab.h>
  39#include <linux/i2c/twl.h>
  40#include <linux/i2c/twl4030-madc.h>
  41#include <linux/module.h>
  42#include <linux/stddef.h>
  43#include <linux/mutex.h>
  44#include <linux/bitops.h>
  45#include <linux/jiffies.h>
  46#include <linux/types.h>
  47#include <linux/gfp.h>
  48#include <linux/err.h>
  49
  50/*
  51 * struct twl4030_madc_data - a container for madc info
  52 * @dev - pointer to device structure for madc
  53 * @lock - mutex protecting this data structure
  54 * @requests - Array of request struct corresponding to SW1, SW2 and RT
  55 * @imr - Interrupt mask register of MADC
  56 * @isr - Interrupt status register of MADC
  57 */
  58struct twl4030_madc_data {
  59        struct device *dev;
  60        struct mutex lock;      /* mutex protecting this data structure */
  61        struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
  62        int imr;
  63        int isr;
  64};
  65
  66static struct twl4030_madc_data *twl4030_madc;
  67
  68struct twl4030_prescale_divider_ratios {
  69        s16 numerator;
  70        s16 denominator;
  71};
  72
  73static const struct twl4030_prescale_divider_ratios
  74twl4030_divider_ratios[16] = {
  75        {1, 1},         /* CHANNEL 0 No Prescaler */
  76        {1, 1},         /* CHANNEL 1 No Prescaler */
  77        {6, 10},        /* CHANNEL 2 */
  78        {6, 10},        /* CHANNEL 3 */
  79        {6, 10},        /* CHANNEL 4 */
  80        {6, 10},        /* CHANNEL 5 */
  81        {6, 10},        /* CHANNEL 6 */
  82        {6, 10},        /* CHANNEL 7 */
  83        {3, 14},        /* CHANNEL 8 */
  84        {1, 3},         /* CHANNEL 9 */
  85        {1, 1},         /* CHANNEL 10 No Prescaler */
  86        {15, 100},      /* CHANNEL 11 */
  87        {1, 4},         /* CHANNEL 12 */
  88        {1, 1},         /* CHANNEL 13 Reserved channels */
  89        {1, 1},         /* CHANNEL 14 Reseved channels */
  90        {5, 11},        /* CHANNEL 15 */
  91};
  92
  93
  94/*
  95 * Conversion table from -3 to 55 degree Celcius
  96 */
  97static int therm_tbl[] = {
  9830800,  29500,  28300,  27100,
  9926000,  24900,  23900,  22900,  22000,  21100,  20300,  19400,  18700,  17900,
 10017200,  16500,  15900,  15300,  14700,  14100,  13600,  13100,  12600,  12100,
 10111600,  11200,  10800,  10400,  10000,  9630,   9280,   8950,   8620,   8310,
 1028020,   7730,   7460,   7200,   6950,   6710,   6470,   6250,   6040,   5830,
 1035640,   5450,   5260,   5090,   4920,   4760,   4600,   4450,   4310,   4170,
 1044040,   3910,   3790,   3670,   3550
 105};
 106
 107/*
 108 * Structure containing the registers
 109 * of different conversion methods supported by MADC.
 110 * Hardware or RT real time conversion request initiated by external host
 111 * processor for RT Signal conversions.
 112 * External host processors can also request for non RT conversions
 113 * SW1 and SW2 software conversions also called asynchronous or GPC request.
 114 */
 115static
 116const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
 117        [TWL4030_MADC_RT] = {
 118                             .sel = TWL4030_MADC_RTSELECT_LSB,
 119                             .avg = TWL4030_MADC_RTAVERAGE_LSB,
 120                             .rbase = TWL4030_MADC_RTCH0_LSB,
 121                             },
 122        [TWL4030_MADC_SW1] = {
 123                              .sel = TWL4030_MADC_SW1SELECT_LSB,
 124                              .avg = TWL4030_MADC_SW1AVERAGE_LSB,
 125                              .rbase = TWL4030_MADC_GPCH0_LSB,
 126                              .ctrl = TWL4030_MADC_CTRL_SW1,
 127                              },
 128        [TWL4030_MADC_SW2] = {
 129                              .sel = TWL4030_MADC_SW2SELECT_LSB,
 130                              .avg = TWL4030_MADC_SW2AVERAGE_LSB,
 131                              .rbase = TWL4030_MADC_GPCH0_LSB,
 132                              .ctrl = TWL4030_MADC_CTRL_SW2,
 133                              },
 134};
 135
 136/*
 137 * Function to read a particular channel value.
 138 * @madc - pointer to struct twl4030_madc_data
 139 * @reg - lsb of ADC Channel
 140 * If the i2c read fails it returns an error else returns 0.
 141 */
 142static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
 143{
 144        u8 msb, lsb;
 145        int ret;
 146        /*
 147         * For each ADC channel, we have MSB and LSB register pair. MSB address
 148         * is always LSB address+1. reg parameter is the address of LSB register
 149         */
 150        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
 151        if (ret) {
 152                dev_err(madc->dev, "unable to read MSB register 0x%X\n",
 153                        reg + 1);
 154                return ret;
 155        }
 156        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
 157        if (ret) {
 158                dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
 159                return ret;
 160        }
 161
 162        return (int)(((msb << 8) | lsb) >> 6);
 163}
 164
 165/*
 166 * Return battery temperature
 167 * Or < 0 on failure.
 168 */
 169static int twl4030battery_temperature(int raw_volt)
 170{
 171        u8 val;
 172        int temp, curr, volt, res, ret;
 173
 174        volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
 175        /* Getting and calculating the supply current in micro ampers */
 176        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
 177                REG_BCICTL2);
 178        if (ret < 0)
 179                return ret;
 180        curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
 181        /* Getting and calculating the thermistor resistance in ohms */
 182        res = volt * 1000 / curr;
 183        /* calculating temperature */
 184        for (temp = 58; temp >= 0; temp--) {
 185                int actual = therm_tbl[temp];
 186
 187                if ((actual - res) >= 0)
 188                        break;
 189        }
 190
 191        return temp + 1;
 192}
 193
 194static int twl4030battery_current(int raw_volt)
 195{
 196        int ret;
 197        u8 val;
 198
 199        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
 200                TWL4030_BCI_BCICTL1);
 201        if (ret)
 202                return ret;
 203        if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
 204                return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
 205        else /* slope of 0.88 mV/mA */
 206                return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
 207}
 208/*
 209 * Function to read channel values
 210 * @madc - pointer to twl4030_madc_data struct
 211 * @reg_base - Base address of the first channel
 212 * @Channels - 16 bit bitmap. If the bit is set, channel value is read
 213 * @buf - The channel values are stored here. if read fails error
 214 * value is stored
 215 * Returns the number of successfully read channels.
 216 */
 217static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
 218                                      u8 reg_base, unsigned
 219                                                long channels, int *buf)
 220{
 221        int count = 0, count_req = 0, i;
 222        u8 reg;
 223
 224        for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
 225                reg = reg_base + 2 * i;
 226                buf[i] = twl4030_madc_channel_raw_read(madc, reg);
 227                if (buf[i] < 0) {
 228                        dev_err(madc->dev,
 229                                "Unable to read register 0x%X\n", reg);
 230                        count_req++;
 231                        continue;
 232                }
 233                switch (i) {
 234                case 10:
 235                        buf[i] = twl4030battery_current(buf[i]);
 236                        if (buf[i] < 0) {
 237                                dev_err(madc->dev, "err reading current\n");
 238                                count_req++;
 239                        } else {
 240                                count++;
 241                                buf[i] = buf[i] - 750;
 242                        }
 243                        break;
 244                case 1:
 245                        buf[i] = twl4030battery_temperature(buf[i]);
 246                        if (buf[i] < 0) {
 247                                dev_err(madc->dev, "err reading temperature\n");
 248                                count_req++;
 249                        } else {
 250                                buf[i] -= 3;
 251                                count++;
 252                        }
 253                        break;
 254                default:
 255                        count++;
 256                        /* Analog Input (V) = conv_result * step_size / R
 257                         * conv_result = decimal value of 10-bit conversion
 258                         *               result
 259                         * step size = 1.5 / (2 ^ 10 -1)
 260                         * R = Prescaler ratio for input channels.
 261                         * Result given in mV hence multiplied by 1000.
 262                         */
 263                        buf[i] = (buf[i] * 3 * 1000 *
 264                                 twl4030_divider_ratios[i].denominator)
 265                                / (2 * 1023 *
 266                                twl4030_divider_ratios[i].numerator);
 267                }
 268        }
 269        if (count_req)
 270                dev_err(madc->dev, "%d channel conversion failed\n", count_req);
 271
 272        return count;
 273}
 274
 275/*
 276 * Enables irq.
 277 * @madc - pointer to twl4030_madc_data struct
 278 * @id - irq number to be enabled
 279 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
 280 * corresponding to RT, SW1, SW2 conversion requests.
 281 * If the i2c read fails it returns an error else returns 0.
 282 */
 283static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
 284{
 285        u8 val;
 286        int ret;
 287
 288        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
 289        if (ret) {
 290                dev_err(madc->dev, "unable to read imr register 0x%X\n",
 291                        madc->imr);
 292                return ret;
 293        }
 294        val &= ~(1 << id);
 295        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
 296        if (ret) {
 297                dev_err(madc->dev,
 298                        "unable to write imr register 0x%X\n", madc->imr);
 299                return ret;
 300
 301        }
 302
 303        return 0;
 304}
 305
 306/*
 307 * Disables irq.
 308 * @madc - pointer to twl4030_madc_data struct
 309 * @id - irq number to be disabled
 310 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
 311 * corresponding to RT, SW1, SW2 conversion requests.
 312 * Returns error if i2c read/write fails.
 313 */
 314static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
 315{
 316        u8 val;
 317        int ret;
 318
 319        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
 320        if (ret) {
 321                dev_err(madc->dev, "unable to read imr register 0x%X\n",
 322                        madc->imr);
 323                return ret;
 324        }
 325        val |= (1 << id);
 326        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
 327        if (ret) {
 328                dev_err(madc->dev,
 329                        "unable to write imr register 0x%X\n", madc->imr);
 330                return ret;
 331        }
 332
 333        return 0;
 334}
 335
 336static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
 337{
 338        struct twl4030_madc_data *madc = _madc;
 339        const struct twl4030_madc_conversion_method *method;
 340        u8 isr_val, imr_val;
 341        int i, len, ret;
 342        struct twl4030_madc_request *r;
 343
 344        mutex_lock(&madc->lock);
 345        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
 346        if (ret) {
 347                dev_err(madc->dev, "unable to read isr register 0x%X\n",
 348                        madc->isr);
 349                goto err_i2c;
 350        }
 351        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
 352        if (ret) {
 353                dev_err(madc->dev, "unable to read imr register 0x%X\n",
 354                        madc->imr);
 355                goto err_i2c;
 356        }
 357        isr_val &= ~imr_val;
 358        for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 359                if (!(isr_val & (1 << i)))
 360                        continue;
 361                ret = twl4030_madc_disable_irq(madc, i);
 362                if (ret < 0)
 363                        dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
 364                madc->requests[i].result_pending = 1;
 365        }
 366        for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 367                r = &madc->requests[i];
 368                /* No pending results for this method, move to next one */
 369                if (!r->result_pending)
 370                        continue;
 371                method = &twl4030_conversion_methods[r->method];
 372                /* Read results */
 373                len = twl4030_madc_read_channels(madc, method->rbase,
 374                                                 r->channels, r->rbuf);
 375                /* Return results to caller */
 376                if (r->func_cb != NULL) {
 377                        r->func_cb(len, r->channels, r->rbuf);
 378                        r->func_cb = NULL;
 379                }
 380                /* Free request */
 381                r->result_pending = 0;
 382                r->active = 0;
 383        }
 384        mutex_unlock(&madc->lock);
 385
 386        return IRQ_HANDLED;
 387
 388err_i2c:
 389        /*
 390         * In case of error check whichever request is active
 391         * and service the same.
 392         */
 393        for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 394                r = &madc->requests[i];
 395                if (r->active == 0)
 396                        continue;
 397                method = &twl4030_conversion_methods[r->method];
 398                /* Read results */
 399                len = twl4030_madc_read_channels(madc, method->rbase,
 400                                                 r->channels, r->rbuf);
 401                /* Return results to caller */
 402                if (r->func_cb != NULL) {
 403                        r->func_cb(len, r->channels, r->rbuf);
 404                        r->func_cb = NULL;
 405                }
 406                /* Free request */
 407                r->result_pending = 0;
 408                r->active = 0;
 409        }
 410        mutex_unlock(&madc->lock);
 411
 412        return IRQ_HANDLED;
 413}
 414
 415static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
 416                                struct twl4030_madc_request *req)
 417{
 418        struct twl4030_madc_request *p;
 419        int ret;
 420
 421        p = &madc->requests[req->method];
 422        memcpy(p, req, sizeof(*req));
 423        ret = twl4030_madc_enable_irq(madc, req->method);
 424        if (ret < 0) {
 425                dev_err(madc->dev, "enable irq failed!!\n");
 426                return ret;
 427        }
 428
 429        return 0;
 430}
 431
 432/*
 433 * Function which enables the madc conversion
 434 * by writing to the control register.
 435 * @madc - pointer to twl4030_madc_data struct
 436 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
 437 * corresponding to RT SW1 or SW2 conversion methods.
 438 * Returns 0 if succeeds else a negative error value
 439 */
 440static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
 441                                         int conv_method)
 442{
 443        const struct twl4030_madc_conversion_method *method;
 444        int ret = 0;
 445        method = &twl4030_conversion_methods[conv_method];
 446        switch (conv_method) {
 447        case TWL4030_MADC_SW1:
 448        case TWL4030_MADC_SW2:
 449                ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 450                                       TWL4030_MADC_SW_START, method->ctrl);
 451                if (ret) {
 452                        dev_err(madc->dev,
 453                                "unable to write ctrl register 0x%X\n",
 454                                method->ctrl);
 455                        return ret;
 456                }
 457                break;
 458        default:
 459                break;
 460        }
 461
 462        return 0;
 463}
 464
 465/*
 466 * Function that waits for conversion to be ready
 467 * @madc - pointer to twl4030_madc_data struct
 468 * @timeout_ms - timeout value in milliseconds
 469 * @status_reg - ctrl register
 470 * returns 0 if succeeds else a negative error value
 471 */
 472static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
 473                                              unsigned int timeout_ms,
 474                                              u8 status_reg)
 475{
 476        unsigned long timeout;
 477        int ret;
 478
 479        timeout = jiffies + msecs_to_jiffies(timeout_ms);
 480        do {
 481                u8 reg;
 482
 483                ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
 484                if (ret) {
 485                        dev_err(madc->dev,
 486                                "unable to read status register 0x%X\n",
 487                                status_reg);
 488                        return ret;
 489                }
 490                if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
 491                        return 0;
 492                usleep_range(500, 2000);
 493        } while (!time_after(jiffies, timeout));
 494        dev_err(madc->dev, "conversion timeout!\n");
 495
 496        return -EAGAIN;
 497}
 498
 499/*
 500 * An exported function which can be called from other kernel drivers.
 501 * @req twl4030_madc_request structure
 502 * req->rbuf will be filled with read values of channels based on the
 503 * channel index. If a particular channel reading fails there will
 504 * be a negative error value in the corresponding array element.
 505 * returns 0 if succeeds else error value
 506 */
 507int twl4030_madc_conversion(struct twl4030_madc_request *req)
 508{
 509        const struct twl4030_madc_conversion_method *method;
 510        u8 ch_msb, ch_lsb;
 511        int ret;
 512
 513        if (!req)
 514                return -EINVAL;
 515        mutex_lock(&twl4030_madc->lock);
 516        if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
 517                ret = -EINVAL;
 518                goto out;
 519        }
 520        /* Do we have a conversion request ongoing */
 521        if (twl4030_madc->requests[req->method].active) {
 522                ret = -EBUSY;
 523                goto out;
 524        }
 525        ch_msb = (req->channels >> 8) & 0xff;
 526        ch_lsb = req->channels & 0xff;
 527        method = &twl4030_conversion_methods[req->method];
 528        /* Select channels to be converted */
 529        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
 530        if (ret) {
 531                dev_err(twl4030_madc->dev,
 532                        "unable to write sel register 0x%X\n", method->sel + 1);
 533                return ret;
 534        }
 535        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
 536        if (ret) {
 537                dev_err(twl4030_madc->dev,
 538                        "unable to write sel register 0x%X\n", method->sel + 1);
 539                return ret;
 540        }
 541        /* Select averaging for all channels if do_avg is set */
 542        if (req->do_avg) {
 543                ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 544                                       ch_msb, method->avg + 1);
 545                if (ret) {
 546                        dev_err(twl4030_madc->dev,
 547                                "unable to write avg register 0x%X\n",
 548                                method->avg + 1);
 549                        return ret;
 550                }
 551                ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 552                                       ch_lsb, method->avg);
 553                if (ret) {
 554                        dev_err(twl4030_madc->dev,
 555                                "unable to write sel reg 0x%X\n",
 556                                method->sel + 1);
 557                        return ret;
 558                }
 559        }
 560        if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
 561                ret = twl4030_madc_set_irq(twl4030_madc, req);
 562                if (ret < 0)
 563                        goto out;
 564                ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
 565                if (ret < 0)
 566                        goto out;
 567                twl4030_madc->requests[req->method].active = 1;
 568                ret = 0;
 569                goto out;
 570        }
 571        /* With RT method we should not be here anymore */
 572        if (req->method == TWL4030_MADC_RT) {
 573                ret = -EINVAL;
 574                goto out;
 575        }
 576        ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
 577        if (ret < 0)
 578                goto out;
 579        twl4030_madc->requests[req->method].active = 1;
 580        /* Wait until conversion is ready (ctrl register returns EOC) */
 581        ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
 582        if (ret) {
 583                twl4030_madc->requests[req->method].active = 0;
 584                goto out;
 585        }
 586        ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
 587                                         req->channels, req->rbuf);
 588        twl4030_madc->requests[req->method].active = 0;
 589
 590out:
 591        mutex_unlock(&twl4030_madc->lock);
 592
 593        return ret;
 594}
 595EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
 596
 597/*
 598 * Return channel value
 599 * Or < 0 on failure.
 600 */
 601int twl4030_get_madc_conversion(int channel_no)
 602{
 603        struct twl4030_madc_request req;
 604        int temp = 0;
 605        int ret;
 606
 607        req.channels = (1 << channel_no);
 608        req.method = TWL4030_MADC_SW2;
 609        req.active = 0;
 610        req.func_cb = NULL;
 611        ret = twl4030_madc_conversion(&req);
 612        if (ret < 0)
 613                return ret;
 614        if (req.rbuf[channel_no] > 0)
 615                temp = req.rbuf[channel_no];
 616
 617        return temp;
 618}
 619EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
 620
 621/*
 622 * Function to enable or disable bias current for
 623 * main battery type reading or temperature sensing
 624 * @madc - pointer to twl4030_madc_data struct
 625 * @chan - can be one of the two values
 626 * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
 627 * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
 628 * sensing
 629 * @on - enable or disable chan.
 630 */
 631static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
 632                                              int chan, int on)
 633{
 634        int ret;
 635        u8 regval;
 636
 637        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
 638                              &regval, TWL4030_BCI_BCICTL1);
 639        if (ret) {
 640                dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
 641                        TWL4030_BCI_BCICTL1);
 642                return ret;
 643        }
 644        if (on)
 645                regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
 646        else
 647                regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
 648        ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
 649                               regval, TWL4030_BCI_BCICTL1);
 650        if (ret) {
 651                dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
 652                        TWL4030_BCI_BCICTL1);
 653                return ret;
 654        }
 655
 656        return 0;
 657}
 658
 659/*
 660 * Function that sets MADC software power on bit to enable MADC
 661 * @madc - pointer to twl4030_madc_data struct
 662 * @on - Enable or disable MADC software powen on bit.
 663 * returns error if i2c read/write fails else 0
 664 */
 665static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
 666{
 667        u8 regval;
 668        int ret;
 669
 670        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
 671                              &regval, TWL4030_MADC_CTRL1);
 672        if (ret) {
 673                dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
 674                        TWL4030_MADC_CTRL1);
 675                return ret;
 676        }
 677        if (on)
 678                regval |= TWL4030_MADC_MADCON;
 679        else
 680                regval &= ~TWL4030_MADC_MADCON;
 681        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
 682        if (ret) {
 683                dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
 684                        TWL4030_MADC_CTRL1);
 685                return ret;
 686        }
 687
 688        return 0;
 689}
 690
 691/*
 692 * Initialize MADC and request for threaded irq
 693 */
 694static int __devinit twl4030_madc_probe(struct platform_device *pdev)
 695{
 696        struct twl4030_madc_data *madc;
 697        struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
 698        int ret;
 699        u8 regval;
 700
 701        if (!pdata) {
 702                dev_err(&pdev->dev, "platform_data not available\n");
 703                return -EINVAL;
 704        }
 705        madc = kzalloc(sizeof(*madc), GFP_KERNEL);
 706        if (!madc)
 707                return -ENOMEM;
 708
 709        /*
 710         * Phoenix provides 2 interrupt lines. The first one is connected to
 711         * the OMAP. The other one can be connected to the other processor such
 712         * as modem. Hence two separate ISR and IMR registers.
 713         */
 714        madc->imr = (pdata->irq_line == 1) ?
 715            TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
 716        madc->isr = (pdata->irq_line == 1) ?
 717            TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
 718        ret = twl4030_madc_set_power(madc, 1);
 719        if (ret < 0)
 720                goto err_power;
 721        ret = twl4030_madc_set_current_generator(madc, 0, 1);
 722        if (ret < 0)
 723                goto err_current_generator;
 724
 725        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
 726                              &regval, TWL4030_BCI_BCICTL1);
 727        if (ret) {
 728                dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
 729                        TWL4030_BCI_BCICTL1);
 730                goto err_i2c;
 731        }
 732        regval |= TWL4030_BCI_MESBAT;
 733        ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
 734                               regval, TWL4030_BCI_BCICTL1);
 735        if (ret) {
 736                dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
 737                        TWL4030_BCI_BCICTL1);
 738                goto err_i2c;
 739        }
 740        platform_set_drvdata(pdev, madc);
 741        mutex_init(&madc->lock);
 742        ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
 743                                   twl4030_madc_threaded_irq_handler,
 744                                   IRQF_TRIGGER_RISING, "twl4030_madc", madc);
 745        if (ret) {
 746                dev_dbg(&pdev->dev, "could not request irq\n");
 747                goto err_irq;
 748        }
 749        twl4030_madc = madc;
 750        return 0;
 751err_irq:
 752        platform_set_drvdata(pdev, NULL);
 753err_i2c:
 754        twl4030_madc_set_current_generator(madc, 0, 0);
 755err_current_generator:
 756        twl4030_madc_set_power(madc, 0);
 757err_power:
 758        kfree(madc);
 759
 760        return ret;
 761}
 762
 763static int __devexit twl4030_madc_remove(struct platform_device *pdev)
 764{
 765        struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
 766
 767        free_irq(platform_get_irq(pdev, 0), madc);
 768        platform_set_drvdata(pdev, NULL);
 769        twl4030_madc_set_current_generator(madc, 0, 0);
 770        twl4030_madc_set_power(madc, 0);
 771        kfree(madc);
 772
 773        return 0;
 774}
 775
 776static struct platform_driver twl4030_madc_driver = {
 777        .probe = twl4030_madc_probe,
 778        .remove = __exit_p(twl4030_madc_remove),
 779        .driver = {
 780                   .name = "twl4030_madc",
 781                   .owner = THIS_MODULE,
 782                   },
 783};
 784
 785static int __init twl4030_madc_init(void)
 786{
 787        return platform_driver_register(&twl4030_madc_driver);
 788}
 789
 790module_init(twl4030_madc_init);
 791
 792static void __exit twl4030_madc_exit(void)
 793{
 794        platform_driver_unregister(&twl4030_madc_driver);
 795}
 796
 797module_exit(twl4030_madc_exit);
 798
 799MODULE_DESCRIPTION("TWL4030 ADC driver");
 800MODULE_LICENSE("GPL");
 801MODULE_AUTHOR("J Keerthy");
 802MODULE_ALIAS("platform:twl4030_madc");
 803