ti-bandgap.c 39.7 KB
Newer Older
1
/*
2
 * TI Bandgap temperature sensor driver
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
 *
 * 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>
36
#include <linux/spinlock.h>
37 38 39 40
#include <linux/reboot.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
41
#include <linux/of_gpio.h>
42
#include <linux/io.h>
43

44
#include "ti-bandgap.h"
45

46 47
/***   Helper functions to access registers and their bitfields   ***/

48
/**
49 50
 * ti_bandgap_readl() - simple read helper function
 * @bgp: pointer to ti_bandgap structure
51 52 53
 * @reg: desired register (offset) to be read
 *
 * Helper function to read bandgap registers. It uses the io remapped area.
54
 * Return: the register value.
55
 */
56
static u32 ti_bandgap_readl(struct ti_bandgap *bgp, u32 reg)
57
{
58
	return readl(bgp->base + reg);
59 60
}

61
/**
62 63
 * ti_bandgap_writel() - simple write helper function
 * @bgp: pointer to ti_bandgap structure
64 65 66 67 68
 * @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.
 */
69
static void ti_bandgap_writel(struct ti_bandgap *bgp, u32 val, u32 reg)
70
{
71
	writel(val, bgp->base + reg);
72 73
}

74 75 76 77 78 79
/**
 * DOC: macro to update bits.
 *
 * RMW_BITS() - used to read, modify and update bandgap bitfields.
 *            The value passed will be shifted.
 */
80
#define RMW_BITS(bgp, id, reg, mask, val)			\
81 82 83 84
do {								\
	struct temp_sensor_registers *t;			\
	u32 r;							\
								\
85
	t = bgp->conf->sensors[(id)].registers;		\
86
	r = ti_bandgap_readl(bgp, t->reg);			\
87 88
	r &= ~t->mask;						\
	r |= (val) << __ffs(t->mask);				\
89
	ti_bandgap_writel(bgp, r, t->reg);			\
90 91
} while (0)

92 93
/***   Basic helper functions   ***/

94
/**
95 96
 * ti_bandgap_power() - controls the power state of a bandgap device
 * @bgp: pointer to ti_bandgap structure
97 98 99 100
 * @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.
101 102
 *
 * Return: 0 on success, -ENOTSUPP if tempsoff is not supported.
103
 */
104
static int ti_bandgap_power(struct ti_bandgap *bgp, bool on)
105
{
106
	int i, ret = 0;
107

108 109
	if (!TI_BANDGAP_HAS(bgp, POWER_SWITCH)) {
		ret = -ENOTSUPP;
110
		goto exit;
111
	}
112

113
	for (i = 0; i < bgp->conf->sensor_count; i++)
114
		/* active on 0 */
115
		RMW_BITS(bgp, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on);
116

117
exit:
118
	return ret;
119 120
}

121
/**
122 123
 * ti_bandgap_read_temp() - helper function to read sensor temperature
 * @bgp: pointer to ti_bandgap structure
124 125 126 127 128 129
 * @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.
130 131
 *
 * Return: temperature in ADC values.
132
 */
133
static u32 ti_bandgap_read_temp(struct ti_bandgap *bgp, int id)
134 135
{
	struct temp_sensor_registers *tsr;
136
	u32 temp, reg;
137

138
	tsr = bgp->conf->sensors[id].registers;
139 140
	reg = tsr->temp_sensor_ctrl;

141
	if (TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
142
		RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
143 144 145 146 147 148 149 150
		/*
		 * In case we cannot read from cur_dtemp / dtemp_0,
		 * then we read from the last valid temp read
		 */
		reg = tsr->ctrl_dtemp_1;
	}

	/* read temperature */
151
	temp = ti_bandgap_readl(bgp, reg);
152 153
	temp &= tsr->bgap_dtemp_mask;

154
	if (TI_BANDGAP_HAS(bgp, FREEZE_BIT))
155
		RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
156 157 158 159

	return temp;
}

160 161
/***   IRQ handlers   ***/

162
/**
163
 * ti_bandgap_talert_irq_handler() - handles Temperature alert IRQs
164
 * @irq: IRQ number
165
 * @data: private data (struct ti_bandgap *)
166 167 168 169 170 171
 *
 * This is the Talert handler. Use it only if bandgap device features
 * HAS(TALERT). This handler goes over all sensors and checks their
 * conditions and acts accordingly. In case there are events pending,
 * it will reset the event mask to wait for the opposite event (next event).
 * Every time there is a new event, it will be reported to thermal layer.
172 173
 *
 * Return: IRQ_HANDLED
174
 */
175
static irqreturn_t ti_bandgap_talert_irq_handler(int irq, void *data)
176
{
177
	struct ti_bandgap *bgp = data;
178
	struct temp_sensor_registers *tsr;
179
	u32 t_hot = 0, t_cold = 0, ctrl;
180 181
	int i;

182 183 184
	spin_lock(&bgp->lock);
	for (i = 0; i < bgp->conf->sensor_count; i++) {
		tsr = bgp->conf->sensors[i].registers;
185
		ctrl = ti_bandgap_readl(bgp, tsr->bgap_status);
186 187 188

		/* Read the status of t_hot */
		t_hot = ctrl & tsr->status_hot_mask;
189 190

		/* Read the status of t_cold */
191
		t_cold = ctrl & tsr->status_cold_mask;
192 193 194 195

		if (!t_cold && !t_hot)
			continue;

196
		ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
197 198 199 200 201 202 203 204 205 206 207 208 209
		/*
		 * One TALERT interrupt: Two sources
		 * If the interrupt is due to t_hot then mask t_hot and
		 * and unmask t_cold else mask t_cold and unmask t_hot
		 */
		if (t_hot) {
			ctrl &= ~tsr->mask_hot_mask;
			ctrl |= tsr->mask_cold_mask;
		} else if (t_cold) {
			ctrl &= ~tsr->mask_cold_mask;
			ctrl |= tsr->mask_hot_mask;
		}

210
		ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
211

212
		dev_dbg(bgp->dev,
213
			"%s: IRQ from %s sensor: hotevent %d coldevent %d\n",
214
			__func__, bgp->conf->sensors[i].domain,
215 216
			t_hot, t_cold);

217
		/* report temperature to whom may concern */
218 219
		if (bgp->conf->report_temperature)
			bgp->conf->report_temperature(bgp, i);
220
	}
221
	spin_unlock(&bgp->lock);
222 223 224 225

	return IRQ_HANDLED;
}

