From a9d2ae7014d9e66dde6dd4a344308449508e4a22 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Wed, 26 Dec 2012 20:03:12 +0000 Subject: I2C: Driver changes for FDT support Functions added to get the I2C bus number and reset I2C bus using FDT node. Signed-off-by: Rajeshwari Shinde Acked-by: Simon Glass Acked-by: Heiko Schocher Signed-off-by: Minkyu Kang --- drivers/i2c/s3c24x0_i2c.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/i2c/s3c24x0_i2c.h | 8 +++++ 2 files changed, 90 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 90d297a..7ec01ec 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */ #include +#include #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include #include +#include #else #include #endif @@ -60,7 +62,14 @@ #define I2C_TIMEOUT 1 /* 1 second */ -static unsigned int g_current_bus; /* Stores Current I2C Bus */ +/* + * For SPL boot some boards need i2c before SDRAM is initialised so force + * variables to live in SRAM + */ +static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] + __attribute__((section(".data"))); +static int i2c_busses __attribute__((section(".data"))); #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -512,4 +521,76 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) (i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, len) != 0); } + +#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{ + int node_list[CONFIG_MAX_I2C_NUM]; + int count, i; + + count = fdtdec_find_aliases_for_id(blob, "i2c", + COMPAT_SAMSUNG_S3C2440_I2C, node_list, + CONFIG_MAX_I2C_NUM); + + for (i = 0; i < count; i++) { + struct s3c24x0_i2c_bus *bus; + int node = node_list[i]; + + if (node <= 0) + continue; + bus = &i2c_bus[i]; + bus->regs = (struct s3c24x0_i2c *) + fdtdec_get_addr(blob, node, "reg"); + bus->id = pinmux_decode_periph_id(blob, node); + bus->node = node; + bus->bus_num = i2c_busses++; + exynos_pinmux_config(bus->id, 0); + } +} + +static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{ + if (bus_idx < i2c_busses) + return &i2c_bus[bus_idx]; + + debug("Undefined bus: %d\n", bus_idx); + return NULL; +} + +int i2c_get_bus_num_fdt(int node) +{ + int i; + + for (i = 0; i < i2c_busses; i++) { + if (node == i2c_bus[i].node) + return i; + } + + debug("%s: Can't find any matched I2C bus\n", __func__); + return -1; +} + +int i2c_reset_port_fdt(const void *blob, int node) +{ + struct s3c24x0_i2c_bus *i2c; + int bus; + + bus = i2c_get_bus_num_fdt(node); + if (bus < 0) { + debug("could not get bus for node %d\n", node); + return -1; + } + + i2c = get_bus(bus); + if (!i2c) { + debug("get_bus() failed for node node %d\n", node); + return -1; + } + + i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + return 0; +} +#endif + #endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06..1243bf1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c { u32 iicds; u32 iiclc; }; + +struct s3c24x0_i2c_bus { + int node; /* device tree node */ + int bus_num; /* i2c bus number */ + struct s3c24x0_i2c *regs; + enum periph_id id; +}; + #endif /* _S3C24X0_I2C_H */ -- cgit v1.1 From f482310c6def17ba975a041077f89d984be54b68 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Wed, 26 Dec 2012 20:03:17 +0000 Subject: Sound: Add FDT support to driver This patch adds FDT support to the sound driver. Signed-off-by: Rajeshwari Shinde Acked-by: Simon Glass Signed-off-by: Minkyu Kang --- drivers/sound/sound.c | 171 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c index 4c74534..fa8432d 100644 --- a/drivers/sound/sound.c +++ b/drivers/sound/sound.c @@ -24,111 +24,159 @@ #include #include #include +#include +#include #include #include #include -#include "wm8994.h" #include +#include "wm8994.h" /* defines */ #define SOUND_400_HZ 400 #define SOUND_BITS_IN_BYTE 8 static struct i2stx_info g_i2stx_pri; -static struct sound_codec_info g_codec_info; /* - * get_sound_fdt_values gets fdt values for i2s parameters + * get_sound_i2s_values gets values for i2s parameters * * @param i2stx_info i2s transmitter transfer param structure - * @param blob FDT blob - */ -static void get_sound_i2s_values(struct i2stx_info *i2s) -{ - i2s->base_address = samsung_get_base_i2s(); - i2s->audio_pll_clk = I2S_PLL_CLK; - i2s->samplingrate = I2S_SAMPLING_RATE; - i2s->bitspersample = I2S_BITS_PER_SAMPLE; - i2s->channels = I2S_CHANNELS; - i2s->rfs = I2S_RFS; - i2s->bfs = I2S_BFS; -} - -/* - * Gets fdt values for wm8994 config parameters - * - * @param pcodec_info codec information structure - * @param blob FDT blob - * @return int value, 0 for success + * @param blob FDT blob if enabled else NULL */ -static int get_sound_wm8994_values(struct sound_codec_info *pcodec_info) +static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob) { +#ifdef CONFIG_OF_CONTROL + int node; int error = 0; + int base; - switch (AUDIO_COMPAT) { - case AUDIO_COMPAT_SPI: - debug("%s: Support not added for SPI interface\n", __func__); + node = fdtdec_next_compatible(blob, 0, + COMPAT_SAMSUNG_EXYNOS5_SOUND); + if (node <= 0) { + debug("EXYNOS_SOUND: No node for sound in device tree\n"); return -1; - break; - case AUDIO_COMPAT_I2C: - pcodec_info->i2c_bus = AUDIO_I2C_BUS; - pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; - debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); - break; - default: - debug("%s: Unknown compat id %d\n", __func__, AUDIO_COMPAT); + } + + /* + * Get the pre-defined sound specific values from FDT. + * All of these are expected to be correct otherwise + * wrong register values in i2s setup parameters + * may result in no sound play. + */ + base = fdtdec_get_addr(blob, node, "reg"); + if (base == FDT_ADDR_T_NONE) { + debug("%s: Missing i2s base\n", __func__); return -1; } + i2s->base_address = base; + i2s->audio_pll_clk = fdtdec_get_int(blob, + node, "samsung,i2s-epll-clock-frequency", -1); + error |= i2s->audio_pll_clk; + debug("audio_pll_clk = %d\n", i2s->audio_pll_clk); + i2s->samplingrate = fdtdec_get_int(blob, + node, "samsung,i2s-sampling-rate", -1); + error |= i2s->samplingrate; + debug("samplingrate = %d\n", i2s->samplingrate); + i2s->bitspersample = fdtdec_get_int(blob, + node, "samsung,i2s-bits-per-sample", -1); + error |= i2s->bitspersample; + debug("bitspersample = %d\n", i2s->bitspersample); + i2s->channels = fdtdec_get_int(blob, + node, "samsung,i2s-channels", -1); + error |= i2s->channels; + debug("channels = %d\n", i2s->channels); + i2s->rfs = fdtdec_get_int(blob, + node, "samsung,i2s-lr-clk-framesize", -1); + error |= i2s->rfs; + debug("rfs = %d\n", i2s->rfs); + i2s->bfs = fdtdec_get_int(blob, + node, "samsung,i2s-bit-clk-framesize", -1); + error |= i2s->bfs; + debug("bfs = %d\n", i2s->bfs); if (error == -1) { - debug("fail to get wm8994 codec node properties\n"); + debug("fail to get sound i2s node properties\n"); return -1; } - +#else + i2s->base_address = samsung_get_base_i2s(); + i2s->audio_pll_clk = I2S_PLL_CLK; + i2s->samplingrate = I2S_SAMPLING_RATE; + i2s->bitspersample = I2S_BITS_PER_SAMPLE; + i2s->channels = I2S_CHANNELS; + i2s->rfs = I2S_RFS; + i2s->bfs = I2S_BFS; +#endif return 0; } /* - * Gets fdt values for codec config parameters + * Init codec * - * @param pcodec_info codec information structure - * @param blob FDT blob - * @return int value, 0 for success + * @param blob FDT blob + * @param pi2s_tx i2s parameters required by codec + * @return int value, 0 for success */ -static int get_sound_codec_values(struct sound_codec_info *pcodec_info) +static int codec_init(const void *blob, struct i2stx_info *pi2s_tx) { - int error = 0; + int ret; const char *codectype; +#ifdef CONFIG_OF_CONTROL + int node; - codectype = AUDIO_CODEC; + /* Get the node from FDT for sound */ + node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SOUND); + if (node <= 0) { + debug("EXYNOS_SOUND: No node for sound in device tree\n"); + debug("node = %d\n", node); + return -1; + } + /* + * Get the pre-defined sound codec specific values from FDT. + * All of these are expected to be correct otherwise sound + * can not be played + */ + codectype = fdt_getprop(blob, node, "samsung,codec-type", NULL); + debug("device = %s\n", codectype); +#else + codectype = AUDIO_CODEC; +#endif if (!strcmp(codectype, "wm8994")) { - pcodec_info->codec_type = CODEC_WM_8994; - error = get_sound_wm8994_values(pcodec_info); + /* Check the codec type and initialise the same */ + ret = wm8994_init(blob, WM8994_AIF2, + pi2s_tx->samplingrate, + (pi2s_tx->samplingrate * (pi2s_tx->rfs)), + pi2s_tx->bitspersample, pi2s_tx->channels); } else { - error = -1; + debug("%s: Unknown code type %s\n", __func__, + codectype); + return -1; } - - if (error == -1) { - debug("fail to get sound codec node properties\n"); + if (ret) { + debug("%s: Codec init failed\n", __func__); return -1; } return 0; } -int sound_init(void) +int sound_init(const void *blob) { int ret; struct i2stx_info *pi2s_tx = &g_i2stx_pri; - struct sound_codec_info *pcodec_info = &g_codec_info; /* Get the I2S Values */ - get_sound_i2s_values(pi2s_tx); + if (get_sound_i2s_values(pi2s_tx, blob) < 0) { + debug(" FDT I2S values failed\n"); + return -1; + } - /* Get the codec Values */ - if (get_sound_codec_values(pcodec_info) < 0) + if (codec_init(blob, pi2s_tx) < 0) { + debug(" Codec init failed\n"); return -1; + } ret = i2s_tx_init(pi2s_tx); if (ret) { @@ -137,21 +185,6 @@ int sound_init(void) return ret; } - /* Check the codec type and initialise the same */ - if (pcodec_info->codec_type == CODEC_WM_8994) { - ret = wm8994_init(pcodec_info, WM8994_AIF2, - pi2s_tx->samplingrate, - (pi2s_tx->samplingrate * (pi2s_tx->rfs)), - pi2s_tx->bitspersample, pi2s_tx->channels); - } else { - debug("%s: Unknown code type %d\n", __func__, - pcodec_info->codec_type); - return -1; - } - if (ret) { - debug("%s: Codec init failed\n", __func__); - return -1; - } return ret; } -- cgit v1.1 From 6647c7ac8ed6ae8b5bda86df0671aea9ee3bc761 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Wed, 26 Dec 2012 20:03:18 +0000 Subject: Sound: WM8994: Add FDT support to codec This patch adds FDT support to the codec. Signed-off-by: Rajeshwari Shinde Acked-by: Simon Glass Signed-off-by: Minkyu Kang --- drivers/sound/wm8994.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-- drivers/sound/wm8994.h | 6 ++-- 2 files changed, 74 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c index 293903a..3b673b4 100644 --- a/drivers/sound/wm8994.c +++ b/drivers/sound/wm8994.c @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include "wm8994.h" #include "wm8994_registers.h" @@ -77,6 +79,7 @@ static int bclk_divs[] = { static struct wm8994_priv g_wm8994_info; static unsigned char g_wm8994_i2c_dev_addr; +static struct sound_codec_info g_codec_info; /* * Initialise I2C for wm 8994 @@ -747,13 +750,80 @@ err: return -1; } +/* + * Gets fdt values for wm8994 config parameters + * + * @param pcodec_info codec information structure + * @param blob FDT blob + * @return int value, 0 for success + */ +static int get_codec_values(struct sound_codec_info *pcodec_info, + const void *blob) +{ + int error = 0; +#ifdef CONFIG_OF_CONTROL + enum fdt_compat_id compat; + int node; + int parent; + + /* Get the node from FDT for codec */ + node = fdtdec_next_compatible(blob, 0, COMPAT_WOLFSON_WM8994_CODEC); + if (node <= 0) { + debug("EXYNOS_SOUND: No node for codec in device tree\n"); + debug("node = %d\n", node); + return -1; + } + + parent = fdt_parent_offset(blob, node); + if (parent < 0) { + debug("%s: Cannot find node parent\n", __func__); + return -1; + } + + compat = fdtdec_lookup(blob, parent); + switch (compat) { + case COMPAT_SAMSUNG_S3C2440_I2C: + pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent); + error |= pcodec_info->i2c_bus; + debug("i2c bus = %d\n", pcodec_info->i2c_bus); + pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node, + "reg", 0); + error |= pcodec_info->i2c_dev_addr; + debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); + break; + default: + debug("%s: Unknown compat id %d\n", __func__, compat); + return -1; + } +#else + pcodec_info->i2c_bus = AUDIO_I2C_BUS; + pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; + debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); +#endif + + pcodec_info->codec_type = CODEC_WM_8994; + + if (error == -1) { + debug("fail to get wm8994 codec node properties\n"); + return -1; + } + + return 0; +} + /*wm8994 Device Initialisation */ -int wm8994_init(struct sound_codec_info *pcodec_info, - enum en_audio_interface aif_id, +int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels) { int ret = 0; + struct sound_codec_info *pcodec_info = &g_codec_info; + + /* Get the codec Values */ + if (get_codec_values(pcodec_info, blob) < 0) { + debug("FDT Codec values failed\n"); + return -1; + } /* shift the device address by 1 for 7 bit addressing */ g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr; diff --git a/drivers/sound/wm8994.h b/drivers/sound/wm8994.h index a8f0de1..a1e8335 100644 --- a/drivers/sound/wm8994.h +++ b/drivers/sound/wm8994.h @@ -69,8 +69,7 @@ enum wm8994_type { /* * intialise wm8994 sound codec device for the given configuration * - * @param pcodec_info pointer value of the sound codec info structure - * parsed from device tree + * @param blob FDT node for codec values * @param aif_id enum value of codec interface port in which * soc i2s is connected * @param sampling_rate Sampling rate ranges between from 8khz to 96khz @@ -80,8 +79,7 @@ enum wm8994_type { * * @returns -1 for error and 0 Success. */ -int wm8994_init(struct sound_codec_info *pcodec_info, - enum en_audio_interface aif_id, +int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels); #endif /*__WM8994_H__ */ -- cgit v1.1 From 4d3acb9df35787e50cc6ea4be10d45352c99657c Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Wed, 26 Dec 2012 20:03:23 +0000 Subject: SPI: EXYNOS: Add FDT support to driver. This patch adds FDT support to the SPI driver. Signed-off-by: Simon Glass Signed-off-by: Rajeshwari Shinde Acked-by: Simon Glass Signed-off-by: Minkyu Kang --- drivers/spi/exynos_spi.c | 96 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 3e6c18f..be60ada 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -28,16 +29,20 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /* Information about each SPI controller */ struct spi_bus { enum periph_id periph_id; s32 frequency; /* Default clock frequency, -1 for none */ struct exynos_spi *regs; int inited; /* 1 if this bus is ready for use */ + int node; }; /* A list of spi buses that we know about */ static struct spi_bus spi_bus[EXYNOS5_SPI_NUM_CONTROLLERS]; +static unsigned int bus_count; struct exynos_spi_slave { struct spi_slave slave; @@ -50,7 +55,7 @@ struct exynos_spi_slave { static struct spi_bus *spi_get_bus(unsigned dev_index) { - if (dev_index < EXYNOS5_SPI_NUM_CONTROLLERS) + if (dev_index < bus_count) return &spi_bus[dev_index]; debug("%s: invalid bus %d", __func__, dev_index); @@ -347,21 +352,100 @@ static inline struct exynos_spi *get_spi_base(int dev_index) (dev_index - 3); } +/* + * Read the SPI config from the device tree node. + * + * @param blob FDT blob to read from + * @param node Node offset to read from + * @param bus SPI bus structure to fill with information + * @return 0 if ok, or -FDT_ERR_NOTFOUND if something was missing + */ +static int spi_get_config(const void *blob, int node, struct spi_bus *bus) +{ + bus->node = node; + bus->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg"); + bus->periph_id = pinmux_decode_periph_id(blob, node); + + if (bus->periph_id == PERIPH_ID_NONE) { + debug("%s: Invalid peripheral ID %d\n", __func__, + bus->periph_id); + return -FDT_ERR_NOTFOUND; + } + + /* Use 500KHz as a suitable default */ + bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", + 500000); + + return 0; +} + +/* + * Process a list of nodes, adding them to our list of SPI ports. + * + * @param blob fdt blob + * @param node_list list of nodes to process (any <=0 are ignored) + * @param count number of nodes to process + * @param is_dvc 1 if these are DVC ports, 0 if standard I2C + * @return 0 if ok, -1 on error + */ +static int process_nodes(const void *blob, int node_list[], int count) +{ + int i; + + /* build the i2c_controllers[] for each controller */ + for (i = 0; i < count; i++) { + int node = node_list[i]; + struct spi_bus *bus; + + if (node <= 0) + continue; + + bus = &spi_bus[i]; + if (spi_get_config(blob, node, bus)) { + printf("exynos spi_init: failed to decode bus %d\n", + i); + return -1; + } + + debug("spi: controller bus %d at %p, periph_id %d\n", + i, bus->regs, bus->periph_id); + bus->inited = 1; + bus_count++; + } + + return 0; +} + /* Sadly there is no error return from this function */ void spi_init(void) { - int i; + int count; + +#ifdef CONFIG_OF_CONTROL + int node_list[EXYNOS5_SPI_NUM_CONTROLLERS]; + const void *blob = gd->fdt_blob; + + count = fdtdec_find_aliases_for_id(blob, "spi", + COMPAT_SAMSUNG_EXYNOS_SPI, node_list, + EXYNOS5_SPI_NUM_CONTROLLERS); + if (process_nodes(blob, node_list, count)) + return; + +#else struct spi_bus *bus; - for (i = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) { - bus = &spi_bus[i]; - bus->regs = get_spi_base(i); - bus->periph_id = PERIPH_ID_SPI0 + i; + for (count = 0; count < EXYNOS5_SPI_NUM_CONTROLLERS; count++) { + bus = &spi_bus[count]; + bus->regs = get_spi_base(count); + bus->periph_id = PERIPH_ID_SPI0 + count; /* Although Exynos5 supports upto 50Mhz speed, * we are setting it to 10Mhz for safe side */ bus->frequency = 10000000; bus->inited = 1; + bus->node = 0; + bus_count = EXYNOS5_SPI_NUM_CONTROLLERS; } +#endif } -- cgit v1.1 From e18bf1f9f2d2afa688e30e3f73d52de6a5edf4c1 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Mon, 7 Jan 2013 23:35:03 +0000 Subject: EHCI: Exynos: Add fdt support Adding fdt support to ehci-exynos in order to parse register base addresses from the device node. Signed-off-by: Vivek Gautam Signed-off-by: Rajeshwari Shinde Signed-off-by: Minkyu Kang --- drivers/usb/host/ehci-exynos.c | 92 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 9f0ed06..3ca4c5c 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -21,13 +21,71 @@ */ #include +#include +#include +#include #include #include #include #include #include +#include +#include #include "ehci.h" +/* Declare global data pointer */ +DECLARE_GLOBAL_DATA_PTR; + +/** + * Contains pointers to register base addresses + * for the usb controller. + */ +struct exynos_ehci { + struct exynos_usb_phy *usb; + unsigned int *hcd; +}; + +static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos) +{ + unsigned int node; + int depth; + + node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_EHCI); + if (node <= 0) { + debug("EHCI: Can't get device node for ehci\n"); + return -ENODEV; + } + + /* + * Get the base address for EHCI controller from the device node + */ + exynos->hcd = (unsigned int *)fdtdec_get_addr(blob, node, "reg"); + if (exynos->hcd == NULL) { + debug("Can't get the EHCI register address\n"); + return -ENXIO; + } + + depth = 0; + node = fdtdec_next_compatible_subnode(blob, node, + COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth); + if (node <= 0) { + debug("EHCI: Can't get device node for usb-phy controller\n"); + return -ENODEV; + } + + /* + * Get the base address for usbphy from the device node + */ + exynos->usb = (struct exynos_usb_phy *)fdtdec_get_addr(blob, node, + "reg"); + if (exynos->usb == NULL) { + debug("Can't get the usbphy register address\n"); + return -ENXIO; + } + + return 0; +} + /* Setup the EHCI host controller. */ static void setup_usb_phy(struct exynos_usb_phy *usb) { @@ -86,12 +144,20 @@ static void reset_usb_phy(struct exynos_usb_phy *usb) */ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { - struct exynos_usb_phy *usb; + struct exynos_ehci *exynos = NULL; + + exynos = (struct exynos_ehci *) + kzalloc(sizeof(struct exynos_ehci), GFP_KERNEL); + if (!exynos) { + debug("failed to allocate exynos ehci context\n"); + return -ENOMEM; + } - usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy(); - setup_usb_phy(usb); + exynos_usb_parse_dt(gd->fdt_blob, exynos); - *hccr = (struct ehci_hccr *)samsung_get_base_usb_ehci(); + setup_usb_phy(exynos->usb); + + *hccr = (struct ehci_hccr *)(exynos->hcd); *hcor = (struct ehci_hcor *)((uint32_t) *hccr + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); @@ -99,6 +165,8 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) (uint32_t)*hccr, (uint32_t)*hcor, (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + kfree(exynos); + return 0; } @@ -108,10 +176,20 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) */ int ehci_hcd_stop(int index) { - struct exynos_usb_phy *usb; + struct exynos_ehci *exynos = NULL; + + exynos = (struct exynos_ehci *) + kzalloc(sizeof(struct exynos_ehci), GFP_KERNEL); + if (!exynos) { + debug("failed to allocate exynos ehci context\n"); + return -ENOMEM; + } + + exynos_usb_parse_dt(gd->fdt_blob, exynos); + + reset_usb_phy(exynos->usb); - usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy(); - reset_usb_phy(usb); + kfree(exynos); return 0; } -- cgit v1.1 From c6d647e3094b4123c9c6e27765221762753f00be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Majewski?= Date: Tue, 8 Jan 2013 03:48:40 +0000 Subject: video:cache:fix: Enable dcache flush at LCD subsystem for Exynos based boards lcd_set_flush_dcache(1) function is called from exynos_fb.c configuration file to enable lcd_sync function. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Minkyu Kang --- drivers/video/exynos_fb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index d9a3f9a..aac74a3 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -63,6 +63,9 @@ static void exynos_lcd_init_mem(void *lcdbase, vidinfo_t *vid) static void exynos_lcd_init(vidinfo_t *vid) { exynos_fimd_lcd_init(vid); + + /* Enable flushing after LCD writes if requested */ + lcd_set_flush_dcache(1); } static void draw_logo(void) -- cgit v1.1 From 4050f0700f1822e6cb0095128192c15be5e750ee Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Tue, 8 Jan 2013 21:03:40 +0000 Subject: PMIC: MAX77686: Add FDT Support This patch adds fdt support to MAX77686. Signed-off-by: Rajeshwari Shinde Signed-off-by: Minkyu Kang --- drivers/power/pmic/pmic_max77686.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pmic/pmic_max77686.c b/drivers/power/pmic/pmic_max77686.c index fce0183..7fcb4c0 100644 --- a/drivers/power/pmic/pmic_max77686.c +++ b/drivers/power/pmic/pmic_max77686.c @@ -22,10 +22,14 @@ */ #include +#include +#include #include #include #include +DECLARE_GLOBAL_DATA_PTR; + int pmic_init(unsigned char bus) { static const char name[] = "MAX77686_PMIC"; @@ -36,13 +40,40 @@ int pmic_init(unsigned char bus) return -ENOMEM; } - puts("Board PMIC init\n"); +#ifdef CONFIG_OF_CONTROL + const void *blob = gd->fdt_blob; + int node, parent; + + node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_MAX77686_PMIC); + if (node < 0) { + debug("PMIC: No node for PMIC Chip in device tree\n"); + debug("node = %d\n", node); + return -1; + } + + parent = fdt_parent_offset(blob, node); + if (parent < 0) { + debug("%s: Cannot find node parent\n", __func__); + return -1; + } + + p->bus = i2c_get_bus_num_fdt(parent); + if (p->bus < 0) { + debug("%s: Cannot find I2C bus\n", __func__); + return -1; + } + p->hw.i2c.addr = fdtdec_get_int(blob, node, "reg", 9); +#else + p->bus = bus; + p->hw.i2c.addr = MAX77686_I2C_ADDR; +#endif + p->name = name; p->interface = PMIC_I2C; p->number_of_regs = PMIC_NUM_OF_REGS; - p->hw.i2c.addr = MAX77686_I2C_ADDR; p->hw.i2c.tx_num = 1; - p->bus = bus; + + puts("Board PMIC init\n"); return 0; } -- cgit v1.1 From 61b59e2749451d86e73139a81f9f8995e2f4a932 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Date: Tue, 8 Jan 2013 20:42:25 +0000 Subject: video: Modify exynos_fimd driver to support LCD console Currently, exynos FIMD driver is being used to support only TIZEN LOGOs. In order to get LCD console, we need to enable half word swap feature of FIMD and use 16 BPP. LCD console and proprietary Logo cannot be used simultaneously. We use "logo_on" field inside vidinfo_t structure to decide whether user wants Logo or Console. Define CONFIG_CMD_BMP and make logo_on = 1 to get Logo on screen. Use logo_on = 0 to get output console on LCD. Signed-off-by: Ajay Kumar Signed-off-by: Minkyu Kang --- drivers/video/exynos_fb.c | 2 ++ drivers/video/exynos_fimd.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index aac74a3..183bca0 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -88,7 +88,9 @@ static void draw_logo(void) } addr = panel_info.logo_addr; +#ifdef CONFIG_CMD_BMP bmp_display(addr, x, y); +#endif } static void lcd_panel_on(vidinfo_t *vid) diff --git a/drivers/video/exynos_fimd.c b/drivers/video/exynos_fimd.c index 06eae2e..2efe6a6 100644 --- a/drivers/video/exynos_fimd.c +++ b/drivers/video/exynos_fimd.c @@ -88,14 +88,18 @@ static void exynos_fimd_set_par(unsigned int win_id) /* DATAPATH is DMA */ cfg |= EXYNOS_WINCON_DATAPATH_DMA; - /* bpp is 32 */ - cfg |= EXYNOS_WINCON_WSWP_ENABLE; + if (pvid->logo_on) /* To get proprietary LOGO */ + cfg |= EXYNOS_WINCON_WSWP_ENABLE; + else /* To get output console on LCD */ + cfg |= EXYNOS_WINCON_HAWSWP_ENABLE; /* dma burst is 16 */ cfg |= EXYNOS_WINCON_BURSTLEN_16WORD; - /* pixel format is unpacked RGB888 */ - cfg |= EXYNOS_WINCON_BPPMODE_24BPP_888; + if (pvid->logo_on) /* To get proprietary LOGO */ + cfg |= EXYNOS_WINCON_BPPMODE_24BPP_888; + else /* To get output console on LCD */ + cfg |= EXYNOS_WINCON_BPPMODE_16BPP_565; writel(cfg, (unsigned int)&fimd_ctrl->wincon0 + EXYNOS_WINCON(win_id)); -- cgit v1.1 From d04df3c6adf7b025d4f68d4f558975d3beb32544 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Sun, 13 Jan 2013 19:49:36 +0000 Subject: I2C: S3C24X0: Resolve build error for VCMA9 This patch resolves the following build errors for I2C driver in VCMA9: In file included from s3c24x0_i2c.c:40:0: s3c24x0_i2c.h:38:17: error: field 'id' has incomplete type s3c24x0_i2c.c:70:39: error: 'CONFIG_MAX_I2C_NUM' undeclared here (not in a function) s3c24x0_i2c.c:70:31: warning: 'i2c_bus' defined but not used [-Wunused-variable] s3c24x0_i2c.c:72:12: warning: 'i2c_busses' defined but not used [-Wunused-variable] Signed-off-by: Rajeshwari Shinde Signed-off-by: Minkyu Kang --- drivers/i2c/s3c24x0_i2c.c | 4 +++- drivers/i2c/s3c24x0_i2c.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 7ec01ec..769a2ba 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -67,9 +67,11 @@ * variables to live in SRAM */ static unsigned int g_current_bus __attribute__((section(".data"))); +#ifdef CONFIG_OF_CONTROL +static int i2c_busses __attribute__((section(".data"))); static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] __attribute__((section(".data"))); -static int i2c_busses __attribute__((section(".data"))); +#endif #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 1243bf1..a56d749 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -35,7 +35,6 @@ struct s3c24x0_i2c_bus { int node; /* device tree node */ int bus_num; /* i2c bus number */ struct s3c24x0_i2c *regs; - enum periph_id id; + int id; }; - #endif /* _S3C24X0_I2C_H */ -- cgit v1.1 From 02a58b934036dfaa74afb61d383771eda444642b Mon Sep 17 00:00:00 2001 From: Ajay Kumar Date: Sun, 13 Jan 2013 23:32:15 +0000 Subject: video: exynos_dp: Remove unused variable disp_info Remove unused variable disp_info to fix the following compilation warning: exynos_dp.c: In function 'exynos_init_dp': exynos_dp.c:860:23: warning: variable 'disp_info' set but not used [-Wunused-but-set-variable] Signed-off-by: Ajay Kumar Signed-off-by: Minkyu Kang --- drivers/video/exynos_dp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/exynos_dp.c b/drivers/video/exynos_dp.c index 53e4101..d72fa56 100644 --- a/drivers/video/exynos_dp.c +++ b/drivers/video/exynos_dp.c @@ -857,7 +857,6 @@ unsigned int exynos_init_dp(void) { unsigned int ret; struct edp_device_info *edp_info; - struct edp_disp_info disp_info; edp_info = kzalloc(sizeof(struct edp_device_info), GFP_KERNEL); if (!edp_info) { @@ -870,7 +869,6 @@ unsigned int exynos_init_dp(void) debug("failed to get edp_info data.\n"); return -EFAULT; } - disp_info = edp_info->disp_info; exynos_dp_disp_info(&edp_info->disp_info); -- cgit v1.1 From e4660e0b7363cdc86519f4af2143b841592a7ffd Mon Sep 17 00:00:00 2001 From: Ajay Kumar Date: Sun, 13 Jan 2013 23:32:16 +0000 Subject: video: exynos_fb: Make a call to draw_logo only when CONFIG_CMD_BMP is selected Previously, the call to draw_logo() was happening irrespective of whether we have selected logo or LCD console. With this patch we call draw_logo() only when CONFIG_CMD_BMP is selected. This would even fix the following compilation warning: exynos_fb.c: In function 'draw_logo': exynos_fb.c:74:8: warning: variable 'addr' set but not used [-Wunused-but-set-variable] exynos_fb.c:73:9: warning: variable 'y' set but not used [-Wunused-but-set-variable] exynos_fb.c:73:6: warning: variable 'x' set but not used [-Wunused-but-set-variable] Signed-off-by: Ajay Kumar Signed-off-by: Minkyu Kang --- drivers/video/exynos_fb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index 183bca0..ee0ed06 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -68,6 +68,7 @@ static void exynos_lcd_init(vidinfo_t *vid) lcd_set_flush_dcache(1); } +#ifdef CONFIG_CMD_BMP static void draw_logo(void) { int x, y; @@ -88,10 +89,9 @@ static void draw_logo(void) } addr = panel_info.logo_addr; -#ifdef CONFIG_CMD_BMP bmp_display(addr, x, y); -#endif } +#endif static void lcd_panel_on(vidinfo_t *vid) { @@ -150,7 +150,9 @@ void lcd_enable(void) if (panel_info.logo_on) { memset(lcd_base, 0, panel_width * panel_height * (NBITS(panel_info.vl_bpix) >> 3)); +#ifdef CONFIG_CMD_BMP draw_logo(); +#endif } lcd_panel_on(&panel_info); -- cgit v1.1