From c0c88533fffdba4544043e6070ba322c8b79234a Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Thu, 25 Oct 2012 19:49:24 +0000 Subject: Sound: Add command for audio playback This patch adds command to test audio playback. sound init - Initialises the audio subsystem (i2s and wm8994 codec) sound play - Plays predefined the audio data when specified length and frequency. Signed-off-by: Rajeshwari Shinde Acked-by: Simon Glass Signed-off-by: Minkyu Kang --- common/Makefile | 1 + common/cmd_sound.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 common/cmd_sound.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index 9e43322..ded6318 100644 --- a/common/Makefile +++ b/common/Makefile @@ -75,6 +75,7 @@ COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o COBJS-$(CONFIG_CMD_DATE) += cmd_date.o +COBJS-$(CONFIG_CMD_SOUND) += cmd_sound.o ifdef CONFIG_4xx COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o endif diff --git a/common/cmd_sound.c b/common/cmd_sound.c new file mode 100644 index 0000000..459d1eb --- /dev/null +++ b/common/cmd_sound.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Rajeshwari Shinde + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* Initilaise sound subsystem */ +static int do_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + int ret; + + ret = sound_init(); + if (ret) { + printf("Initialise Audio driver failed\n"); + return CMD_RET_FAILURE; + } + + return 0; +} + +/* play sound from buffer */ +static int do_play(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + int ret = 0; + int msec = 1000; + int freq = 400; + + if (argc > 1) + msec = simple_strtoul(argv[1], NULL, 10); + if (argc > 2) + freq = simple_strtoul(argv[2], NULL, 10); + + ret = sound_play(msec, freq); + if (ret) { + printf("play failed"); + return CMD_RET_FAILURE; + } + + return 0; +} + +static cmd_tbl_t cmd_sound_sub[] = { + U_BOOT_CMD_MKENT(init, 0, 1, do_init, "", ""), + U_BOOT_CMD_MKENT(play, 2, 1, do_play, "", ""), +}; + +/* process sound command */ +static int do_sound(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + cmd_tbl_t *c; + + if (argc < 1) + return CMD_RET_USAGE; + + /* Strip off leading 'sound' command argument */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], &cmd_sound_sub[0], ARRAY_SIZE(cmd_sound_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + sound, 4, 1, do_sound, + "sound sub-system", + "init - initialise the sound driver\n" + "sound play [len] [freq] - play a sound for len ms at freq hz\n" +); -- cgit v1.1 From 676d319ef5f450ca7845555f75de496b96cd688e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 17 Oct 2012 13:24:54 +0000 Subject: lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment The normal alignment is PAGE_SIZE, but if this is defined, we can support other alignments. The motivation for this change is to make the display section-aligned on ARM so that we can easily turn off data caching for the frame buffer region without resorting to level 2 page tables. Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- common/lcd.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index b6be800..37b0393 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -72,6 +72,10 @@ # endif #endif +#ifndef CONFIG_LCD_ALIGNMENT +#define CONFIG_LCD_ALIGNMENT PAGE_SIZE +#endif + DECLARE_GLOBAL_DATA_PTR; ulong lcd_setmem (ulong addr); @@ -326,6 +330,12 @@ static void test_pattern(void) /* ** GENERIC Initialization Routines */ /************************************************************************/ +int lcd_get_size(int *line_length) +{ + *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; + return *line_length * panel_info.vl_row; +} + int drv_lcd_init (void) { struct stdio_dev lcddev; @@ -333,7 +343,7 @@ int drv_lcd_init (void) lcd_base = (void *)(gd->fb_base); - lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; + lcd_get_size(&lcd_line_length); lcd_init(lcd_base); /* LCD initialization */ @@ -445,15 +455,16 @@ static int lcd_init(void *lcdbase) ulong lcd_setmem(ulong addr) { ulong size; - int line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; + int line_length; debug("LCD panel info: %d x %d, %d bit/pix\n", panel_info.vl_col, panel_info.vl_row, NBITS(panel_info.vl_bpix)); - size = line_length * panel_info.vl_row; + size = lcd_get_size(&line_length); - /* Round up to nearest full page */ - size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); + /* Round up to nearest full page, or MMU section if defined */ + size = ALIGN(size, CONFIG_LCD_ALIGNMENT); + addr = ALIGN(addr - CONFIG_LCD_ALIGNMENT + 1, CONFIG_LCD_ALIGNMENT); /* Allocate pages for the frame buffer. */ addr -= size; -- cgit v1.1 From 9a8efc4604b32221ea362ea41b38d714e4b4ab7a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 30 Oct 2012 13:40:18 +0000 Subject: lcd: Add support for flushing LCD fb from dcache after update This provides an option for the LCD to flush the dcache after each update (puts, scroll or clear). Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- common/lcd.c | 46 +++++++++++++++++++++++++++++++++++++++------- common/main.c | 12 ++++++++++-- 2 files changed, 49 insertions(+), 9 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index 37b0393..d2a3e910 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -94,6 +94,9 @@ static void lcd_setbgcolor(int color); char lcd_is_enabled = 0; +static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ + + #ifdef NOT_USED_SO_FAR static void lcd_getcolreg(ushort regno, ushort *red, ushort *green, ushort *blue); @@ -102,6 +105,28 @@ static int lcd_getfgcolor(void); /************************************************************************/ +/* Flush LCD activity to the caches */ +void lcd_sync(void) +{ + /* + * flush_dcache_range() is declared in common.h but it seems that some + * architectures do not actually implement it. Is there a way to find + * out whether it exists? For now, ARM is safe. + */ +#if defined(CONFIG_ARM) && !defined(CONFIG_SYS_DCACHE_OFF) + int line_length; + + if (lcd_flush_dcache) + flush_dcache_range((u32)lcd_base, + (u32)(lcd_base + lcd_get_size(&line_length))); +#endif +} + +void lcd_set_flush_dcache(int flush) +{ + lcd_flush_dcache = (flush != 0); +} + /*----------------------------------------------------------------------*/ static void console_scrollup(void) @@ -111,6 +136,7 @@ static void console_scrollup(void) /* Clear the last one */ memset(CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); + lcd_sync(); } /*----------------------------------------------------------------------*/ @@ -140,6 +166,8 @@ static inline void console_newline(void) /* Scroll everything up */ console_scrollup(); --console_row; + } else { + lcd_sync(); } } @@ -195,6 +223,7 @@ void lcd_puts(const char *s) while (*s) { lcd_putc(*s++); } + lcd_sync(); } /*----------------------------------------------------------------------*/ @@ -362,13 +391,6 @@ int drv_lcd_init (void) } /*----------------------------------------------------------------------*/ -static -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) -{ - lcd_clear(); - return 0; -} - void lcd_clear(void) { #if LCD_BPP == LCD_MONOCHROME @@ -410,6 +432,14 @@ void lcd_clear(void) console_col = 0; console_row = 0; + lcd_sync(); +} + +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + lcd_clear(); + return 0; } U_BOOT_CMD( @@ -621,6 +651,7 @@ void bitmap_plot(int x, int y) } WATCHDOG_RESET(); + lcd_sync(); } #else static inline void bitmap_plot(int x, int y) {} @@ -842,6 +873,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) break; }; + lcd_sync(); return 0; } #endif diff --git a/common/main.c b/common/main.c index 592ce07..5fdfff2 100644 --- a/common/main.c +++ b/common/main.c @@ -1041,8 +1041,16 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout) puts (tab_seq+(col&07)); col += 8 - (col&07); } else { - ++col; /* echo input */ - putc (c); + char buf[2]; + + /* + * Echo input using puts() to force am + * LCD flush if we are using an LCD + */ + ++col; + buf[0] = c; + buf[1] = '\0'; + puts(buf); } *p++ = c; ++n; -- cgit v1.1 From 0d89efef773318b241df7cb1295ac72742e6f848 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 17 Oct 2012 13:24:59 +0000 Subject: lcd: Add CONFIG_CONSOLE_SCROLL_LINES option to speed console When the cursor position gets to the end of the LCD console we normally scroll by one line. This adds an option to increase that value. Console scrolling is often slow, and if a large amount of output is being sent, increasing this option to 10 or so will speed things up considerably. Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- common/lcd.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index d2a3e910..3017604 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -76,6 +76,11 @@ #define CONFIG_LCD_ALIGNMENT PAGE_SIZE #endif +/* By default we scroll by a single line */ +#ifndef CONFIG_CONSOLE_SCROLL_LINES +#define CONFIG_CONSOLE_SCROLL_LINES 1 +#endif + DECLARE_GLOBAL_DATA_PTR; ulong lcd_setmem (ulong addr); @@ -131,12 +136,20 @@ void lcd_set_flush_dcache(int flush) static void console_scrollup(void) { - /* Copy up rows ignoring the first one */ - memcpy(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); + const int rows = CONFIG_CONSOLE_SCROLL_LINES; + + /* Copy up rows ignoring those that will be overwritten */ + memcpy(CONSOLE_ROW_FIRST, + lcd_console_address + CONSOLE_ROW_SIZE * rows, + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows); + + /* Clear the last rows */ + memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, + COLOR_MASK(lcd_color_bg), + CONSOLE_ROW_SIZE * rows); - /* Clear the last one */ - memset(CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); lcd_sync(); + console_row -= rows; } /*----------------------------------------------------------------------*/ @@ -165,7 +178,6 @@ static inline void console_newline(void) if (console_row >= CONSOLE_ROWS) { /* Scroll everything up */ console_scrollup(); - --console_row; } else { lcd_sync(); } -- cgit v1.1