Home | History | Annotate | Download | only in power
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2011 Samsung Electronics
      4  * Lukasz Majewski <l.majewski (at) samsung.com>
      5  *
      6  * (C) Copyright 2010
      7  * Stefano Babic, DENX Software Engineering, sbabic (at) denx.de
      8  *
      9  * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
     10  */
     11 
     12 #include <common.h>
     13 #include <linux/types.h>
     14 #include <power/pmic.h>
     15 #include <i2c.h>
     16 #include <linux/compiler.h>
     17 
     18 int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
     19 {
     20 	unsigned char buf[4] = { 0 };
     21 
     22 	if (check_reg(p, reg))
     23 		return -EINVAL;
     24 
     25 	I2C_SET_BUS(p->bus);
     26 
     27 	switch (pmic_i2c_tx_num) {
     28 	case 3:
     29 		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
     30 			buf[2] = (cpu_to_le32(val) >> 16) & 0xff;
     31 			buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
     32 			buf[0] = cpu_to_le32(val) & 0xff;
     33 		} else {
     34 			buf[0] = (cpu_to_le32(val) >> 16) & 0xff;
     35 			buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
     36 			buf[2] = cpu_to_le32(val) & 0xff;
     37 		}
     38 		break;
     39 	case 2:
     40 		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
     41 			buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
     42 			buf[0] = cpu_to_le32(val) & 0xff;
     43 		} else {
     44 			buf[0] = (cpu_to_le32(val) >> 8) & 0xff;
     45 			buf[1] = cpu_to_le32(val) & 0xff;
     46 		}
     47 		break;
     48 	case 1:
     49 		buf[0] = cpu_to_le32(val) & 0xff;
     50 		break;
     51 	default:
     52 		printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
     53 		return -EINVAL;
     54 	}
     55 
     56 	return i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num);
     57 }
     58 
     59 int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
     60 {
     61 	unsigned char buf[4] = { 0 };
     62 	u32 ret_val = 0;
     63 	int ret;
     64 
     65 	if (check_reg(p, reg))
     66 		return -EINVAL;
     67 
     68 	I2C_SET_BUS(p->bus);
     69 
     70 	ret = i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num);
     71 	if (ret)
     72 		return ret;
     73 
     74 	switch (pmic_i2c_tx_num) {
     75 	case 3:
     76 		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
     77 			ret_val = le32_to_cpu(buf[2] << 16
     78 					      | buf[1] << 8 | buf[0]);
     79 		else
     80 			ret_val = le32_to_cpu(buf[0] << 16 |
     81 					      buf[1] << 8 | buf[2]);
     82 		break;
     83 	case 2:
     84 		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
     85 			ret_val = le32_to_cpu(buf[1] << 8 | buf[0]);
     86 		else
     87 			ret_val = le32_to_cpu(buf[0] << 8 | buf[1]);
     88 		break;
     89 	case 1:
     90 		ret_val = le32_to_cpu(buf[0]);
     91 		break;
     92 	default:
     93 		printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
     94 		return -EINVAL;
     95 	}
     96 	memcpy(val, &ret_val, sizeof(ret_val));
     97 
     98 	return 0;
     99 }
    100 
    101 int pmic_probe(struct pmic *p)
    102 {
    103 	i2c_set_bus_num(p->bus);
    104 	debug("Bus: %d PMIC:%s probed!\n", p->bus, p->name);
    105 	if (i2c_probe(pmic_i2c_addr)) {
    106 		printf("Can't find PMIC:%s\n", p->name);
    107 		return -ENODEV;
    108 	}
    109 
    110 	return 0;
    111 }
    112