226
/**
227
 * ti_bandgap_tshut_irq_handler() - handles Temperature shutdown signal
228 229 230 231 232 233
 * @irq: IRQ number
 * @data: private data (unused)
 *
 * This is the Tshut handler. Use it only if bandgap device features
 * HAS(TSHUT). If any sensor fires the Tshut signal, we simply shutdown
 * the system.
234 235
 *
 * Return: IRQ_HANDLED
236
 */
237
static irqreturn_t ti_bandgap_tshut_irq_handler(int irq, void *data)
238
{
239 240 241
	pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n",
		 __func__);

242 243 244 245 246
	orderly_poweroff(true);

	return IRQ_HANDLED;
}

247 248
/***   Helper functions which manipulate conversion ADC <-> mi Celsius   ***/

249
/**
250 251
 * ti_bandgap_adc_to_mcelsius() - converts an ADC value to mCelsius scale
 * @bgp: struct ti_bandgap pointer
252 253 254 255 256 257
 * @adc_val: value in ADC representation
 * @t: address where to write the resulting temperature in mCelsius
 *
 * Simple conversion from ADC representation to mCelsius. In case the ADC value
 * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
 * The conversion table is indexed by the ADC values.
258 259 260
 *
 * Return: 0 if conversion was successful, else -ERANGE in case the @adc_val
 * argument is out of the ADC conv table range.
261
 */
262
static
263
int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
264
{
265
	const struct ti_bandgap_data *conf = bgp->conf;
266
	int ret = 0;
267 268

	/* look up for temperature in the table and return the temperature */
269
	if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val) {
270 271 272
		ret = -ERANGE;
		goto exit;
	}
273

274
	*t = bgp->conf->conv_table[adc_val - conf->adc_start_val];
275

276 277
exit:
	return ret;
278 279
}

280
/**
281 282
 * ti_bandgap_mcelsius_to_adc() - converts a mCelsius value to ADC scale
 * @bgp: struct ti_bandgap pointer
283 284 285 286 287 288
 * @temp: value in mCelsius
 * @adc: address where to write the resulting temperature in ADC representation
 *
 * Simple conversion from mCelsius to ADC values. In case the temp value
 * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
 * The conversion table is indexed by the ADC values.
289 290 291
 *
 * Return: 0 if conversion was successful, else -ERANGE in case the @temp
 * argument is out of the ADC conv table range.
292
 */
293
static
294
int ti_bandgap_mcelsius_to_adc(struct ti_bandgap *bgp, long temp, int *adc)
295
{
296
	const struct ti_bandgap_data *conf = bgp->conf;
297
	const int *conv_table = bgp->conf->conv_table;
298
	int high, low, mid, ret = 0;
299 300

	low = 0;
301
	high = conf->adc_end_val - conf->adc_start_val;
302 303
	mid = (high + low) / 2;

304 305 306 307
	if (temp < conv_table[low] || temp > conv_table[high]) {
		ret = -ERANGE;
		goto exit;
	}
308 309

	while (low < high) {
310
		if (temp < conv_table[mid])
311 312 313 314 315 316
			high = mid - 1;
		else
			low = mid + 1;
		mid = (low + high) / 2;
	}

317
	*adc = conf->adc_start_val + low;
318

319 320
exit:
	return ret;
321 322
}

323
/**
324 325
 * ti_bandgap_add_hyst() - add hysteresis (in mCelsius) to an ADC value
 * @bgp: struct ti_bandgap pointer
326 327 328 329 330
 * @adc_val: temperature value in ADC representation
 * @hyst_val: hysteresis value in mCelsius
 * @sum: address where to write the resulting temperature (in ADC scale)
 *
 * Adds an hysteresis value (in mCelsius) to a ADC temperature value.
331 332
 *
 * Return: 0 on success, -ERANGE otherwise.
333
 */
334
static
335 336
int ti_bandgap_add_hyst(struct ti_bandgap *bgp, int adc_val, int hyst_val,
			u32 *sum)
337 338 339 340 341 342 343
{
	int temp, ret;

	/*
	 * Need to add in the mcelsius domain, so we have a temperature
	 * the conv_table range
	 */
344
	ret = ti_bandgap_adc_to_mcelsius(bgp, adc_val, &temp);
345 346 347 348 349
	if (ret < 0)
		goto exit;

	temp += hyst_val;

350
	ret = ti_bandgap_mcelsius_to_adc(bgp, temp, sum);
351 352 353 354 355

exit:
	return ret;
}

356 357
/***   Helper functions handling device Alert/Shutdown signals   ***/

358
/**
359 360
 * ti_bandgap_unmask_interrupts() - unmasks the events of thot & tcold
 * @bgp: struct ti_bandgap pointer
361
 * @id: bandgap sensor id
362 363 364 365 366 367
 * @t_hot: hot temperature value to trigger alert signal
 * @t_cold: cold temperature value to trigger alert signal
 *
 * Checks the requested t_hot and t_cold values and configures the IRQ event
 * masks accordingly. Call this function only if bandgap features HAS(TALERT).
 */
368 369
static void ti_bandgap_unmask_interrupts(struct ti_bandgap *bgp, int id,
					 u32 t_hot, u32 t_cold)
370 371 372 373 374
{
	struct temp_sensor_registers *tsr;
	u32 temp, reg_val;

	/* Read the current on die temperature */
375
	temp = ti_bandgap_read_temp(bgp, id);
376

377
	tsr = bgp->conf->sensors[id].registers;
378
	reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
379

380 381 382 383 384 385 386 387 388
	if (temp < t_hot)
		reg_val |= tsr->mask_hot_mask;
	else
		reg_val &= ~tsr->mask_hot_mask;

	if (t_cold < temp)
		reg_val |= tsr->mask_cold_mask;
	else
		reg_val &= ~tsr->mask_cold_mask;
389
	ti_bandgap_writel(bgp, reg_val, tsr->bgap_mask_ctrl);
390 391
}

392
/**
393 394
 * ti_bandgap_update_alert_threshold() - sequence to update thresholds
 * @bgp: struct ti_bandgap pointer
395 396 397 398 399 400 401 402 403 404
 * @id: bandgap sensor id
 * @val: value (ADC) of a new threshold
 * @hot: desired threshold to be updated. true if threshold hot, false if
 *       threshold cold
 *
 * It will program the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to update t_hot or t_cold, depending on @hot value.
 * It checks the resulting t_hot and t_cold values, based on the new passed @val
 * and configures the thresholds so that t_hot is always greater than t_cold.
 * Call this function only if bandgap features HAS(TALERT).
405 406
 *
 * Return: 0 if no error, else corresponding error
407
 */
