diff options
-rw-r--r-- | board/goldelico/gta04/commands.c | 24 | ||||
-rw-r--r-- | board/goldelico/gta04/status.c | 63 | ||||
-rw-r--r-- | board/goldelico/gta04/status.h | 2 |
3 files changed, 59 insertions, 30 deletions
diff --git a/board/goldelico/gta04/commands.c b/board/goldelico/gta04/commands.c index f0d56a9..c2f8117 100644 --- a/board/goldelico/gta04/commands.c +++ b/board/goldelico/gta04/commands.c @@ -449,25 +449,13 @@ static int do_status_flash(int argc, char *const argv[]) static int do_status_vibra(int argc, char *const argv[]) { - int len; - + static int value; if (argc < 3) { - printf ("status flash: missing subcommand.\n"); + printf ("status vibra: missing value.\n"); return (-1); } - - len = strlen (argv[2]); - if (strncmp ("of", argv[2], 2) == 0) { - return status_set_vibra (0); - } else if (strncmp ("on", argv[2], 2) == 0) { - return status_set_vibra (1); - } else if (strncmp ("fl", argv[2], 2) == 0) { - return status_set_vibra (2); - } else { - printf ("status: unknown operation: %s\n", argv[1]); - return 1; - } - return (0); + value=simple_strtol(argv[2], NULL, 10); + return status_set_vibra(value); } static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) @@ -511,8 +499,8 @@ U_BOOT_CMD(status, 3, 0, do_status, "LED and Buttons sub-system", "se[t] value - set LEDs state\n" "mi[rror] - read buttons and mirror to LEDs\n" "bl[ink] - blink LEDs\n" - "fl[ash] of[f] | on | fl[ash] - switch torch / flashlight\n" - "vi[bra] of[f] | le[ft] | ri[ght] - switch vibracall motor\n" + "fl[ash] of[f] | on | fl[ash] - control torch / flashlight\n" + "vi[bra] -256..256 - run vibracall motor\n" ); /** GPS commands */ diff --git a/board/goldelico/gta04/status.c b/board/goldelico/gta04/status.c index a78ab92..ea10357 100644 --- a/board/goldelico/gta04/status.c +++ b/board/goldelico/gta04/status.c @@ -43,8 +43,8 @@ static int hasTCA6507=0; #endif -#define TWL4030_I2C_BUS 1 // I2C1 -#define TCA6507_BUS 2 // I2C2 +#define TWL4030_I2C_BUS (1-1) // I2C1 +#define TCA6507_BUS (2-1) // I2C2 #define TCA6507_ADDRESS 0x45 /* register numbers */ @@ -118,7 +118,7 @@ void status_set_status(int value) } else { value &= 0x3f; // 6 LEDs only - 7th is reserved to reset the WLAN/BT chip - i2c_set_bus_num(TCA6507_BUS-1); // write I2C2 + i2c_set_bus_num(TCA6507_BUS); // write I2C2 // we could write a autoincrement address and all 3 bytes in a single message // we could set the TCA to do smooth transitions i2c_reg_write(TCA6507_ADDRESS, TCA6507_SELECT0, 0); @@ -131,7 +131,7 @@ int status_get_buttons(void) { // convert button state into led state #if defined(CONFIG_OMAP3_GTA04) u8 val; - i2c_set_bus_num(TWL4030_I2C_BUS-1); // read I2C1 + i2c_set_bus_num(TWL4030_I2C_BUS); // read I2C1 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, &val, TWL4030_PM_MASTER_STS_HW_CONDITIONS); // read state of power button (bit 0) from TPS65950 return ((omap_get_gpio_datain(GPIO_AUX)) << 0) | ((omap_get_gpio_datain(GPIO_GPSEXT)) << 1) | @@ -156,7 +156,7 @@ int status_init(void) { isXM = (get_board_revision() == REVISION_XM); #if !defined(CONFIG_OMAP3_GTA04) - if(i2c_set_bus_num(TCA6507_BUS-1)) + if(i2c_set_bus_num(TCA6507_BUS)) { printf ("could not select I2C2\n"); return 1; @@ -222,7 +222,7 @@ int status_init(void) int status_set_flash (int mode) { // 0: off, 1: torch, 2: flash - if(i2c_set_bus_num(TCA6507_BUS-1)) + if(i2c_set_bus_num(TCA6507_BUS)) { printf ("could not select I2C2\n"); return 1; @@ -232,14 +232,55 @@ int status_set_flash (int mode) return 0; } -int status_set_vibra (int mode) -{ // 0: off, 1: left, 2: right - if(i2c_set_bus_num(TWL4030_I2C_BUS-1)) +int status_set_vibra (int value) +{ // 0: off otherwise msb controls left/right (2's complement) + unsigned char byte; + if(i2c_set_bus_num(TWL4030_I2C_BUS)) { printf ("could not select I2C1\n"); return 1; } - // initialize if needed - // set vibra controller mode + + // program Audio controller (see document SWCU050D) + + byte = 0x00; // LEDAON=LEDBON=0 + i2c_write(0x4A, 0xEE, 1, &byte, 1); // LEDEN + byte = value != 0 ? 0x03 : 0x00; // 8 kHz, Codec on (if value != 0), Option 1:RX and TX stereo audio path + i2c_write(0x49, 0x01, 1, &byte, 1); // CODEC_MODE + byte = 0x16; // APLL_EN enabled, 26 MHz + i2c_write(0x49, 0x3a, 1, &byte, 1); // APLL_CTL + byte = 0x04; // use PWM + i2c_write(0x4B, 0x60, 1, &byte, 1); // VIBRATOR_CFG + byte = value > 0?0x01:0x03; // use VIBRADIR, local driver, enable + i2c_write(0x49, 0x45, 1, &byte, 1); // VIBRATOR_CFG + byte = 256-(value>=0?value:-value); // PWM turnon value + if(byte == 0) byte = 0x01; // 0x00 is forbidden! + i2c_write(0x49, 0x46, 1, &byte, 1); // VIBRA_SEL + + // do we have to set some Audio PLL frequency (number 6 & 7?) + + /* + To use the vibrator H-bridge: + 1. Disable LEDA: Set the LEDEN[0]LEDAON bit to logic 0. + 2. Disable LEDB: Set the LEDEN[1]LEDBON bit to logic 0. + 3. Turn on the codec: + Set the CODEC_MODE[1] CODECPDZ bit to 1. + The H-bridge vibrator can get its operation from the following sources: + • An audio channel can provide the stimulus. + • A PWM in the audio subchip can generate the signal. + If an audio channel provides the motivating force for the vibrator (for example: the audio right 1 channel): + 1. Set the VIBR_CTL[4]VIBRA_SEL bit to 1. + 2. Set the VIBR_CTL[5]VIBRA_DIR_SEL bit to 1. + 3. Set the VIBR_CTL[3:2]VIBRA_AUDIO_SEL bit field to 0x1 (audio right 1 channel). + 4. Select the use of the SIGN bit to determine the output phase to VIBRA_P and VIBRA_M. + 5. Set the VIBRA_CTL[0]VIBRA_EN bit to 1 (power to the H-bridge is driven by audiodata). + Notes: + • If audio data drives the vibrator H-bridge, set the VIBRA_SET register to 0xFF. + • The direction of the vibrator H-bridge controlled by the VIBRA_DIR bit can be changed + on the fly. + 6. Set the audio PLL input frequency: The APLL_CTL APLL_INFREQ bitfield=0x6. + 7. Enable the audio PLL: The APLL_CTL APLL_ENbit=1. + Note: Do not enable LEDA/B and the H-vibrator simultaneously. + */ return 0; } diff --git a/board/goldelico/gta04/status.h b/board/goldelico/gta04/status.h index d60fc8a..5bed2e2 100644 --- a/board/goldelico/gta04/status.h +++ b/board/goldelico/gta04/status.h @@ -7,6 +7,6 @@ void status_set_status (int value); int status_get_buttons (void); int status_set_flash (int mode); // 0: off, 1: torch, 2: flash -int status_set_vibra (int mode); // 0: off, 1: left, 2: right +int status_set_vibra (int value); // 0: off, >0 / <0 determines polarity . -255 ... +255 #endif |