Deleted Added
full compact
chrome_ec.c (263981) chrome_ec.c (266785)
1/*-
2 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * SUCH DAMAGE.
25 */
26
27/*
28 * Samsung Chromebook Embedded Controller
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * SUCH DAMAGE.
25 */
26
27/*
28 * Samsung Chromebook Embedded Controller
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/arm/samsung/exynos/chrome_ec.c 263981 2014-04-01 04:40:08Z br $");
32__FBSDID("$FreeBSD: head/sys/arm/samsung/exynos/chrome_ec.c 266785 2014-05-28 06:11:12Z br $");
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/bus.h>
37#include <sys/kernel.h>
38#include <sys/module.h>
39#include <sys/malloc.h>
40#include <sys/rman.h>

--- 14 unchanged lines hidden (view full) ---

55
56#include <dev/iicbus/iiconf.h>
57
58#include "iicbus_if.h"
59#include "gpio_if.h"
60
61#include <arm/samsung/exynos/chrome_ec.h>
62
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/bus.h>
37#include <sys/kernel.h>
38#include <sys/module.h>
39#include <sys/malloc.h>
40#include <sys/rman.h>

--- 14 unchanged lines hidden (view full) ---

55
56#include <dev/iicbus/iiconf.h>
57
58#include "iicbus_if.h"
59#include "gpio_if.h"
60
61#include <arm/samsung/exynos/chrome_ec.h>
62
63/* TODO: export to DTS */
64#define OUR_GPIO 177
65#define EC_GPIO 168
66
67struct ec_softc {
68 device_t dev;
63struct ec_softc {
64 device_t dev;
65 int have_arbitrator;
66 pcell_t our_gpio;
67 pcell_t ec_gpio;
69};
70
71struct ec_softc *ec_sc;
72
73/*
74 * bus_claim, bus_release
75 * both functions used for bus arbitration
76 * in multi-master mode
77 */
78
79static int
80bus_claim(struct ec_softc *sc)
81{
82 device_t gpio_dev;
83 int status;
84
68};
69
70struct ec_softc *ec_sc;
71
72/*
73 * bus_claim, bus_release
74 * both functions used for bus arbitration
75 * in multi-master mode
76 */
77
78static int
79bus_claim(struct ec_softc *sc)
80{
81 device_t gpio_dev;
82 int status;
83
84 if (sc->our_gpio == 0 || sc->ec_gpio == 0) {
85 device_printf(sc->dev, "i2c arbitrator is not configured\n");
86 return (1);
87 }
88
85 gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
89 gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
86 if (gpio_dev == NULL) {
90 if (gpio_dev == NULL) {
87 device_printf(sc->dev, "cant find gpio_dev\n");
88 return (1);
89 }
90
91 /* Say we want the bus */
91 device_printf(sc->dev, "cant find gpio_dev\n");
92 return (1);
93 }
94
95 /* Say we want the bus */
92 GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_LOW);
96 GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_LOW);
93
97
98 /* TODO(imax): insert a delay to allow EC to react. */
99
94 /* Check EC decision */
100 /* Check EC decision */
95 GPIO_PIN_GET(gpio_dev, EC_GPIO, &status);
101 GPIO_PIN_GET(gpio_dev, sc->ec_gpio, &status);
96
97 if (status == 1) {
98 /* Okay. We have bus */
99 return (0);
100 }
101
102 /* EC is master */
103 return (-1);
104}
105
106static int
107bus_release(struct ec_softc *sc)
108{
109 device_t gpio_dev;
110
102
103 if (status == 1) {
104 /* Okay. We have bus */
105 return (0);
106 }
107
108 /* EC is master */
109 return (-1);
110}
111
112static int
113bus_release(struct ec_softc *sc)
114{
115 device_t gpio_dev;
116
117 if (sc->our_gpio == 0 || sc->ec_gpio == 0) {
118 device_printf(sc->dev, "i2c arbitrator is not configured\n");
119 return (1);
120 }
121
111 gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
122 gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
112 if (gpio_dev == NULL) {
123 if (gpio_dev == NULL) {
113 device_printf(sc->dev, "cant find gpio_dev\n");
114 return (1);
115 }
116
124 device_printf(sc->dev, "cant find gpio_dev\n");
125 return (1);
126 }
127
117 GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_HIGH);
128 GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_HIGH);
118
119 return (0);
120}
121
122static int
123ec_probe(device_t dev)
124{
125

--- 78 unchanged lines hidden (view full) ---

204 data_in[3] = 0x10;
205
206 ec_command(EC_CMD_MKBP_STATE, data_in, 4,
207 data_out, 4);
208
209 return (0);
210}
211
129
130 return (0);
131}
132
133static int
134ec_probe(device_t dev)
135{
136

--- 78 unchanged lines hidden (view full) ---

215 data_in[3] = 0x10;
216
217 ec_command(EC_CMD_MKBP_STATE, data_in, 4,
218 data_out, 4);
219
220 return (0);
221}
222
223static void
224configure_i2c_arbitrator(struct ec_softc *sc)
225{
226 phandle_t arbitrator;
227
228 /* TODO(imax): look for compatible entry instead of hard-coded path */
229 arbitrator = OF_finddevice("/i2c-arbitrator");
230 if (arbitrator > 0 &&
231 OF_hasprop(arbitrator, "freebsd,our-gpio") &&
232 OF_hasprop(arbitrator, "freebsd,ec-gpio")) {
233 sc->have_arbitrator = 1;
234 OF_getencprop(arbitrator, "freebsd,our-gpio",
235 &sc->our_gpio, sizeof(sc->our_gpio));
236 OF_getencprop(arbitrator, "freebsd,ec-gpio",
237 &sc->ec_gpio, sizeof(sc->ec_gpio));
238 } else {
239 sc->have_arbitrator = 0;
240 sc->our_gpio = 0;
241 sc->ec_gpio = 0;
242 }
243}
244
212static int
213ec_attach(device_t dev)
214{
215 struct ec_softc *sc;
216
217 sc = device_get_softc(dev);
218 sc->dev = dev;
219
220 ec_sc = sc;
221
245static int
246ec_attach(device_t dev)
247{
248 struct ec_softc *sc;
249
250 sc = device_get_softc(dev);
251 sc->dev = dev;
252
253 ec_sc = sc;
254
255 configure_i2c_arbitrator(sc);
256
222 /*
223 * Claim the bus.
224 *
225 * We don't know cases when EC is master,
226 * so hold the bus forever for us.
227 *
228 */
229
257 /*
258 * Claim the bus.
259 *
260 * We don't know cases when EC is master,
261 * so hold the bus forever for us.
262 *
263 */
264
230 if (bus_claim(sc) != 0) {
265 if (sc->have_arbitrator && bus_claim(sc) != 0) {
231 return (ENXIO);
232 }
233
234 return (0);
235}
236
237static int
238ec_detach(device_t dev)
239{
240 struct ec_softc *sc;
241
242 sc = device_get_softc(dev);
243
266 return (ENXIO);
267 }
268
269 return (0);
270}
271
272static int
273ec_detach(device_t dev)
274{
275 struct ec_softc *sc;
276
277 sc = device_get_softc(dev);
278
244 bus_release(sc);
279 if (sc->have_arbitrator) {
280 bus_release(sc);
281 }
245
246 return (0);
247}
248
249static device_method_t ec_methods[] = {
250 DEVMETHOD(device_probe, ec_probe),
251 DEVMETHOD(device_attach, ec_attach),
252 DEVMETHOD(device_detach, ec_detach),

--- 14 unchanged lines hidden ---
282
283 return (0);
284}
285
286static device_method_t ec_methods[] = {
287 DEVMETHOD(device_probe, ec_probe),
288 DEVMETHOD(device_attach, ec_attach),
289 DEVMETHOD(device_detach, ec_detach),

--- 14 unchanged lines hidden ---