Tom Rini | 10e4779 | 2018-05-06 17:58:06 -0400 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (C) 2011 Samsung Electronics |
| 4 | * Lukasz Majewski <l.majewski@samsung.com> |
| 5 | * |
| 6 | * (C) Copyright 2010 |
| 7 | * Stefano Babic, DENX Software Engineering, sbabic@denx.de |
| 8 | * |
| 9 | * (C) Copyright 2008-2009 Freescale Semiconductor, Inc. |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 12 | #include <linux/types.h> |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 13 | #include <power/pmic.h> |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 14 | #include <spi.h> |
| 15 | |
| 16 | static struct spi_slave *slave; |
| 17 | |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 18 | static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write) |
| 19 | { |
| 20 | u32 pmic_tx, pmic_rx; |
| 21 | u32 tmp; |
| 22 | |
| 23 | if (!slave) { |
Tom Rini | 9ea1854 | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 24 | slave = spi_setup_slave(p->bus, p->hw.spi.cs, p->hw.spi.clk, |
| 25 | p->hw.spi.mode); |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 26 | |
| 27 | if (!slave) |
Jaehoon Chung | 10e80f3 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 28 | return -ENODEV; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 29 | } |
| 30 | |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 31 | if (check_reg(p, reg)) |
Jaehoon Chung | 10e80f3 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 32 | return -EINVAL; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 33 | |
| 34 | if (spi_claim_bus(slave)) |
Jaehoon Chung | 10e80f3 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 35 | return -EBUSY; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 36 | |
| 37 | pmic_tx = p->hw.spi.prepare_tx(reg, val, write); |
| 38 | |
| 39 | tmp = cpu_to_be32(pmic_tx); |
| 40 | |
| 41 | if (spi_xfer(slave, pmic_spi_bitlen, &tmp, &pmic_rx, |
Tom Rini | 9ea1854 | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 42 | pmic_spi_flags)) |
| 43 | goto err; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 44 | |
| 45 | if (write) { |
Helmut Raiger | b6e1841 | 2011-10-19 20:34:43 +0000 | [diff] [blame] | 46 | pmic_tx = p->hw.spi.prepare_tx(reg, val, 0); |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 47 | tmp = cpu_to_be32(pmic_tx); |
| 48 | if (spi_xfer(slave, pmic_spi_bitlen, &tmp, &pmic_rx, |
Tom Rini | 9ea1854 | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 49 | pmic_spi_flags)) |
| 50 | goto err; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | spi_release_bus(slave); |
| 54 | *val = cpu_to_be32(pmic_rx); |
| 55 | |
| 56 | return 0; |
Tom Rini | 9ea1854 | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 57 | |
| 58 | err: |
| 59 | spi_release_bus(slave); |
Jaehoon Chung | 10e80f3 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 60 | return -ENOTSUPP; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 61 | } |
| 62 | |
| 63 | int pmic_reg_write(struct pmic *p, u32 reg, u32 val) |
| 64 | { |
Jaehoon Chung | 10e80f3 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 65 | return pmic_reg(p, reg, &val, 1); |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) |
| 69 | { |
Jaehoon Chung | 10e80f3 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 70 | return pmic_reg(p, reg, val, 0); |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 71 | } |