408 409
static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
					     int val, bool hot)
410
{
411
	struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data;
412
	struct temp_sensor_registers *tsr;
413 414
	u32 thresh_val, reg_val, t_hot, t_cold;
	int err = 0;
415

416
	tsr = bgp->conf->sensors[id].registers;
417

418
	/* obtain the current value */
419
	thresh_val = ti_bandgap_readl(bgp, tsr->bgap_threshold);
420 421 422 423 424 425 426 427 428
	t_cold = (thresh_val & tsr->threshold_tcold_mask) >>
		__ffs(tsr->threshold_tcold_mask);
	t_hot = (thresh_val & tsr->threshold_thot_mask) >>
		__ffs(tsr->threshold_thot_mask);
	if (hot)
		t_hot = val;
	else
		t_cold = val;

429
	if (t_cold > t_hot) {
430
		if (hot)
431 432 433
			err = ti_bandgap_add_hyst(bgp, t_hot,
						  -ts_data->hyst_val,
						  &t_cold);
434
		else
435 436 437
			err = ti_bandgap_add_hyst(bgp, t_cold,
						  ts_data->hyst_val,
						  &t_hot);
438 439
	}

440
	/* write the new threshold values */
441 442 443 444
	reg_val = thresh_val &
		  ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
	reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
		   (t_cold << __ffs(tsr->threshold_tcold_mask));
445
	ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold);
446

447
	if (err) {
448
		dev_err(bgp->dev, "failed to reprogram thot threshold\n");
449 450
		err = -EIO;
		goto exit;
451 452
	}

453
	ti_bandgap_unmask_interrupts(bgp, id, t_hot, t_cold);
454 455
exit:
	return err;
456 457
}

458
/**
459 460
 * ti_bandgap_validate() - helper to check the sanity of a struct ti_bandgap
 * @bgp: struct ti_bandgap pointer
461 462 463 464
 * @id: bandgap sensor id
 *
 * Checks if the bandgap pointer is valid and if the sensor id is also
 * applicable.
465 466 467
 *
 * Return: 0 if no errors, -EINVAL for invalid @bgp pointer or -ERANGE if
 * @id cannot index @bgp sensors.
468
 */
469
static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
470
{
471
	int ret = 0;
472

473
	if (!bgp || IS_ERR(bgp)) {
474 475 476
		pr_err("%s: invalid bandgap pointer\n", __func__);
		ret = -EINVAL;
		goto exit;
477 478
	}

479 480
	if ((id < 0) || (id >= bgp->conf->sensor_count)) {
		dev_err(bgp->dev, "%s: sensor id out of range (%d)\n",
481 482
			__func__, id);
		ret = -ERANGE;
483 484
	}

485 486
exit:
	return ret;
487 488
}

489
/**
490 491
 * _ti_bandgap_write_threshold() - helper to update TALERT t_cold or t_hot
 * @bgp: struct ti_bandgap pointer
492 493 494 495 496 497 498 499 500
 * @id: bandgap sensor id
 * @val: value (mCelsius) of a new threshold
 * @hot: desired threshold to be updated. true if threshold hot, false if
 *       threshold cold
 *
 * It will update the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to update t_hot or t_cold, depending on @hot value.
 * Validates the mCelsius range and update the requested threshold.
 * Call this function only if bandgap features HAS(TALERT).
501 502
 *
 * Return: 0 if no error, else corresponding error value.
503
 */
504 505
static int _ti_bandgap_write_threshold(struct ti_bandgap *bgp, int id, int val,
				       bool hot)
506
{
507 508 509 510 511
	struct temp_sensor_data *ts_data;
	struct temp_sensor_registers *tsr;
	u32 adc_val;
	int ret;

512
	ret = ti_bandgap_validate(bgp, id);
513 514 515
	if (ret)
		goto exit;

516
	if (!TI_BANDGAP_HAS(bgp, TALERT)) {
517 518
		ret = -ENOTSUPP;
		goto exit;
519 520
	}

521 522
	ts_data = bgp->conf->sensors[id].ts_data;
	tsr = bgp->conf->sensors[id].registers;
523 524 525 526 527 528
	if (hot) {
		if (val < ts_data->min_temp + ts_data->hyst_val)
			ret = -EINVAL;
	} else {
		if (val > ts_data->max_temp + ts_data->hyst_val)
			ret = -EINVAL;
529 530
	}

531 532 533
	if (ret)
		goto exit;

534
	ret = ti_bandgap_mcelsius_to_adc(bgp, val, &adc_val);
535 536 537
	if (ret < 0)
		goto exit;

538
	spin_lock(&bgp->lock);
539
	ret = ti_bandgap_update_alert_threshold(bgp, id, adc_val, hot);
540
	spin_unlock(&bgp->lock);
541 542 543

exit:
	return ret;
544 545
}

546
/**
547 548
 * _ti_bandgap_read_threshold() - helper to read TALERT t_cold or t_hot
 * @bgp: struct ti_bandgap pointer
549 550 551 552 553 554 555 556
 * @id: bandgap sensor id
 * @val: value (mCelsius) of a threshold
 * @hot: desired threshold to be read. true if threshold hot, false if
 *       threshold cold
 *
 * It will fetch the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to read t_hot or t_cold, depending on @hot value.
 * Call this function only if bandgap features HAS(TALERT).
557 558 559
 *
 * Return: 0 if no error, -ENOTSUPP if it has no TALERT support, or the
 * corresponding error value if some operation fails.
560
 */
561 562
static int _ti_bandgap_read_threshold(struct ti_bandgap *bgp, int id,
				      int *val, bool hot)
563 564
{
	struct temp_sensor_registers *tsr;
565 566
	u32 temp, mask;
	int ret = 0;
567

568
	ret = ti_bandgap_validate(bgp, id);
569
	if (ret)
570
		goto exit;
571

572
	if (!TI_BANDGAP_HAS(bgp, TALERT)) {
573 574 575
		ret = -ENOTSUPP;
		goto exit;
	}
576

577
	tsr = bgp->conf->sensors[id].registers;
578 579 580 581 582
	if (hot)
		mask = tsr->threshold_thot_mask;
	else
		mask = tsr->threshold_tcold_mask;

583
	temp = ti_bandgap_readl(bgp, tsr->bgap_threshold);
584
	temp = (temp & mask) >> __ffs(mask);
585
	ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
586
	if (ret) {
587
		dev_err(bgp->dev, "failed to read thot\n");
588 589
		ret = -EIO;
		goto exit;
590 591
	}

592
	*val = temp;
593

594
exit:
595
	return ret;
596 597
}

