1*2b27bdccSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b63128e8STony Lindgren /*
3b63128e8STony Lindgren * Helper module for board specific I2C bus registration
4b63128e8STony Lindgren *
5b63128e8STony Lindgren * Copyright (C) 2009 Nokia Corporation.
6b63128e8STony Lindgren */
7b63128e8STony Lindgren
8e4c060dbSTony Lindgren #include "soc.h"
92a296c8fSTony Lindgren #include "omap_hwmod.h"
1025c7d49eSTony Lindgren #include "omap_device.h"
11b63128e8STony Lindgren
12b13159afSPaul Walmsley #include "prm.h"
13b13159afSPaul Walmsley #include "common.h"
143a8761c0STony Lindgren #include "i2c.h"
15b63128e8STony Lindgren
166d3c55fdSAvinash.H.M /* In register I2C_CON, Bit 15 is the I2C enable bit */
176d3c55fdSAvinash.H.M #define I2C_EN BIT(15)
186d3c55fdSAvinash.H.M #define OMAP2_I2C_CON_OFFSET 0x24
196d3c55fdSAvinash.H.M #define OMAP4_I2C_CON_OFFSET 0xA4
206d3c55fdSAvinash.H.M
213a8761c0STony Lindgren #define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
223a8761c0STony Lindgren
236d3c55fdSAvinash.H.M /**
246d3c55fdSAvinash.H.M * omap_i2c_reset - reset the omap i2c module.
256d3c55fdSAvinash.H.M * @oh: struct omap_hwmod *
266d3c55fdSAvinash.H.M *
276d3c55fdSAvinash.H.M * The i2c moudle in omap2, omap3 had a special sequence to reset. The
286d3c55fdSAvinash.H.M * sequence is:
296d3c55fdSAvinash.H.M * - Disable the I2C.
306d3c55fdSAvinash.H.M * - Write to SOFTRESET bit.
316d3c55fdSAvinash.H.M * - Enable the I2C.
326d3c55fdSAvinash.H.M * - Poll on the RESETDONE bit.
336d3c55fdSAvinash.H.M * The sequence is implemented in below function. This is called for 2420,
346d3c55fdSAvinash.H.M * 2430 and omap3.
356d3c55fdSAvinash.H.M */
omap_i2c_reset(struct omap_hwmod * oh)366d3c55fdSAvinash.H.M int omap_i2c_reset(struct omap_hwmod *oh)
376d3c55fdSAvinash.H.M {
386d3c55fdSAvinash.H.M u32 v;
396d3c55fdSAvinash.H.M u16 i2c_con;
406d3c55fdSAvinash.H.M int c = 0;
416d3c55fdSAvinash.H.M
4270451127STony Lindgren if (soc_is_omap24xx() || soc_is_omap34xx() || soc_is_am35xx())
436d3c55fdSAvinash.H.M i2c_con = OMAP2_I2C_CON_OFFSET;
4470451127STony Lindgren else
4570451127STony Lindgren i2c_con = OMAP4_I2C_CON_OFFSET;
466d3c55fdSAvinash.H.M
476d3c55fdSAvinash.H.M /* Disable I2C */
486d3c55fdSAvinash.H.M v = omap_hwmod_read(oh, i2c_con);
496d3c55fdSAvinash.H.M v &= ~I2C_EN;
506d3c55fdSAvinash.H.M omap_hwmod_write(v, oh, i2c_con);
516d3c55fdSAvinash.H.M
526d3c55fdSAvinash.H.M /* Write to the SOFTRESET bit */
536d3c55fdSAvinash.H.M omap_hwmod_softreset(oh);
546d3c55fdSAvinash.H.M
556d3c55fdSAvinash.H.M /* Enable I2C */
566d3c55fdSAvinash.H.M v = omap_hwmod_read(oh, i2c_con);
576d3c55fdSAvinash.H.M v |= I2C_EN;
586d3c55fdSAvinash.H.M omap_hwmod_write(v, oh, i2c_con);
596d3c55fdSAvinash.H.M
606d3c55fdSAvinash.H.M /* Poll on RESETDONE bit */
616d3c55fdSAvinash.H.M omap_test_timeout((omap_hwmod_read(oh,
626d3c55fdSAvinash.H.M oh->class->sysc->syss_offs)
636d3c55fdSAvinash.H.M & SYSS_RESETDONE_MASK),
646d3c55fdSAvinash.H.M MAX_MODULE_SOFTRESET_WAIT, c);
656d3c55fdSAvinash.H.M
666d3c55fdSAvinash.H.M if (c == MAX_MODULE_SOFTRESET_WAIT)
673d0cb73eSJoe Perches pr_warn("%s: %s: softreset failed (waited %d usec)\n",
686d3c55fdSAvinash.H.M __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT);
696d3c55fdSAvinash.H.M else
706d3c55fdSAvinash.H.M pr_debug("%s: %s: softreset in %d usec\n", __func__,
716d3c55fdSAvinash.H.M oh->name, c);
726d3c55fdSAvinash.H.M
736d3c55fdSAvinash.H.M return 0;
746d3c55fdSAvinash.H.M }
75