FS#9591 by Anton Veretenenko for the Philips GoGear HDD1620/1630 (with a few changes by me). Fixes boot problem, pixel format, sound, and a few other things.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19395 a1c6a512-1295-4272-9138-f99709370657
diff --git a/docs/CREDITS b/docs/CREDITS
index 2b6128d..03a8cd7 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -435,6 +435,7 @@
 Bartosz Fabianowski
 Adam Hogan
 Andrew Mahone
+Anton Veretenenko
 
 
 The libmad team
diff --git a/firmware/export/config-hdd1630.h b/firmware/export/config-hdd1630.h
index 7ee3f11..3ed77c2 100755
--- a/firmware/export/config-hdd1630.h
+++ b/firmware/export/config-hdd1630.h
@@ -1,12 +1,12 @@
 /*
- * This config file is for the Philips GoGear HDD1630
+ * This config file is for the Philips GoGear HDD16x0/HDD63x0
  */
 
 #define TARGET_TREE /* this target is using the target tree system */
 
 /* For Rolo and boot loader */
 #define MODEL_NUMBER 31
-#define MODEL_NAME   "Philips GoGear HDD1630"
+#define MODEL_NAME   "Philips GoGear HDD16x0"
 
 /* define this if you use an ATA controller */
 #define CONFIG_STORAGE STORAGE_ATA
@@ -48,7 +48,7 @@
 #define LCD_WIDTH  128
 #define LCD_HEIGHT 128
 #define LCD_DEPTH  16   /* 65536 colours */
-#define LCD_PIXELFORMAT RGB565SWAPPED /* rgb565 byte-swapped */
+#define LCD_PIXELFORMAT RGB565  /* rgb565 byte-swapped */
 
 #ifndef BOOTLOADER
 /* Define this if your LCD can be enabled/disabled */
@@ -95,7 +95,7 @@
 /* WM8731 has no tone controls, so we use the software ones */
 #define HAVE_SW_TONE_CONTROLS
 
-#define AB_REPEAT_ENABLE 1
+/* TODO: #define AB_REPEAT_ENABLE 1 */
 
 /* FM Tuner */
 /* #define CONFIG_TUNER TEA5767 */
@@ -117,8 +117,6 @@
 /* define this if you have a light associated with the buttons */
 /* #define HAVE_BUTTON_LIGHT */
 
-#define AB_REPEAT_ENABLE 1
-
 #define BATTERY_CAPACITY_DEFAULT 1550 /* default battery capacity */
 #define BATTERY_CAPACITY_MIN 1500  /* min. capacity selectable */
 #define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
@@ -162,7 +160,7 @@
 #define DEFAULT_CONTRAST_SETTING    14 /* Match boot contrast */
 
 /* We're able to shut off power to the HDD */
-/* #define HAVE_ATA_POWER_OFF */
+#define HAVE_ATA_POWER_OFF
 
 /* Offset ( in the firmware file's header ) to the file CRC and data. These are
    only used when loading the old format rockbox.e200 file */
diff --git a/firmware/target/arm/adc-pp5020.c b/firmware/target/arm/adc-pp5020.c
index a8fe8c1..3395001 100644
--- a/firmware/target/arm/adc-pp5020.c
+++ b/firmware/target/arm/adc-pp5020.c
@@ -35,28 +35,28 @@
 
     /* Start conversion */
     ADC_ADDR |= 0x80000000;
-    
+
     /* Wait for conversion to complete */
     while((ADC_STATUS & (0x40<<8*channel))==0);
-    
+
     /* Stop conversion */
     ADC_ADDR &=~ 0x80000000;
-    
+
     /* ADC_DATA_1 and ADC_DATA_2 are both four bytes, one byte per channel.
        For each channel, ADC_DATA_1 stores the 8-bit msb, ADC_DATA_2 stores the
        2-bit lsb (in bits 0 and 1). Each channel is 10 bits total. */
     adc_data_1 = ((ADC_DATA_1 >> (8*channel)) & 0xff);
     adc_data_2 = ((ADC_DATA_2 >> (8*channel+6)) & 0x3);