598 599 600
/***   Exposed APIs   ***/

/**
601
 * ti_bandgap_read_thot() - reads sensor current thot
602 603 604
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @thot: resulting current thot value
605
 *
606
 * Return: 0 on success or the proper error code
607
 */
608
int ti_bandgap_read_thot(struct ti_bandgap *bgp, int id, int *thot)
609
{
610
	return _ti_bandgap_read_threshold(bgp, id, thot, true);
611 612
}

613
/**
614
 * ti_bandgap_write_thot() - sets sensor current thot
615 616 617
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @val: desired thot value
618
 *
619
 * Return: 0 on success or the proper error code
620
 */
621
int ti_bandgap_write_thot(struct ti_bandgap *bgp, int id, int val)
622
{
623
	return _ti_bandgap_write_threshold(bgp, id, val, true);
624 625 626
}

/**
627
 * ti_bandgap_read_tcold() - reads sensor current tcold
628 629 630
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @tcold: resulting current tcold value
631
 *
632
 * Return: 0 on success or the proper error code
633
 */
634
int ti_bandgap_read_tcold(struct ti_bandgap *bgp, int id, int *tcold)
635
{
636
	return _ti_bandgap_read_threshold(bgp, id, tcold, false);
637 638 639
}

/**
640
 * ti_bandgap_write_tcold() - sets the sensor tcold
641 642 643
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @val: desired tcold value
644
 *
645
 * Return: 0 on success or the proper error code
646
 */
647
int ti_bandgap_write_tcold(struct ti_bandgap *bgp, int id, int val)
648
{
649
	return _ti_bandgap_write_threshold(bgp, id, val, false);
650 651
}

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
/**
 * ti_bandgap_read_counter() - read the sensor counter
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: resulting update interval in miliseconds
 */
static void ti_bandgap_read_counter(struct ti_bandgap *bgp, int id,
				    int *interval)
{
	struct temp_sensor_registers *tsr;
	int time;

	tsr = bgp->conf->sensors[id].registers;
	time = ti_bandgap_readl(bgp, tsr->bgap_counter);
	time = (time & tsr->counter_mask) >>
					__ffs(tsr->counter_mask);
	time = time * 1000 / bgp->clk_rate;
	*interval = time;
}

/**
 * ti_bandgap_read_counter_delay() - read the sensor counter delay
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: resulting update interval in miliseconds
 */
static void ti_bandgap_read_counter_delay(struct ti_bandgap *bgp, int id,
					  int *interval)
{
	struct temp_sensor_registers *tsr;
	int reg_val;

	tsr = bgp->conf->sensors[id].registers;

	reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
	reg_val = (reg_val & tsr->mask_counter_delay_mask) >>
				__ffs(tsr->mask_counter_delay_mask);
	switch (reg_val) {
	case 0:
		*interval = 0;
		break;
	case 1:
		*interval = 1;
		break;
	case 2:
		*interval = 10;
		break;
	case 3:
		*interval = 100;
		break;
	case 4:
		*interval = 250;
		break;
	case 5:
		*interval = 500;
		break;
	default:
		dev_warn(bgp->dev, "Wrong counter delay value read from register %X",
			 reg_val);
	}
}

714
/**
715
 * ti_bandgap_read_update_interval() - read the sensor update interval
716 717 718
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: resulting update interval in miliseconds
719
 *
720
 * Return: 0 on success or the proper error code
721
 */
722 723
int ti_bandgap_read_update_interval(struct ti_bandgap *bgp, int id,
				    int *interval)
724
{
725
	int ret = 0;
726

727
	ret = ti_bandgap_validate(bgp, id);
728
	if (ret)
729
		goto exit;
730

731 732 733 734 735
	if (!TI_BANDGAP_HAS(bgp, COUNTER) &&
	    !TI_BANDGAP_HAS(bgp, COUNTER_DELAY)) {
		ret = -ENOTSUPP;
		goto exit;
	}
736

737 738 739 740
	if (TI_BANDGAP_HAS(bgp, COUNTER)) {
		ti_bandgap_read_counter(bgp, id, interval);
		goto exit;
	}
741

742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786
	ti_bandgap_read_counter_delay(bgp, id, interval);
exit:
	return ret;
}

/**
 * ti_bandgap_write_counter_delay() - set the counter_delay
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: desired update interval in miliseconds
 *
 * Return: 0 on success or the proper error code
 */
static int ti_bandgap_write_counter_delay(struct ti_bandgap *bgp, int id,
					  u32 interval)
{
	int rval;

	switch (interval) {
	case 0: /* Immediate conversion */
		rval = 0x0;
		break;
	case 1: /* Conversion after ever 1ms */
		rval = 0x1;
		break;
	case 10: /* Conversion after ever 10ms */
		rval = 0x2;
		break;
	case 100: /* Conversion after ever 100ms */
		rval = 0x3;
		break;
	case 250: /* Conversion after ever 250ms */
		rval = 0x4;
		break;
	case 500: /* Conversion after ever 500ms */
		rval = 0x5;
		break;
	default:
		dev_warn(bgp->dev, "Delay %d ms is not supported\n", interval);
		return -EINVAL;
	}

	spin_lock(&bgp->lock);
	RMW_BITS(bgp, id, bgap_mask_ctrl, mask_counter_delay_mask, rval);
	spin_unlock(&bgp->lock);
787 788 789 790

	return 0;
}

791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
/**
 * ti_bandgap_write_counter() - set the bandgap sensor counter
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: desired update interval in miliseconds
 */
static void ti_bandgap_write_counter(struct ti_bandgap *bgp, int id,
				     u32 interval)
{
	interval = interval * bgp->clk_rate / 1000;
	spin_lock(&bgp->lock);
	RMW_BITS(bgp, id, bgap_counter, counter_mask, interval);
	spin_unlock(&bgp->lock);
}

806
/**
807
 * ti_bandgap_write_update_interval() - set the update interval
808 809 810
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: desired update interval in miliseconds
811
 *
812
 * Return: 0 on success or the proper error code
813
 */
814 815
int ti_bandgap_write_update_interval(struct ti_bandgap *bgp,
				     int id, u32 interval)
