Commit 1ab3ed37 authored by Robert Sprowson's avatar Robert Sprowson
Browse files

Add support for IIC attached power control and real time clock addons

Boot.s: reorder the SmartReflex turn off to allow for power control module
PowerCtrl.s: new
RTC: scan for a DS1338 real time clock too (and prefer that if found)
Built, but not tested here.

Version 0.25. Tagged as 'OMAP4-0_25'
parent dbed5080
......@@ -17,7 +17,7 @@
COMPONENT = OMAP-4 HAL
TARGET = OMAP4
OBJS = Top Boot Interrupts Timers CLib CLibAsm Stubs UART Debug PRCM Video USB I2C RTC SDMA TPS Audio GPIO GPMC NVMemory KbdScan SDIO SR44x
OBJS = Top Boot Interrupts Timers CLib CLibAsm Stubs UART Debug PRCM Video USB I2C RTC SDMA TPS Audio GPIO GPMC NVMemory KbdScan SDIO SR44x PowerCtrl
USBDIR = <Lib$Dir>.USB
HDRS =
......
/* (0.24)
/* (0.25)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.24
#define Module_MajorVersion_CMHG 0.25
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 09 Nov 2013
#define Module_Date_CMHG 12 Nov 2013
#define Module_MajorVersion "0.24"
#define Module_Version 24
#define Module_MajorVersion "0.25"
#define Module_Version 25
#define Module_MinorVersion ""
#define Module_Date "09 Nov 2013"
#define Module_Date "12 Nov 2013"
#define Module_ApplicationDate "09-Nov-13"
#define Module_ApplicationDate "12-Nov-13"
#define Module_ComponentName "OMAP4"
#define Module_ComponentPath "castle/RiscOS/Sources/HAL/OMAP4"
#define Module_FullVersion "0.24"
#define Module_HelpVersion "0.24 (09 Nov 2013)"
#define Module_LibraryVersionInfo "0:24"
#define Module_FullVersion "0.25"
#define Module_HelpVersion "0.25 (12 Nov 2013)"
#define Module_LibraryVersionInfo "0:25"
......@@ -63,6 +63,8 @@ UseSR44x SETL {TRUE}
IMPORT DebugCallstack
IMPORT SR44x_Init
IMPORT SR44x_Exit
IMPORT PowerCtrl_Init
IMPORT PowerCtrl_SwitchOff
; v8 is used as pointer to RISC OS entry table throughout pre-MMU stage.
MACRO
......@@ -730,6 +732,7 @@ HAL_InitDevices
BL SDMA_Init
BL VideoDevice_Init
BL Audio_Init
BL PowerCtrl_Init
; Board-specific HAL devices
LDR pc, [sb, #BoardConfig_InitDevices]
Board_InitDevices_None
......@@ -866,16 +869,17 @@ HAL_PhysTable
DCD 0
HAL_Reset
[ UseSR44x
Push "a1"
BL SR44x_Exit
Pull "a1"
]
; Reset or power off?
CMP a1, #0
BNE %FT10
; If there is a power control unit connected we can do a power off command
BL PowerCtrl_SwitchOff
10
[ UseSR44x
BL SR44x_Exit
]
; Reset, or power off not supported
; For a reset, we just poke PRM_RSTCTRL.RST_GLOBAL_WARM_software
LDR a3, L4_PowerMan_Log
......
; Copyright 2013 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; support for CJE's power control module
GET Hdr:ListOpts
GET Hdr:Macros
GET Hdr:System
GET Hdr:Machine.<Machine>
GET Hdr:ImageSize.<ImageSize>
$GetIO
GET Hdr:OSEntries
GET Hdr:HALEntries
GET hdr.omap4430
GET hdr.StaticWS
AREA |Asm$$Code|, CODE, READONLY, PIC
EXPORT PowerCtrl_Init
EXPORT PowerCtrl_SwitchOff
IMPORT I2CBusRead
IMPORT I2CBusWrite
IMPORT IIC_DoOp_Poll
; support for external power control chip (CJE)
PWRCTRL_IIC_BUS * (4 - 1) ; I2C4 (on expansion connector A)
PWRCTRL_IIC_ADDR * (&74 * 2)
; Chassis Controller Register
PWRCTRL_ID0 * 0
PWRCTRL_ID1 * 1
PWRCTRL_ID2 * 2
PWRCTRL_ID3 * 3
PWRCTRL_PSU_CONTROL * 4
PWRCTRL_DURATION_A * 5
PWRCTRL_MARK_A * 6
PWRCTRL_SPACE_A * 7
PWRCTRL_LED_A * 8
PWRCTRL_DURATION_B * 9
PWRCTRL_MARK_B * 10
PWRCTRL_SPACE_B * 11
PWRCTRL_LED_B * 12
PWRCTRL_POWER_OFF * 13
PWRCTRL_RESET_TIME * 14
PWRCTRL_ID_STRING * &31454A43 ; == "CJE1"
; values in PWRCTRL_PSU_CONTROL
PWRCTRL_PSU_CONTROL_OFF * "0"
PWRCTRL_PSU_CONTROL_ON * "1"
PWRCTRL_PSU_CONTROL_RESET * "R"
PWRCTRL_PSU_CONTROL_SHUTDOWN * "S" ; ReadOnly (write is ignored)
PowerCtrl_Init
Push "v1-v2,lr"
; check for external PWRCTRL chip on I2C4 bus
; read 4 ID bytes and compare with ID string
LDR v1, OSentries+4*OS_IICOpV ; for I2CBusRead
MOV v2, #PWRCTRL_IIC_BUS ; specify I2C bus
SUB sp, sp, #4 ; temp small buffer on stack
MOV a1, #PWRCTRL_IIC_ADDR
MOV a3, #4
MOV a4, #PWRCTRL_ID0
MOV a2, sp
BL I2CBusRead
CMP a1, #IICStatus_Completed
BNE %FT10
LDR a1, [a2]
LDR lr, =PWRCTRL_ID_STRING
CMP a1, lr
BNE %FT10
; we have seen a PWRCTRL chip ==> activate Soft Power Off feature
LDRB a3, [sb, #BoardConfig_BoardFlags]
ORR a3, a3, #2_01000
STRB a3, [sb, #BoardConfig_BoardFlags]
10
ADD sp, sp, #4
Pull "v1-v2,pc"
PowerCtrl_SwitchOff
Push "v1-v2,lr"
; check if we are called with interrupts disabled - do a polling transfer
MRS v1, CPSR
TST v1, #I32_bit
ADRNEL v1, IIC_DoOp_Poll
LDREQ v1, OSentries+4*OS_IICOpV ; for I2CBusWrite
MOV v2, #PWRCTRL_IIC_BUS ; specify I2C bus
SUB sp, sp, #4 ; temp small buffer on stack
MOV a2, sp
MOV a1, #PWRCTRL_PSU_CONTROL_OFF
STRB a1, [a2]
MOV a1, #PWRCTRL_IIC_ADDR
MOV a3, #1
MOV a4, #PWRCTRL_PSU_CONTROL
BL I2CBusWrite
CMP a1, #IICStatus_Completed
BNE %FT10
B . ; wait until switched OFF
10
ADD sp, sp, #4
Pull "v1-v2,pc"
END
......@@ -32,9 +32,12 @@
AREA |Asm$$Code|, CODE, READONLY, PIC
EXPORT I2CBusRead
EXPORT I2CBusWrite
EXPORT RTC_Init
IMPORT TPSRead
IMPORT TPSWrite
IMPORT IIC_DoOp_Poll
IMPORT memcpy
; TWL6030 RTC IIC address
......@@ -63,18 +66,121 @@ RTC_STATUS_1D_EVENT_M * (1 << 5)
RTC_STATUS_ALARM_M * (1 << 6)
RTC_STATUS_POWER_UP_M * (1 << 7)
; support for external DS1338 RTC chip
DS1338_IIC_BUS * (4 - 1) ; I2C4 (on expansion connector A)
DS1338_IIC_ADDR * (&68 * 2)
DS_RTC_SEC_REG * 0
DS_RTC_MIN_REG * 1
DS_RTC_HOUR_REG * 2
DS_RTC_WDAY_REG * 3
DS_RTC_DAY_REG * 4
DS_RTC_MONTH_REG * 5
DS_RTC_YEAR_REG * 6
DS_RTC_CTRL_REG * 7
; bits in DS_RTC_CTRL_REG
DS_RTC_CTRL_RS0 * (1 << 0)
DS_RTC_CTRL_RS1 * (1 << 1)
DS_RTC_CTRL_SQWE * (1 << 4)
DS_RTC_CTRL_OSF * (1 << 5)
DS_RTC_CTRL_OUT * (1 << 7)
; read/write functions for I2C on any bus
I2CBusRead
; a1 = IIC address(*2)
; a2 = buffer
; a3 = count
; a4 = start register
; v1 = IIC func
; v2 = IIC bus no
; out:
; a1 = return code
; ip corrupted
; buffer updated
ORR a1, a1, #1 ; read
Push "a1-a4,lr" ; Push regs and second iic_transfer block
EOR a1, a1, #1+(1:SHL:29) ; write with retry
ADD a2, sp, #12
MOV a3, #1
Push "a1-a3" ; push first iic_transfer block
MOV a1, sp
MOV a2, v2, LSL #24 ; bus number goes here
ADD a2, a2, #2
MOV a3, #0
BLX v1
ADD sp, sp, #16
Pull "a2-a4,pc"
I2CBusWrite
; a1 = IIC address(*2)
; a2 = buffer
; a3 = count
; a4 = start register
; v1 = IIC func
; v2 = IIC bus no
; out:
; a1 = return code
; ip corrupted
ORR a1, a1, #1:SHL:31 ; Write (no start bit)
Push "a1-a4,lr" ; Push regs and second iic_transfer block
EOR a1, a1, #(1:SHL:29)+(1:SHL:31) ; Write (retries)
ADD a2, sp, #12
MOV a3, #1
Push "a1-a3" ; push first iic_transfer block
MOV a1, sp
MOV a2, v2, LSL #24 ; bus number goes here
ADD a2, a2, #2
MOV a3, #0
BLX v1
ADD sp, sp, #16
Pull "a2-a4,pc"
RTC_Init
; Just register our HAL Device with the OS
Push "v1-v2,lr"
ADRL a1, RTCWS
ADR a2, RTCDeviceTemplate
MOV a3, #RTCSize
Push "lr"
BL memcpy
Pull "lr"
STR sb, [a1, #RTCDeviceHAL_SB]
MOV a2, a1
; check for external DS1338 chip on I2C4 bus
LDR v1, OSentries+4*OS_IICOpV ; for I2CBusRead/I2CBusWrite
MOV v2, #DS1338_IIC_BUS ; specify I2C bus
SUB sp, sp, #4 ; temp small buffer on stack
MOV a1, #DS1338_IIC_ADDR
MOV a3, #1
MOV a4, #DS_RTC_CTRL_REG
MOV a2, sp
BL I2CBusRead
CMP a1, #IICStatus_Completed
BNE %FT10
LDRB a1, [a2]
TST a1, #DS_RTC_CTRL_OSF
BEQ %FT05
BIC a1, a1, #DS_RTC_CTRL_OSF
STRB a1, [a2]
MOV a1, #DS1338_IIC_ADDR
BL I2CBusWrite
05 ; we have seen a DS1338 chip ==> mark it in our workspace
ADRL a3, RTCWS
ADR a1, DS_RTCReadTime
STR a1, [a3, #HALDevice_RTCReadTime]
ADR a1, DS_RTCWriteTime
STR a1, [a3, #HALDevice_RTCWriteTime]
ADR a1, DS_RTCDesc
STR a1, [a3, #HALDevice_Description]
MOV a1, #HALDeviceID_RTC_DS1307 ; at least we are compatible to this one :-)
STRH a1, [a3, #HALDevice_ID]
10
ADD sp, sp, #4
Pull "v1-v2,lr"
MOV a1, #0
ADRL a2, RTCWS
CallOS OS_AddDevice, tailcall
RTCDeviceTemplate
......@@ -103,7 +209,8 @@ RTCDeviceTemplate
RTCDesc
DCB "TWL6030-compatible real-time clock",0
DS_RTCDesc
DCB "DS1338-compatible real-time clock",0
ALIGN
RTCActivate
......@@ -185,7 +292,12 @@ RTCWriteTime
; a1 = return code
Push "v1,v3,sb,lr"
LDR sb, [a1, #RTCDeviceHAL_SB]
LDR v1, OSentries+4*OS_IICOpV ; for TPSRead/TPSWrite
; check if we are called with interrupts disabled - do a polling transfer
; this can happen during the shutdown sequence
MRS v1, CPSR
TST v1, #I32_bit
ADRNEL v1, IIC_DoOp_Poll
LDREQ v1, OSentries+4*OS_IICOpV ; for TPSRead/TPSWrite
MOV v3, a2
; Writing the time safely involves several transfers:
; 1. Write 0 to RTC_CTRL_REG to stop the clock (just in case there are any issues with
......@@ -242,4 +354,104 @@ RTCWriteTime
ADD sp, sp, #4
Pull "v1,v3,sb,pc"
; read/write functions for DS1338 chip
DS_RTCReadTime
; In:
; a1 = HALDevice ptr
; a2 = RTCTimeStruct ptr
; Out:
; a1 = return code
; RTCTimeStruct updated
Push "v1-v3,sb,lr"
LDR sb, [a1, #RTCDeviceHAL_SB]
LDR v1, OSentries+4*OS_IICOpV ; for I2CBusRead
MOV v2, #DS1338_IIC_BUS ; specify I2C bus
MOV v3, a2
; Reading the time starting with DS_RTC_SEC_REG automatically latches the current time.
; There is nothing else to do. We must read the time in 2 blocks because there is
; the weekday register in between which has no corresponding part in RTCTimeStruct.
MOV a1, #DS1338_IIC_ADDR
; We can read the time directly into the RTCTimeStruct buffer
ASSERT RTCTimeStruct_BCD_Minutes=RTCTimeStruct_BCD_Seconds+1
ASSERT RTCTimeStruct_BCD_Hours=RTCTimeStruct_BCD_Seconds+2
ASSERT RTCTimeStruct_BCD_DayOfMonth=RTCTimeStruct_BCD_Seconds+3
ASSERT RTCTimeStruct_BCD_Month=RTCTimeStruct_BCD_Seconds+4
ASSERT RTCTimeStruct_BCD_YearLO=RTCTimeStruct_BCD_Seconds+5
ADD a2, v3, #RTCTimeStruct_BCD_Seconds
MOV a3, #(DS_RTC_WDAY_REG - DS_RTC_SEC_REG)
MOV a4, #DS_RTC_SEC_REG
BL I2CBusRead
CMP a1, #IICStatus_Completed
MOVNE a1, #RTCRetCode_Error
Pull "v1-v3,sb,pc", NE
; read second part
MOV a1, #DS1338_IIC_ADDR
ADD a2, v3, #RTCTimeStruct_BCD_DayOfMonth
MOV a3, #(DS_RTC_YEAR_REG - DS_RTC_WDAY_REG)
MOV a4, #DS_RTC_DAY_REG
BL I2CBusRead
CMP a1, #IICStatus_Completed
MOVNE a1, #RTCRetCode_Error
ASSERT IICStatus_Completed = 0
STREQB a1, [v3, #RTCTimeStruct_BCD_Centiseconds] ; No centisecond time
STREQB a1, [v3, #RTCTimeStruct_BCD_YearHI] ; Kernel gives year help
ASSERT RTCRetCode_OK = 0
Pull "v1-v3,sb,pc"
DS_RTCWriteTime
; In:
; a1 = HALDevice ptr
; a2 = RTCTimeStruct ptr
; Out:
; a1 = return code
Push "v1-v3,sb,lr"
LDR sb, [a1, #RTCDeviceHAL_SB]
; check if we are called with interrupts disabled - do a polling transfer
; this can happen during the shutdown sequence
MRS v1, CPSR
TST v1, #I32_bit
ADRNEL v1, IIC_DoOp_Poll
LDREQ v1, OSentries+4*OS_IICOpV ; for I2CBusWrite
MOV v2, #DS1338_IIC_BUS ; specify I2C bus
MOV v3, a2
; Writing the time starting with DS_RTC_SEC_REG automatically synchronises the write.
; There is nothing else to do. But we must cope for differences in the register layout
; and the RTCTimeStruct (weekday register in between).
; We can write the time directly from the RTCTimeStruct buffer
ASSERT RTCTimeStruct_BCD_Minutes=RTCTimeStruct_BCD_Seconds+1
ASSERT RTCTimeStruct_BCD_Hours=RTCTimeStruct_BCD_Seconds+2
ASSERT RTCTimeStruct_BCD_DayOfMonth=RTCTimeStruct_BCD_Seconds+3
ASSERT RTCTimeStruct_BCD_Month=RTCTimeStruct_BCD_Seconds+4
ASSERT RTCTimeStruct_BCD_YearLO=RTCTimeStruct_BCD_Seconds+5
ADD a2, v3, #RTCTimeStruct_BCD_Seconds
; Sometimes we don't write the time, so skip those bytes if necessary
LDRB ip, [a2]
CMP ip, #255
BEQ %FT10
MOV a1, #DS1338_IIC_ADDR
MOV a3, #(DS_RTC_WDAY_REG - DS_RTC_SEC_REG)
MOV a4, #DS_RTC_SEC_REG
BL I2CBusWrite
CMP a1, #IICStatus_Completed
MOVNE a1, #RTCRetCode_Error
Pull "v1-v3,sb,pc", NE
10
; write second part
; Sometimes we don't write the date either
LDRB ip, [v3, #RTCTimeStruct_BCD_DayOfMonth]
CMP ip, #255
BEQ %FT20
MOV a1, #DS1338_IIC_ADDR
ADD a2, v3, #RTCTimeStruct_BCD_DayOfMonth
MOV a3, #(DS_RTC_YEAR_REG - DS_RTC_WDAY_REG)
MOV a4, #DS_RTC_DAY_REG
BL I2CBusWrite
CMP a1, #IICStatus_Completed
MOVNE a1, #RTCRetCode_Error
Pull "v1-v3,sb,pc"
20
MOV a1, #RTCRetCode_OK
Pull "v1-v3,sb,pc"
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment