Home | History | Annotate | Line # | Download | only in samsung
exynos_i2c.c revision 1.3
      1 /*	$NetBSD: exynos_i2c.c,v 1.3 2014/12/29 22:34:08 skrll Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2014 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Reinoud Zandijk.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  *
     31  */
     32 
     33 
     34 #include "opt_exynos.h"
     35 #include "opt_arm_debug.h"
     36 #include "exynos_iic.h"
     37 
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.3 2014/12/29 22:34:08 skrll Exp $");
     40 
     41 
     42 #include <sys/param.h>
     43 #include <sys/bus.h>
     44 #include <sys/device.h>
     45 #include <sys/intr.h>
     46 #include <sys/systm.h>
     47 #include <sys/kmem.h>
     48 
     49 #include <arm/samsung/exynos_reg.h>
     50 #include <arm/samsung/exynos_io.h>
     51 #include <arm/samsung/exynos_intr.h>
     52 
     53 #include <sys/gpio.h>
     54 #include <dev/gpio/gpiovar.h>
     55 
     56 #include <dev/i2c/i2cvar.h>
     57 #include <dev/i2c/i2c_bitbang.h>
     58 
     59 
     60 struct exynos_iic_dev_softc {
     61 	int			isc_bus;
     62 	bool			isc_isgpio;
     63 
     64 	bus_space_tag_t		isc_bst;
     65 	bus_space_handle_t	isc_bsh;
     66 
     67 	struct exynos_gpio_pinset  isc_pinset;
     68 	struct exynos_gpio_pindata isc_sda;
     69 	struct exynos_gpio_pindata isc_slc;
     70 	bool			isc_sda_is_output;
     71 
     72 	kmutex_t		isc_buslock;
     73 	struct i2c_controller 	isc_i2cbus;
     74 };
     75 
     76 
     77 #if NEXYNOS_IIC > 0
     78 static int	exynos_iic_acquire_bus(void *, int);
     79 static void	exynos_iic_release_bus(void *, int);
     80 
     81 static int	exynos_iic_send_start(void *, int);
     82 static int	exynos_iic_send_stop(void *, int);
     83 static int	exynos_iic_initiate_xfer(void *, i2c_addr_t, int);
     84 static int	exynos_iic_read_byte(void *, uint8_t *, int);
     85 static int	exynos_iic_write_byte(void *, uint8_t , int);
     86 
     87 static bool exynos_iic_attach_i2cbus(struct exynos_iic_dev_softc *,
     88 	struct i2c_controller *, struct exyo_locators const *);
     89 #endif
     90 
     91 
     92 struct i2c_controller *exynos_i2cbus[EXYNOS_MAX_IIC_BUSSES];
     93 static int exynos_iic_match(device_t, cfdata_t, void *);
     94 static void exynos_iic_attach(device_t, device_t, void *);
     95 
     96 struct exynos_iic_softc {
     97 	device_t		sc_dev;
     98 
     99 	struct exynos_iic_dev_softc sc_idevs[EXYNOS_MAX_IIC_BUSSES];
    100 	struct i2c_controller       sc_i2cbus[EXYNOS_MAX_IIC_BUSSES];
    101 } exynos_iic_sc;
    102 
    103 
    104 CFATTACH_DECL_NEW(exynos_iic, sizeof(struct exynos_iic_softc),
    105     exynos_iic_match, exynos_iic_attach, NULL, NULL);
    106 
    107 
    108 static int
    109 exynos_iic_match(device_t self, cfdata_t cf, void *aux)
    110 {
    111 #ifdef DIAGNOSTIC
    112 	struct exyo_attach_args *exyoaa = aux;
    113 	struct exyo_locators *loc = &exyoaa->exyo_loc;
    114 #endif
    115 	int i;
    116 
    117 	/* no locators expected */
    118 	KASSERT(loc->loc_offset == 0);
    119 	KASSERT(loc->loc_size   == 0);
    120 	KASSERT(loc->loc_port   == EXYOCF_PORT_DEFAULT);
    121 
    122 	if (exynos_iic_sc.sc_dev != NULL)
    123 		return 0;
    124 	for (i = 0; i < EXYNOS_MAX_IIC_BUSSES; i++)
    125 		exynos_i2cbus[i] = NULL;
    126 #if NEXYNOS_IIC > 0
    127 	return 1;
    128 #else
    129 	return 0;
    130 #endif
    131 }
    132 
    133 
    134 static void
    135 exynos_iic_attach(device_t parent, device_t self, void *aux)
    136 {
    137 #if NEXYNOS_IIC > 0
    138 	prop_dictionary_t dict = device_properties(self);
    139         struct exynos_iic_softc * const sc =  device_private(self);
    140 	struct exyo_attach_args * const exyoaa = aux;
    141         struct exynos_iic_dev_softc *ei2c_sc;
    142 	struct i2c_controller *i2c_cntr;
    143 	struct i2cbus_attach_args iba;
    144 	struct exyo_locinfo const *locs;
    145 	struct exyo_locators const *loc;
    146 	bool enable;
    147 	char scrap[strlen("iic??_enable")];
    148 	int i;
    149 
    150 	locs = NULL;
    151 #ifdef EXYNOS4
    152 	if (IS_EXYNOS4_P())
    153 		locs = &exynos4_i2c_locinfo;
    154 #endif
    155 #ifdef EXYNOS5
    156 	if (IS_EXYNOS5_P())
    157 		locs = &exynos5_i2c_locinfo;
    158 #endif
    159 	KASSERT(locs);
    160 
    161 	sc->sc_dev  = self;
    162 	if (locs->nlocators == 0) {
    163 		aprint_error(": no i2c busses defined\n");
    164 		return;
    165 	}
    166 
    167 	aprint_normal("\n");
    168 
    169 	for (i = 0; i < locs->nlocators; i++) {
    170 		/* get subdriver type : either gpio or hw */
    171 		snprintf(scrap, sizeof(scrap), "iic%d_enable", i);
    172 		if (prop_dictionary_get_bool(dict, scrap, &enable)) {
    173 			if (!enable)
    174 				continue;
    175 			/* found an iic device */
    176 			ei2c_sc   = &sc->sc_idevs[i];
    177 			i2c_cntr = &sc->sc_i2cbus[i];
    178 			loc = &locs->locators[i];
    179 
    180 			ei2c_sc->isc_bus = i;
    181 			ei2c_sc->isc_isgpio = (loc->loc_flags > 0);
    182 			mutex_init(&ei2c_sc->isc_buslock, MUTEX_DEFAULT, IPL_NONE);
    183 
    184 			ei2c_sc->isc_bst  = exyoaa->exyo_core_bst;
    185 			if (bus_space_subregion(ei2c_sc->isc_bst,
    186 			    exyoaa->exyo_core_bsh,
    187 			    loc->loc_offset, loc->loc_size,
    188 			    &ei2c_sc->isc_bsh)) {
    189 				aprint_error_dev(self,
    190 				    ": failed to map registers for i2cbus%d\n",
    191 				    i);
    192 				continue;
    193 			}
    194 
    195 			if (!exynos_iic_attach_i2cbus(ei2c_sc, i2c_cntr, loc))
    196 				continue;
    197 
    198 			exynos_i2cbus[i] = i2c_cntr;
    199 			iba.iba_tag = i2c_cntr;
    200  			(void) config_found_ia(sc->sc_dev, "i2cbus", &iba,
    201 					iicbus_print);
    202 		}
    203 	}
    204 #endif
    205 }
    206 
    207 
    208 #if NEXYNOS_IIC > 0
    209 static bool
    210 exynos_iic_attach_i2cbus(struct exynos_iic_dev_softc *ei2c_sc,
    211 	struct i2c_controller *i2c_cntr, struct exyo_locators const *loc)
    212 {
    213 	struct exynos_gpio_pinset *pinset;
    214 
    215 	/* reserve our pins */
    216 	pinset = &ei2c_sc->isc_pinset;
    217 	strcpy(pinset->pinset_group, loc->loc_gpio_bus);
    218 	pinset->pinset_mask = __BIT(loc->loc_sda) | __BIT(loc->loc_slc);
    219 	pinset->pinset_func = loc->loc_func;
    220 
    221 	i2c_cntr->ic_cookie = ei2c_sc;
    222 	i2c_cntr->ic_acquire_bus = exynos_iic_acquire_bus;
    223 	i2c_cntr->ic_release_bus = exynos_iic_release_bus;
    224 	i2c_cntr->ic_send_start  = exynos_iic_send_start;
    225 	i2c_cntr->ic_send_stop   = exynos_iic_send_stop;
    226 	i2c_cntr->ic_initiate_xfer = exynos_iic_initiate_xfer;
    227 	i2c_cntr->ic_read_byte   = exynos_iic_read_byte;
    228 	i2c_cntr->ic_write_byte  = exynos_iic_write_byte;
    229 
    230 	exynos_gpio_pinset_acquire(pinset);
    231 	if (ei2c_sc->isc_isgpio) {
    232 		/* get sda and slc pins */
    233 		exynos_gpio_pinset_to_pindata(pinset,
    234 			loc->loc_sda, &ei2c_sc->isc_sda);
    235 		exynos_gpio_pinset_to_pindata(pinset,
    236 			loc->loc_slc, &ei2c_sc->isc_slc);
    237 		ei2c_sc->isc_sda_is_output = false;
    238 		exynos_gpio_pindata_ctl(&ei2c_sc->isc_sda, GPIO_PIN_INPUT);
    239 		exynos_gpio_pindata_ctl(&ei2c_sc->isc_slc, GPIO_PIN_OUTPUT);
    240 		return 1;
    241 	} else {
    242 		/* TBD: attach hardware driver */
    243 		aprint_normal("i2cbus%d: would attach native i2c driver\n",
    244 		    ei2c_sc->isc_bus);
    245 		return 0;
    246 	}
    247 }
    248 
    249 
    250 #define EXYNOS_IIC_BB_SDA	__BIT(1)
    251 #define EXYNOS_IIC_BB_SCL	__BIT(2)
    252 #define EXYNOS_IIC_BB_SDA_OUT	__BIT(3)
    253 #define EXYNOS_IIC_BB_SDA_IN	0
    254 
    255 static void
    256 exynos_iic_bb_set_bits(void *cookie, uint32_t bits)
    257 {
    258 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    259 	int sda, slc;
    260 
    261 	sda = (bits & EXYNOS_IIC_BB_SDA) ? true : false;
    262 	slc = (bits & EXYNOS_IIC_BB_SCL) ? true : false;
    263 
    264 	if (i2c_sc->isc_sda_is_output)
    265 		exynos_gpio_pindata_write(&i2c_sc->isc_sda, sda);
    266 	exynos_gpio_pindata_write(&i2c_sc->isc_slc, slc);
    267 }
    268 
    269 static uint32_t
    270 exynos_iic_bb_read_bits(void *cookie)
    271 {
    272 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    273 	int sda, slc;
    274 
    275 	sda = 0;
    276 	if (!i2c_sc->isc_sda_is_output)
    277 		sda = exynos_gpio_pindata_read(&i2c_sc->isc_sda);
    278 	slc = exynos_gpio_pindata_read(&i2c_sc->isc_slc);
    279 
    280 	return (sda ? EXYNOS_IIC_BB_SDA : 0) | (slc ? EXYNOS_IIC_BB_SCL : 0);
    281 }
    282 
    283 
    284 static void
    285 exynos_iic_bb_set_dir(void *cookie, uint32_t bits)
    286 {
    287 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    288 	int flags;
    289 
    290 	flags = GPIO_PIN_INPUT | GPIO_PIN_TRISTATE;
    291 	i2c_sc->isc_sda_is_output = ((bits & EXYNOS_IIC_BB_SDA_OUT) != 0);
    292 	if (i2c_sc->isc_sda_is_output)
    293 		flags = GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE;
    294 
    295 	exynos_gpio_pindata_ctl(&i2c_sc->isc_sda, flags);
    296 }
    297 
    298 
    299 static const struct i2c_bitbang_ops exynos_iic_bbops = {
    300 	exynos_iic_bb_set_bits,
    301 	exynos_iic_bb_set_dir,
    302 	exynos_iic_bb_read_bits,
    303 	{
    304 		EXYNOS_IIC_BB_SDA,
    305 		EXYNOS_IIC_BB_SCL,
    306 		EXYNOS_IIC_BB_SDA_OUT,
    307 		EXYNOS_IIC_BB_SDA_IN,
    308 	}
    309 };
    310 
    311 
    312 static int
    313 exynos_iic_acquire_bus(void *cookie, int flags)
    314 {
    315 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    316 
    317 	/* XXX what to do in polling case? could another cpu help */
    318 	if (flags & I2C_F_POLL)
    319 		return 0;
    320 	mutex_enter(&i2c_sc->isc_buslock);
    321 	return 0;
    322 }
    323 
    324 static void
    325 exynos_iic_release_bus(void *cookie, int flags)
    326 {
    327 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    328 
    329 	/* XXX what to do in polling case? could another cpu help */
    330 	if (flags & I2C_F_POLL)
    331 		return;
    332 	mutex_exit(&i2c_sc->isc_buslock);
    333 }
    334 
    335 static int
    336 exynos_iic_send_start(void *cookie, int flags)
    337 {
    338 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    339 
    340 	if (i2c_sc->isc_isgpio)
    341 		return i2c_bitbang_send_start(cookie, flags, &exynos_iic_bbops);
    342 	panic("%s: not implemented for non gpio case\n", __func__);
    343 	return EINVAL;
    344 }
    345 
    346 static int
    347 exynos_iic_send_stop(void *cookie, int flags)
    348 {
    349 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    350 
    351 	if (i2c_sc->isc_isgpio)
    352 		return i2c_bitbang_send_stop(cookie, flags, &exynos_iic_bbops);
    353 	panic("%s: not implemented for non gpio case\n", __func__);
    354 	return EINVAL;
    355 }
    356 
    357 static int
    358 exynos_iic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
    359 {
    360 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    361 
    362 	if (i2c_sc->isc_isgpio)
    363 		return i2c_bitbang_initiate_xfer(cookie, addr, flags,
    364 							&exynos_iic_bbops);
    365 	panic("%s: not implemented for non gpio case\n", __func__);
    366 	return EINVAL;
    367 }
    368 
    369 static int
    370 exynos_iic_read_byte(void *cookie, uint8_t *bytep, int flags)
    371 {
    372 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    373 
    374 	if (i2c_sc->isc_isgpio)
    375 		return i2c_bitbang_read_byte(cookie, bytep, flags,
    376 							&exynos_iic_bbops);
    377 	panic("%s: not implemented for non gpio case\n", __func__);
    378 	return EINVAL;
    379 }
    380 
    381 static int
    382 exynos_iic_write_byte(void *cookie, uint8_t byte, int flags)
    383 {
    384 	struct exynos_iic_dev_softc *i2c_sc = cookie;
    385 
    386 	if (i2c_sc->isc_isgpio)
    387 		return i2c_bitbang_write_byte(cookie, byte, flags,
    388 							&exynos_iic_bbops);
    389 	panic("%s: not implemented for non gpio case\n", __func__);
    390 	return EINVAL;
    391 }
    392 
    393 #endif /* NEXYNOS_IIC > 0 */
    394 
    395