816
{
817
	int ret = ti_bandgap_validate(bgp, id);
818
	if (ret)
819
		goto exit;
820

821 822 823 824 825
	if (!TI_BANDGAP_HAS(bgp, COUNTER) &&
	    !TI_BANDGAP_HAS(bgp, COUNTER_DELAY)) {
		ret = -ENOTSUPP;
		goto exit;
	}
826

827 828 829 830
	if (TI_BANDGAP_HAS(bgp, COUNTER)) {
		ti_bandgap_write_counter(bgp, id, interval);
		goto exit;
	}
831

832 833 834
	ret = ti_bandgap_write_counter_delay(bgp, id, interval);
exit:
	return ret;
835 836 837
}

/**
838
 * ti_bandgap_read_temperature() - report current temperature
839 840 841
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @temperature: resulting temperature
842
 *
843
 * Return: 0 on success or the proper error code
844
 */
845 846
int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
				int *temperature)
847 848 849 850
{
	u32 temp;
	int ret;

851
	ret = ti_bandgap_validate(bgp, id);
852 853 854
	if (ret)
		return ret;

855
	spin_lock(&bgp->lock);
856
	temp = ti_bandgap_read_temp(bgp, id);
857
	spin_unlock(&bgp->lock);
858

859
	ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
860 861 862 863 864 865 866 867 868
	if (ret)
		return -EIO;

	*temperature = temp;

	return 0;
}

/**
869
 * ti_bandgap_set_sensor_data() - helper function to store thermal
870
 * framework related data.
871 872 873
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @data: thermal framework related data to be stored
874
 *
875
 * Return: 0 on success or the proper error code
876
 */
877
int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data)
878
{
879
	int ret = ti_bandgap_validate(bgp, id);
880 881 882
	if (ret)
		return ret;

883
	bgp->regval[id].data = data;
884 885 886 887 888

	return 0;
}

/**
889
 * ti_bandgap_get_sensor_data() - helper function to get thermal
890
 * framework related data.
891 892
 * @bgp: pointer to bandgap instance
 * @id: sensor id
893
 *
894
 * Return: data stored by set function with sensor id on success or NULL
895
 */
896
void *ti_bandgap_get_sensor_data(struct ti_bandgap *bgp, int id)
897
{
898
	int ret = ti_bandgap_validate(bgp, id);
899 900 901
	if (ret)
		return ERR_PTR(ret);

902
	return bgp->regval[id].data;
903 904
}

905 906
/***   Helper functions used during device initialization   ***/

907
/**
908 909
 * ti_bandgap_force_single_read() - executes 1 single ADC conversion
 * @bgp: pointer to struct ti_bandgap
910 911 912 913
 * @id: sensor id which it is desired to read 1 temperature
 *
 * Used to initialize the conversion state machine and set it to a valid
 * state. Called during device initialization and context restore events.
914 915
 *
 * Return: 0
916
 */
917
static int
918
ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id)
919 920 921 922
{
	u32 temp = 0, counter = 1000;

	/* Select single conversion mode */
923
	if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
924
		RMW_BITS(bgp, id, bgap_mode_ctrl, mode_ctrl_mask, 0);
925 926

	/* Start of Conversion = 1 */
927
	RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 1);
928
	/* Wait until DTEMP is updated */
929
	temp = ti_bandgap_read_temp(bgp, id);
930 931

	while ((temp == 0) && --counter)
932
		temp = ti_bandgap_read_temp(bgp, id);
933
	/* REVISIT: Check correct condition for end of conversion */
934

935
	/* Start of Conversion = 0 */
936
	RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 0);
937 938 939 940 941

	return 0;
}

/**
942 943
 * ti_bandgap_set_continous_mode() - One time enabling of continuous mode
 * @bgp: pointer to struct ti_bandgap
944
 *
945 946 947 948
 * Call this function only if HAS(MODE_CONFIG) is set. As this driver may
 * be used for junction temperature monitoring, it is desirable that the
 * sensors are operational all the time, so that alerts are generated
 * properly.
949 950
 *
 * Return: 0
951
 */
952
static int ti_bandgap_set_continuous_mode(struct ti_bandgap *bgp)
953 954 955
{
	int i;

956
	for (i = 0; i < bgp->conf->sensor_count; i++) {
957
		/* Perform a single read just before enabling continuous */
958
		ti_bandgap_force_single_read(bgp, i);
959
		RMW_BITS(bgp, i, bgap_mode_ctrl, mode_ctrl_mask, 1);
960 961 962 963 964
	}

	return 0;
}

965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
/**
 * ti_bandgap_get_trend() - To fetch the temperature trend of a sensor
 * @bgp: pointer to struct ti_bandgap
 * @id: id of the individual sensor
 * @trend: Pointer to trend.
 *
 * This function needs to be called to fetch the temperature trend of a
 * Particular sensor. The function computes the difference in temperature
 * w.r.t time. For the bandgaps with built in history buffer the temperatures
 * are read from the buffer and for those without the Buffer -ENOTSUPP is
 * returned.
 *
 * Return: 0 if no error, else return corresponding error. If no
 *		error then the trend value is passed on to trend parameter
 */
int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
{
	struct temp_sensor_registers *tsr;
	u32 temp1, temp2, reg1, reg2;
	int t1, t2, interval, ret = 0;

	ret = ti_bandgap_validate(bgp, id);
	if (ret)
		goto exit;

	if (!TI_BANDGAP_HAS(bgp, HISTORY_BUFFER) ||
	    !TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
		ret = -ENOTSUPP;
		goto exit;
	}

996 997
	spin_lock(&bgp->lock);

998 999 1000
	tsr = bgp->conf->sensors[id].registers;

	/* Freeze and read the last 2 valid readings */
1001
	RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
	reg1 = tsr->ctrl_dtemp_1;
	reg2 = tsr->ctrl_dtemp_2;

	/* read temperature from history buffer */
	temp1 = ti_bandgap_readl(bgp, reg1);
	temp1 &= tsr->bgap_dtemp_mask;

	temp2 = ti_bandgap_readl(bgp, reg2);
	temp2 &= tsr->bgap_dtemp_mask;

	/* Convert from adc values to mCelsius temperature */
	ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
	if (ret)
1015
		goto unfreeze;
1016 1017 1018

	ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
	if (ret)
1019
		goto unfreeze;
1020 1021 1022

	/* Fetch the update interval */
	ret = ti_bandgap_read_update_interval(bgp, id, &interval);
1023
	if (ret)
1024
		goto unfreeze;
1025

1026 1027 1028 1029
	/* Set the interval to 1 ms if bandgap counter delay is not set */
	if (interval == 0)
		interval = 1;

1030 1031 1032 1033 1034
	*trend = (t1 - t2) / interval;

	dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
		t1, t2, *trend);

1035 1036 1037
unfreeze:
	RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
	spin_unlock(&bgp->lock);
