summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/device/odevice_simpad.cpp87
1 files changed, 68 insertions, 19 deletions
diff --git a/libopie2/opiecore/device/odevice_simpad.cpp b/libopie2/opiecore/device/odevice_simpad.cpp
index 2d0160d..fd46b95 100644
--- a/libopie2/opiecore/device/odevice_simpad.cpp
+++ b/libopie2/opiecore/device/odevice_simpad.cpp
@@ -187,24 +187,85 @@ void SIMpad::initButtons()
#define SIMPAD_IRDA_SD 0x0200 // Shutdown for powersave
#define SIMPAD_RS232_ON 0x0400
#define SIMPAD_SD_MEDIAQ 0x0800 // Shutdown for powersave
#define SIMPAD_LED2_ON 0x1000
#define SIMPAD_IRDA_MODE 0x2000 // Fast/Slow IrDA mode
#define SIMPAD_ENABLE_5V 0x4000 // Enable 5V circuit
#define SIMPAD_RESET_SIMCARD 0x8000
//SIMpad touchscreen backlight strength control
#define SIMPAD_BACKLIGHT_CONTROL "/proc/driver/mq200/registers/PWM_CONTROL"
#define SIMPAD_BACKLIGHT_MASK 0x00a10044
+
+/*
+ * The SIMpad exposes ChipSelect3 to userspace
+ * via a proc filesystem file. Using this register
+ * one can toggle power of serial, irda, dect circuits
+ * change the video driver and display status and
+ * many more things.
+ * To not lose the current setting we read the current
+ * cs3 setting and toggle the necessary bits and then
+ * write it.
+ */
+static bool setCS3Bit( bool bitset, int bit ) {
+ int cs3_fd = ::open( SIMPAD_BOARDCONTROL, O_RDONLY );
+
+ if ( cs3_fd < 0 )
+ return false;
+
+ static char line[32];
+ int val = 0;
+ bool ok = false;
+
+ /*
+ * try to read and parse the Chipselect3 status
+ * be paranoid and make sure line[31] is null
+ * terminated
+ */
+ while( !ok && ::read(cs3_fd, &line, sizeof(line)) > 0 ) {
+ line[31] = '\0';
+ if (::sscanf(line, "Chipselect3 : %x", &val ))
+ ok = true;
+ }
+
+ ::close(cs3_fd);
+
+ /*
+ * we were not able to find the current value
+ * and as a result we won't set it
+ */
+ if ( !ok )
+ return false;
+
+ /*
+ * change the value
+ */
+ val = bitset ? (val | bit) : (val & ~bit);
+
+ /*
+ * write it back
+ */
+ cs3_fd = ::open( SIMPAD_BOARDCONTROL, O_WRONLY );
+ if ( cs3_fd < 0 )
+ return false;
+
+ ::snprintf(line, sizeof(line), "0x%04x\n", val);
+ ::write(cs3_fd, line, strlen(line));
+ ::close(cs3_fd);
+
+ return true;
+}
+
+
QValueList <OLed> SIMpad::ledList() const
{
QValueList <OLed> vl;
vl << Led_Power; //FIXME which LED is LED2 ? The green one or the amber one?
//vl << Led_Mail; //TODO find out if LED1 is accessible anyway
return vl;
}
QValueList <OLedState> SIMpad::ledStateList ( OLed l ) const
{
QValueList <OLedState> vl;
@@ -220,39 +281,30 @@ OLedState SIMpad::ledState ( OLed l ) const
switch ( l ) {
case Led_Power:
return m_leds [0];
//case Led_Mail:
// return m_leds [1];
default:
return Led_Off;
}
}
bool SIMpad::setLedState ( OLed l, OLedState st )
{
-#if 0
- static int fd = ::open ( SIMPAD_BOARDCONTROL, O_RDWR | O_NONBLOCK );
-
- /*TODO Implement this like that:
- read from cs3
- && with SIMPAD_LED2_ON
- write to cs3 */
- m_leds [0] = st;
- return true;
- // }
-// }
-#else
- Q_UNUSED( l )
- Q_UNUSED( st )
-#endif
+ if ( l == Led_Power ) {
+ m_leds [0] = st;
+ setCS3Bit(st == Led_On, SIMPAD_LED2_ON);
+ return true;
+ }
+
return false;
}
bool SIMpad::filter ( int /*unicode*/, int /*keycode*/, int /*modifiers*/, bool /*isPress*/, bool /*autoRepeat*/ )
{
//TODO
return false;
}
void SIMpad::timerEvent ( QTimerEvent * )
{
@@ -301,28 +353,25 @@ bool SIMpad::suspend() // Must override because SIMpad does NOT have apm
bool SIMpad::setSoftSuspend ( bool soft )
{
qDebug( "ODevice for SIMpad: UNHANDLED setSoftSuspend(%s)", soft? "on" : "off" );
return false;
}
bool SIMpad::setDisplayStatus ( bool on )
{
qDebug( "ODevice for SIMpad: setDisplayStatus(%s)", on? "on" : "off" );
-
- QString cmdline = QString().sprintf( "echo %s > /proc/cs3", on ? "0xd41a" : "0xd40a" ); //TODO make better :)
-
- return ( ::system( (const char*) cmdline ) == 0 );
+ return setCS3Bit(on, SIMPAD_DISPLAY_ON);
}
bool SIMpad::setDisplayBrightness ( int bright )
{
qDebug( "ODevice for SIMpad: setDisplayBrightness( %d )", bright );
bool res = false;
int fd;
if ( bright > 255 )
bright = 255;
if ( bright < 1 )