-    
+
     adcdata[channel] = (adc_data_1<<2 | adc_data_2);
-    
+
     /* ADC values read low if PLL is enabled */
     if(PLL_CONTROL & 0x80000000){
         adcdata[channel] += 0x14;
         if(adcdata[channel] > 0x400)
             adcdata[channel] = 0x400;
     }
-    
+
     return adcdata[channel];
 }
 
@@ -83,17 +83,18 @@
 /* Figured out from how the OF does things */
 void adc_init(void)
 {
+
     ADC_INIT |= 1;
     ADC_INIT |= 0x40000000;
     udelay(100);
-    
+
     /* Reset ADC */
     DEV_RS2 |= 0x20;
     udelay(100);
-    
+
     DEV_RS2 &=~ 0x20;
     udelay(100);
-    
+
     /* Enable ADC */
     DEV_EN2 |= 0x20;
     udelay(100);
@@ -121,7 +122,8 @@
     ADC_ADDR   |= 0x2000000;
     ADC_STATUS |= 0x2000;
 
-#if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100)
+#if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || \
+    defined(MROBE_100) || defined(PHILIPS_HDD1630)
     /* Enable channel 2 (H10:remote) */
     DEV_INIT1  &=~0x300;
     DEV_INIT1  |= 0x100;
diff --git a/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c b/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c
index 0c49e65..eb2c273 100755
--- a/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c
+++ b/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c
@@ -34,10 +34,14 @@
 
 void _backlight_on(void)
 {
+    GPO32_VAL &= ~0x1000000;
+    GPO32_ENABLE &= ~0x1000000;
 }
 
 void _backlight_off(void)
 {
+    GPO32_VAL |= 0x1000000;
+    GPO32_ENABLE |= 0x1000000;
 }
 
 #ifdef HAVE_BUTTON_LIGHT
diff --git a/firmware/target/arm/philips/hdd1630/button-hdd1630.c b/firmware/target/arm/philips/hdd1630/button-hdd1630.c
index 3a8f7c5..84cb8f0 100755
--- a/firmware/target/arm/philips/hdd1630/button-hdd1630.c
+++ b/firmware/target/arm/philips/hdd1630/button-hdd1630.c
@@ -23,6 +23,21 @@
 #include "button.h"
 #include "backlight.h"
 
+/* Remember last buttons, to make single buzz sound */
+int btn_old;
+
+/*
+ * Generate a click sound from the player (not in headphones yet)
+ * TODO: integrate this with the "key click" option
+ */
+void button_click(void)
+{
+    GPO32_ENABLE |= 0x2000;
+    GPIOD_OUTPUT_VAL |= 0x8;
+    udelay(1000);
+    GPO32_VAL &= ~0x2000;
+}
+
 void button_init_device(void)
 {
     /* TODO...for now, hardware initialisation is done by the bootloader */
@@ -49,19 +64,33 @@
    /* device buttons */
     if (!hold_button)
     {
+        /* These are the correct button definitions
         if (!(GPIOA_INPUT_VAL & 0x01)) btn |= BUTTON_MENU;
         if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_VOL_UP;
         if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN;
         if (!(GPIOA_INPUT_VAL & 0x08)) btn |= BUTTON_VIEW;
-
         if (!(GPIOD_INPUT_VAL & 0x20)) btn |= BUTTON_PLAYLIST;
         if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER;
+        */
+
+        /* This is a hack until the touchpad works */
+        if (!(GPIOA_INPUT_VAL & 0x01)) btn |= BUTTON_LEFT;   /* BUTTON_MENU */
+        if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_UP;     /* BUTTON_VOL_UP */
+        if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_DOWN;   /* BUTTON_VOL_DOWN */
+        if (!(GPIOA_INPUT_VAL & 0x08)) btn |= BUTTON_RIGHT;  /* BUTTON_VIEW */
+        if (!(GPIOD_INPUT_VAL & 0x20)) btn |= BUTTON_SELECT; /* BUTTON_PLAYLIST */
+        if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER;
     }
 
+    if ((btn != btn_old) && (btn != BUTTON_NONE))
+        button_click();
+
+    btn_old = btn;
+
     return btn;
 }
 
 bool headphones_inserted(void)
 {
-    return true;
+    return (GPIOE_INPUT_VAL & 0x80) ? true : false;
 }
diff --git a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c
index d7dee20..827e3ef 100755
--- a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c
+++ b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c
@@ -84,6 +84,7 @@
     LCD2_BLOCK_CTRL = 0x10008080;
     LCD2_BLOCK_CONFIG = 0xF00000;
 
+    /* lcd power */
     GPIOJ_ENABLE     |= 0x4;
     GPIOJ_OUTPUT_VAL |= 0x4;
     GPIOJ_OUTPUT_EN  |= 0x4;
diff --git a/firmware/target/arm/philips/hdd1630/power-hdd1630.c b/firmware/target/arm/philips/hdd1630/power-hdd1630.c
index ade2536..03a5794 100755
--- a/firmware/target/arm/philips/hdd1630/power-hdd1630.c
+++ b/firmware/target/arm/philips/hdd1630/power-hdd1630.c
@@ -35,11 +35,30 @@
 
 void power_init(void)
 {
+    /* power off bit */
+    GPIOB_ENABLE |= 0x80;
+    GPIOB_OUTPUT_VAL |= 0x80;
+    GPIOB_OUTPUT_EN |= 0x80;
+
+    /* charger inserted bit */
+    GPIOE_ENABLE |= 0x20;
+    GPIOE_INPUT_VAL |= 0x20;
 }
 
 unsigned int power_input_status(void)
-{     
-    return POWER_INPUT_NONE;
+{
+    unsigned int status = POWER_INPUT_NONE;
+
+    /* AC charger */
+    if (GPIOE_INPUT_VAL & 0x20)
+        status |= POWER_INPUT_MAIN_CHARGER;
+
+    /* Do nothing with USB for now
+    if (GPIOE_INPUT_VAL & 0x4)
+        status |= POWER_INPUT_USB_CHARGER;
+    */
+
+    return status;
 }
 
 void ide_power_enable(bool on)
@@ -57,4 +76,8 @@
 
 void power_off(void)
 {
+    /* power off bit */
+    GPIOB_ENABLE |= 0x80;
+    GPIOB_OUTPUT_VAL &= ~0x80;
+    GPIOB_OUTPUT_EN |= 0x80;
 }
diff --git a/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c b/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c
index c8d5584..0bb9458 100644
--- a/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c
+++ b/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c
@@ -26,7 +26,7 @@
 
 const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
 {
-    3450 
+    3450
 };
 
 const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
@@ -44,7 +44,7 @@
 /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
 const unsigned short percent_to_volt_charge[11] =
 {
-    3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 
+    3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990
 };
 #endif /* CONFIG_CHARGING */
 
@@ -60,5 +60,7 @@
 /* Returns battery voltage from ADC [millivolts] */
 unsigned int battery_adc_voltage(void)
 {
-    return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
+    /* For now, assume as battery full (we need to calibrate) */
+    /* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
+    return 3990;
 }
diff --git a/firmware/target/arm/wmcodec-pp.c b/firmware/target/arm/wmcodec-pp.c
index 031f5c8..bd3d4e6 100644
--- a/firmware/target/arm/wmcodec-pp.c
+++ b/firmware/target/arm/wmcodec-pp.c
@@ -32,11 +32,12 @@
 #include "i2s.h"
 #include "wmcodec.h"
 
-#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100)
+#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \
+    defined(MROBE_100) || defined(PHILIPS_HDD1630)
 /* The H10's audio codec uses an I2C address of 0x1b */
 #define I2C_AUDIO_ADDRESS 0x1b
 #else
-/* The iPod's audio codecs use an I2C address of 0x1a */ 
+/* The iPod's audio codecs use an I2C address of 0x1a */
 #define I2C_AUDIO_ADDRESS 0x1a
 #endif
 
@@ -100,7 +101,7 @@
 
     /* reset the I2S controller into known state */
     i2s_reset();
-    
+
     audiohw_preinit();
 }