1038 1039 1040 1041
exit:
	return ret;
}

1042
/**
1043 1044
 * ti_bandgap_tshut_init() - setup and initialize tshut handling
 * @bgp: pointer to struct ti_bandgap
1045 1046 1047 1048 1049 1050 1051 1052
 * @pdev: pointer to device struct platform_device
 *
 * Call this function only in case the bandgap features HAS(TSHUT).
 * In this case, the driver needs to handle the TSHUT signal as an IRQ.
 * The IRQ is wired as a GPIO, and for this purpose, it is required
 * to specify which GPIO line is used. TSHUT IRQ is fired anytime
 * one of the bandgap sensors violates the TSHUT high/hot threshold.
 * And in that case, the system must go off.
1053 1054
 *
 * Return: 0 if no error, else error status
1055
 */
1056 1057
static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
				 struct platform_device *pdev)
1058
{
1059
	int gpio_nr = bgp->tshut_gpio;
1060 1061 1062 1063 1064
	int status;

	/* Request for gpio_86 line */
	status = gpio_request(gpio_nr, "tshut");
	if (status < 0) {
1065
		dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n", 86);
1066 1067 1068 1069
		return status;
	}
	status = gpio_direction_input(gpio_nr);
	if (status) {
1070
		dev_err(bgp->dev, "Cannot set input TSHUT GPIO %d\n", gpio_nr);
1071 1072 1073
		return status;
	}

1074 1075
	status = request_irq(gpio_to_irq(gpio_nr), ti_bandgap_tshut_irq_handler,
			     IRQF_TRIGGER_RISING, "tshut", NULL);
1076 1077
	if (status) {
		gpio_free(gpio_nr);
1078
		dev_err(bgp->dev, "request irq failed for TSHUT");
1079 1080 1081 1082 1083
	}

	return 0;
}

1084
/**
1085 1086
 * ti_bandgap_alert_init() - setup and initialize talert handling
 * @bgp: pointer to struct ti_bandgap
1087 1088 1089 1090 1091 1092 1093
 * @pdev: pointer to device struct platform_device
 *
 * Call this function only in case the bandgap features HAS(TALERT).
 * In this case, the driver needs to handle the TALERT signals as an IRQs.
 * TALERT is a normal IRQ and it is fired any time thresholds (hot or cold)
 * are violated. In these situation, the driver must reprogram the thresholds,
 * accordingly to specified policy.
1094 1095
 *
 * Return: 0 if no error, else return corresponding error.
1096
 */
1097 1098
static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
				  struct platform_device *pdev)
1099 1100 1101
{
	int ret;

1102 1103
	bgp->irq = platform_get_irq(pdev, 0);
	if (bgp->irq < 0) {
1104
		dev_err(&pdev->dev, "get_irq failed\n");
1105
		return bgp->irq;
1106
	}
1107
	ret = request_threaded_irq(bgp->irq, NULL,
1108
				   ti_bandgap_talert_irq_handler,
1109
				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
1110
				   "talert", bgp);
1111 1112 1113 1114 1115 1116 1117 1118
	if (ret) {
		dev_err(&pdev->dev, "Request threaded irq failed.\n");
		return ret;
	}

	return 0;
}

1119
static const struct of_device_id of_ti_bandgap_match[];
1120
/**
1121
 * ti_bandgap_build() - parse DT and setup a struct ti_bandgap
1122 1123 1124 1125
 * @pdev: pointer to device struct platform_device
 *
 * Used to read the device tree properties accordingly to the bandgap
 * matching version. Based on bandgap version and its capabilities it
1126
 * will build a struct ti_bandgap out of the required DT entries.
1127 1128 1129
 *
 * Return: valid bandgap structure if successful, else returns ERR_PTR
 * return value must be verified with IS_ERR.
1130
 */
1131
static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
1132 1133 1134
{
	struct device_node *node = pdev->dev.of_node;
	const struct of_device_id *of_id;
1135
	struct ti_bandgap *bgp;
1136 1137 1138 1139 1140 1141 1142 1143 1144
	struct resource *res;
	int i;

	/* just for the sake */
	if (!node) {
		dev_err(&pdev->dev, "no platform information available\n");
		return ERR_PTR(-EINVAL);
	}

1145
	bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
1146
	if (!bgp) {
1147 1148 1149 1150
		dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
		return ERR_PTR(-ENOMEM);
	}

1151
	of_id = of_match_device(of_ti_bandgap_match, &pdev->dev);
1152
	if (of_id)
1153
		bgp->conf = of_id->data;
1154

1155 1156 1157
	/* register shadow for context save and restore */
	bgp->regval = devm_kzalloc(&pdev->dev, sizeof(*bgp->regval) *
				   bgp->conf->sensor_count, GFP_KERNEL);
1158
	if (!bgp->regval) {
1159 1160 1161 1162
		dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
		return ERR_PTR(-ENOMEM);
	}

1163 1164 1165 1166 1167 1168 1169
	i = 0;
	do {
		void __iomem *chunk;

		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		if (!res)
			break;
1170
		chunk = devm_ioremap_resource(&pdev->dev, res);
1171
		if (i == 0)
1172
			bgp->base = chunk;
1173 1174
		if (IS_ERR(chunk))
			return ERR_CAST(chunk);
1175

1176 1177 1178
		i++;
	} while (res);

1179
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
1180
		bgp->tshut_gpio = of_get_gpio(node, 0);
1181
		if (!gpio_is_valid(bgp->tshut_gpio)) {
1182
			dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
1183
				bgp->tshut_gpio);
1184 1185 1186 1187
			return ERR_PTR(-EINVAL);
		}
	}

1188
	return bgp;
1189 1190
}

1191 1192
/***   Device driver call backs   ***/

1193
static
1194
int ti_bandgap_probe(struct platform_device *pdev)
1195
{
1196
	struct ti_bandgap *bgp;
1197 1198
	int clk_rate, ret = 0, i;

1199
	bgp = ti_bandgap_build(pdev);
1200
	if (IS_ERR(bgp)) {
1201
		dev_err(&pdev->dev, "failed to fetch platform data\n");
1202
		return PTR_ERR(bgp);
1203
	}
1204
	bgp->dev = &pdev->dev;
1205

1206 1207
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
		ret = ti_bandgap_tshut_init(bgp, pdev);
1208 1209 1210 1211 1212 1213 1214
		if (ret) {
			dev_err(&pdev->dev,
				"failed to initialize system tshut IRQ\n");
			return ret;
		}
	}

1215
	bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
1216
	ret = IS_ERR(bgp->fclock);
