/*
* OMAP4 Bandgap temperature sensor driver
*
* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
* Author: J Keerthy <j-keerthy@ti.com>
* Author: Moiz Sonasath <m-sonasath@ti.com>
* Couple of fixes, DT and MFD adaptation:
* Eduardo Valentin <eduardo.valentin@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/module.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/reboot.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/io.h>
#include "ti-bandgap.h"
/*** Helper functions to access registers and their bitfields ***/
/**
* omap_bandgap_readl() - simple read helper function
* @bgp: pointer to omap_bandgap structure
* @reg: desired register (offset) to be read
*
* Helper function to read bandgap registers. It uses the io remapped area.
* Returns the register value.
*/
static u32 omap_bandgap_readl(struct omap_bandgap *bgp, u32 reg)
{
return readl(bgp->base + reg);
}
/**
* omap_bandgap_writel() - simple write helper function
* @bgp: pointer to omap_bandgap structure
* @val: desired register value to be written
* @reg: desired register (offset) to be written
*
* Helper function to write bandgap registers. It uses the io remapped area.
*/
static void omap_bandgap_writel(struct omap_bandgap *bgp, u32 val, u32 reg)
{
writel(val, bgp->base + reg);
}
/**
* DOC: macro to update bits.
*
* RMW_BITS() - used to read, modify and update bandgap bitfields.
* The value passed will be shifted.
*/
#define RMW_BITS(bgp, id, reg, mask, val) \
do { \
struct temp_sensor_registers *t; \
u32 r; \
\
t = bgp->conf->sensors[(id)].registers; \
r = omap_bandgap_readl(bgp, t->reg); \
r &= ~t->mask; \
r |= (val) << __ffs(t->mask); \
omap_bandgap_writel(bgp, r, t->reg); \
} while (0)
/*** Basic helper functions ***/
/**
* omap_bandgap_power() - controls the power state of a bandgap device
* @bgp: pointer to omap_bandgap structure
* @on: desired power state (1 - on, 0 - off)
*
* Used to power on/off a bandgap device instance. Only used on those
* that features tempsoff bit.
*/
static int omap_bandgap_power(struct omap_bandgap *bgp, bool on)
{
int i;
if (!OMAP_BANDGAP_HAS(bgp, POWER_SWITCH))
goto exit;
for (i = 0; i < bgp->conf->sensor_count; i++)
/* active on 0 */
RMW_BITS(bgp, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on);
exit:
return 0;
}
/**
* omap_bandgap_read_temp() - helper function to read sensor temperature
* @bgp: pointer to omap_bandgap structure
* @id: bandgap sensor id
*
* Function to concentrate the steps to read sensor temperature register.
* This function is desired because, depending on bandgap device version,
* it might be needed to freeze the bandgap state machine, before fetching
* the register value.
*/
static u32 omap_bandgap_read_temp(struct omap_bandgap *bgp, int id)
{
struct temp_sensor_registers *tsr;
u32 temp, reg;
tsr = bgp->conf->sensors[id].