1217 1218
	if (ret) {
		dev_err(&pdev->dev, "failed to request fclock reference\n");
1219
		ret = PTR_ERR(bgp->fclock);
1220 1221 1222
		goto free_irqs;
	}

1223
	bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
1224
	ret = IS_ERR(bgp->div_clk);
1225 1226 1227
	if (ret) {
		dev_err(&pdev->dev,
			"failed to request div_ts_ck clock ref\n");
1228
		ret = PTR_ERR(bgp->div_clk);
1229 1230 1231
		goto free_irqs;
	}

1232
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1233 1234 1235
		struct temp_sensor_registers *tsr;
		u32 val;

1236
		tsr = bgp->conf->sensors[i].registers;
1237 1238 1239 1240 1241
		/*
		 * check if the efuse has a non-zero value if not
		 * it is an untrimmed sample and the temperatures
		 * may not be accurate
		 */
1242
		val = ti_bandgap_readl(bgp, tsr->bgap_efuse);
1243 1244 1245 1246 1247
		if (ret || !val)
			dev_info(&pdev->dev,
				 "Non-trimmed BGAP, Temp not accurate\n");
	}

1248 1249 1250
	clk_rate = clk_round_rate(bgp->div_clk,
				  bgp->conf->sensors[0].ts_data->max_freq);
	if (clk_rate < bgp->conf->sensors[0].ts_data->min_freq ||
1251
	    clk_rate <= 0) {
1252 1253 1254 1255 1256
		ret = -ENODEV;
		dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
		goto put_clks;
	}

1257
	ret = clk_set_rate(bgp->div_clk, clk_rate);
1258 1259 1260
	if (ret)
		dev_err(&pdev->dev, "Cannot re-set clock rate. Continuing\n");

1261
	bgp->clk_rate = clk_rate;
1262
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1263
		clk_prepare_enable(bgp->fclock);
1264

1265

1266 1267 1268
	spin_lock_init(&bgp->lock);
	bgp->dev = &pdev->dev;
	platform_set_drvdata(pdev, bgp);
1269

1270
	ti_bandgap_power(bgp, true);
1271 1272

	/* Set default counter to 1 for now */
1273
	if (TI_BANDGAP_HAS(bgp, COUNTER))
1274 1275
		for (i = 0; i < bgp->conf->sensor_count; i++)
			RMW_BITS(bgp, i, bgap_counter, counter_mask, 1);
1276

1277
	/* Set default thresholds for alert and shutdown */
1278
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1279 1280
		struct temp_sensor_data *ts_data;

1281
		ts_data = bgp->conf->sensors[i].ts_data;
1282

1283
		if (TI_BANDGAP_HAS(bgp, TALERT)) {
1284
			/* Set initial Talert thresholds */
1285
			RMW_BITS(bgp, i, bgap_threshold,
1286
				 threshold_tcold_mask, ts_data->t_cold);
1287
			RMW_BITS(bgp, i, bgap_threshold,
1288 1289
				 threshold_thot_mask, ts_data->t_hot);
			/* Enable the alert events */
1290 1291
			RMW_BITS(bgp, i, bgap_mask_ctrl, mask_hot_mask, 1);
			RMW_BITS(bgp, i, bgap_mask_ctrl, mask_cold_mask, 1);
1292 1293
		}

1294
		if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG)) {
1295
			/* Set initial Tshut thresholds */
1296
			RMW_BITS(bgp, i, tshut_threshold,
1297
				 tshut_hot_mask, ts_data->tshut_hot);
1298
			RMW_BITS(bgp, i, tshut_threshold,
1299
				 tshut_cold_mask, ts_data->tshut_cold);
1300 1301 1302
		}
	}

1303 1304
	if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
		ti_bandgap_set_continuous_mode(bgp);
1305 1306

	/* Set .250 seconds time as default counter */
1307
	if (TI_BANDGAP_HAS(bgp, COUNTER))
1308 1309 1310
		for (i = 0; i < bgp->conf->sensor_count; i++)
			RMW_BITS(bgp, i, bgap_counter, counter_mask,
				 bgp->clk_rate / 4);
1311 1312

	/* Every thing is good? Then expose the sensors */
1313
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1314 1315
		char *domain;

1316 1317 1318 1319 1320
		if (bgp->conf->sensors[i].register_cooling) {
			ret = bgp->conf->sensors[i].register_cooling(bgp, i);
			if (ret)
				goto remove_sensors;
		}
1321

1322 1323 1324 1325 1326 1327
		if (bgp->conf->expose_sensor) {
			domain = bgp->conf->sensors[i].domain;
			ret = bgp->conf->expose_sensor(bgp, i, domain);
			if (ret)
				goto remove_last_cooling;
		}
1328 1329 1330 1331 1332 1333 1334
	}

	/*
	 * Enable the Interrupts once everything is set. Otherwise irq handler
	 * might be called as soon as it is enabled where as rest of framework
	 * is still getting initialised.
	 */
1335 1336
	if (TI_BANDGAP_HAS(bgp, TALERT)) {
		ret = ti_bandgap_talert_init(bgp, pdev);
1337 1338
		if (ret) {
			dev_err(&pdev->dev, "failed to initialize Talert IRQ\n");
1339
			i = bgp->conf->sensor_count;
1340 1341 1342 1343 1344 1345
			goto disable_clk;
		}
	}

	return 0;

1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
remove_last_cooling:
	if (bgp->conf->sensors[i].unregister_cooling)
		bgp->conf->sensors[i].unregister_cooling(bgp, i);
remove_sensors:
	for (i--; i >= 0; i--) {
		if (bgp->conf->sensors[i].unregister_cooling)
			bgp->conf->sensors[i].unregister_cooling(bgp, i);
		if (bgp->conf->remove_sensor)
			bgp->conf->remove_sensor(bgp, i);
	}
	ti_bandgap_power(bgp, false);
1357
disable_clk:
1358
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1359
		clk_disable_unprepare(bgp->fclock);
1360
put_clks:
1361 1362
	clk_put(bgp->fclock);
	clk_put(bgp->div_clk);
1363
free_irqs:
1364
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
1365 1366
		free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
		gpio_free(bgp->tshut_gpio);
1367 1368 1369 1370 1371 1372
	}

	return ret;
}

static
1373
int ti_bandgap_remove(struct platform_device *pdev)
1374
{
1375
	struct ti_bandgap *bgp = platform_get_drvdata(pdev);
1376 1377 1378
	int i;

	/* First thing is to remove sensor interfaces */
1379
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1380
		if (bgp->conf->sensors[i].unregister_cooling)
1381
			bgp->conf->sensors[i].unregister_cooling(bgp, i);
1382

1383 1384
		if (bgp->conf->remove_sensor)
			bgp->conf->remove_sensor(bgp, i);
1385 1386
	}

1387
	ti_bandgap_power(bgp, false);
1388

1389
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1390 1391 1392
		clk_disable_unprepare(bgp->fclock);
	clk_put(bgp->fclock);
	clk_put(bgp->div_clk);
1393

1394
	if (TI_BANDGAP_HAS(bgp, TALERT))
1395
		free_irq(bgp->irq, bgp);
1396

1397
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
1398 1399
		free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
		gpio_free(bgp->tshut_gpio);
1400 1401 1402 1403 1404
	}

	return 0;
}

1405
#ifdef CONFIG_PM_SLEEP
1406
static int ti_bandgap_save_ctxt(struct ti_bandgap *bgp)
1407 1408 1409
{
	int i;

1410
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1411 1412 1413
		struct temp_sensor_registers *tsr;
		struct temp_sensor_regval *rval;

1414
		rval = &bgp->regval[i];
1415
		tsr = bgp->conf->sensors[i].registers;
1416

1417 1418
		if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
			rval->bg_mode_ctrl = ti_bandgap_readl(bgp,
1419
							tsr->bgap_mode_ctrl);
1420 1421
		if (TI_BANDGAP_HAS(bgp, COUNTER))
			rval->bg_counter = ti_bandgap_readl(bgp,
1422
							tsr->bgap_counter);
1423 1424
		if (TI_BANDGAP_HAS(bgp, TALERT)) {
			rval->bg_threshold = ti_bandgap_readl(bgp,
1425
							tsr->bgap_threshold);
1426
			rval->bg_ctrl = ti_bandgap_readl(bgp,
1427
						   tsr->bgap_mask_ctrl);
1428 1429
		}

1430 1431
		if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
			rval->tshut_threshold = ti_bandgap_readl(bgp,
1432
						   tsr->tshut_threshold);
1433 1434 1435 1436 1437
	}

	return 0;
}

1438
static int ti_bandgap_restore_ctxt(struct ti_bandgap *bgp)
1439 1440 1441
{
	int i;

1442
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1443 1444 1445 1446
		struct temp_sensor_registers *tsr;
		struct temp_sensor_regval *rval;
		u32 val = 0;

1447
		rval = &bgp->regval[i];
1448
		tsr = bgp->conf->sensors[i].registers;
1449

1450 1451
		if (TI_BANDGAP_HAS(bgp, COUNTER))
			val = ti_bandgap_readl(bgp, tsr->bgap_counter);
1452

1453 1454 1455
		if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
			ti_bandgap_writel(bgp, rval->tshut_threshold,
					  tsr->tshut_threshold);
1456 1457 1458
		/* Force immediate temperature measurement and update
		 * of the DTEMP field
		 */
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
		ti_bandgap_force_single_read(bgp, i);

		if (TI_BANDGAP_HAS(bgp, COUNTER))
			ti_bandgap_writel(bgp, rval->bg_counter,
					  tsr->bgap_counter);
		if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
			ti_bandgap_writel(bgp, rval->bg_mode_ctrl,
					  tsr->bgap_mode_ctrl);
		if (TI_BANDGAP_HAS(bgp, TALERT)) {
			ti_bandgap_writel(bgp, rval->bg_threshold,
					  tsr->bgap_threshold);
			ti_bandgap_writel(bgp, rval->bg_ctrl,
					  tsr->bgap_mask_ctrl);
1472 1473 1474 1475 1476 1477
		}
	}

	return 0;
}

1478
static int ti_bandgap_suspend(struct device *dev)
1479
{
1480
	struct ti_bandgap *bgp = dev_get_drvdata(dev);
1481 1482
	int err;

1483 1484
	err = ti_bandgap_save_ctxt(bgp);
	ti_bandgap_power(bgp, false);
1485

1486
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1487
		clk_disable_unprepare(bgp->fclock);
1488 1489 1490 1491

	return err;
}

1492
static int ti_bandgap_resume(struct device *dev)
1493
{
1494
	struct ti_bandgap *bgp = dev_get_drvdata(dev);
1495

1496
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1497
		clk_prepare_enable(bgp->fclock);
1498

1499
	ti_bandgap_power(bgp, true);
1500

1501
	return ti_bandgap_restore_ctxt(bgp);
1502
}
1503 1504
static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
			 ti_bandgap_resume);
1505

1506
#define DEV_PM_OPS	(&ti_bandgap_dev_pm_ops)
1507 1508 1509 1510
#else
#define DEV_PM_OPS	NULL
#endif

1511
static const struct of_device_id of_ti_bandgap_match[] = {
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
#ifdef CONFIG_OMAP4_THERMAL
	{
		.compatible = "ti,omap4430-bandgap",
		.data = (void *)&omap4430_data,
	},
	{
		.compatible = "ti,omap4460-bandgap",
		.data = (void *)&omap4460_data,
	},
	{
		.compatible = "ti,omap4470-bandgap",
		.data = (void *)&omap4470_data,
	},
1525 1526 1527 1528 1529 1530
#endif
#ifdef CONFIG_OMAP5_THERMAL
	{
		.compatible = "ti,omap5430-bandgap",
		.data = (void *)&omap5430_data,
	},
1531 1532 1533 1534 1535 1536
#endif
#ifdef CONFIG_DRA752_THERMAL
	{
		.compatible = "ti,dra752-bandgap",
		.data = (void *)&dra752_data,
	},
1537
#endif
1538 1539 1540
	/* Sentinel */
	{ },
};
1541
MODULE_DEVICE_TABLE(of, of_ti_bandgap_match);
1542

1543 1544 1545
static struct platform_driver ti_bandgap_sensor_driver = {
	.probe = ti_bandgap_probe,
	.remove = ti_bandgap_remove,
1546
	.driver = {
1547
			.name = "ti-soc-thermal",
1548
			.pm = DEV_PM_OPS,
1549
			.of_match_table	= of_ti_bandgap_match,
1550 1551 1552
	},
};

1553
module_platform_driver(ti_bandgap_sensor_driver);
1554 1555 1556

MODULE_DESCRIPTION("OMAP4+ bandgap temperature sensor driver");
MODULE_LICENSE("GPL v2");
1557
MODULE_ALIAS("platform:ti-soc-thermal");
1558
MODULE_AUTHOR("Texas Instrument Inc.");