brintos

brintos / linux-shallow public Read only

0
0
Text · 8.0 KiB · 757dda7 Raw
394 lines · plain
1/*2 * Copyright 2013 Red Hat Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: Ben Skeggs23 */24 25#define T_TIMEOUT  220000026#define T_RISEFALL 100027#define T_HOLD     500028 29#ifdef INCLUDE_PROC30process(PROC_I2C_, #i2c_init, #i2c_recv)31#endif32 33/******************************************************************************34 * I2C_ data segment35 *****************************************************************************/36#ifdef INCLUDE_DATA37i2c_scl_map:38.b32 NV_PPWR_OUTPUT_I2C_0_SCL39.b32 NV_PPWR_OUTPUT_I2C_1_SCL40.b32 NV_PPWR_OUTPUT_I2C_2_SCL41.b32 NV_PPWR_OUTPUT_I2C_3_SCL42.b32 NV_PPWR_OUTPUT_I2C_4_SCL43.b32 NV_PPWR_OUTPUT_I2C_5_SCL44.b32 NV_PPWR_OUTPUT_I2C_6_SCL45.b32 NV_PPWR_OUTPUT_I2C_7_SCL46.b32 NV_PPWR_OUTPUT_I2C_8_SCL47.b32 NV_PPWR_OUTPUT_I2C_9_SCL48i2c_sda_map:49.b32 NV_PPWR_OUTPUT_I2C_0_SDA50.b32 NV_PPWR_OUTPUT_I2C_1_SDA51.b32 NV_PPWR_OUTPUT_I2C_2_SDA52.b32 NV_PPWR_OUTPUT_I2C_3_SDA53.b32 NV_PPWR_OUTPUT_I2C_4_SDA54.b32 NV_PPWR_OUTPUT_I2C_5_SDA55.b32 NV_PPWR_OUTPUT_I2C_6_SDA56.b32 NV_PPWR_OUTPUT_I2C_7_SDA57.b32 NV_PPWR_OUTPUT_I2C_8_SDA58.b32 NV_PPWR_OUTPUT_I2C_9_SDA59#if NVKM_PPWR_CHIPSET < GF11960i2c_ctrl:61.b32 0x00e13862.b32 0x00e15063.b32 0x00e16864.b32 0x00e18065.b32 0x00e25466.b32 0x00e27467.b32 0x00e76468.b32 0x00e78069.b32 0x00e79c70.b32 0x00e7b871#endif72#endif73 74/******************************************************************************75 * I2C_ code segment76 *****************************************************************************/77#ifdef INCLUDE_CODE78 79// $r3  - value80// $r2  - sda line81// $r1  - scl line82// $r0  - zero83i2c_drive_scl:84	cmp b32 $r3 085	bra e #i2c_drive_scl_lo86	nv_iowr(NV_PPWR_OUTPUT_SET, $r1)87	ret88	i2c_drive_scl_lo:89	nv_iowr(NV_PPWR_OUTPUT_CLR, $r1)90	ret91 92i2c_drive_sda:93	cmp b32 $r3 094	bra e #i2c_drive_sda_lo95	nv_iowr(NV_PPWR_OUTPUT_SET, $r2)96	ret97	i2c_drive_sda_lo:98	nv_iowr(NV_PPWR_OUTPUT_CLR, $r2)99	ret100 101i2c_sense_scl:102	bclr $flags $p1103	nv_iord($r3, NV_PPWR_INPUT)104	and $r3 $r1105	bra z #i2c_sense_scl_done106		bset $flags $p1107	i2c_sense_scl_done:108	ret109 110i2c_sense_sda:111	bclr $flags $p1112	nv_iord($r3, NV_PPWR_INPUT)113	and $r3 $r2114	bra z #i2c_sense_sda_done115		bset $flags $p1116	i2c_sense_sda_done:117	ret118 119#define i2c_drive_scl(v) /*120*/	mov $r3 (v) /*121*/	call(i2c_drive_scl)122#define i2c_drive_sda(v) /*123*/	mov $r3 (v) /*124*/	call(i2c_drive_sda)125#define i2c_sense_scl() /*126*/	call(i2c_sense_scl)127#define i2c_sense_sda() /*128*/	call(i2c_sense_sda)129#define i2c_delay(v) /*130*/	mov $r14 (v) /*131*/	call(nsec)132 133#define i2c_trace_init() /*134*/	imm32($r6, 0x10000000) /*135*/	sub b32 $r7 $r6 1 /*136*/137#define i2c_trace_down() /*138*/	shr b32 $r6 4 /*139*/	push $r5 /*140*/	shl b32 $r5 $r6 4 /*141*/	sub b32 $r5 $r6 /*142*/	not b32 $r5 /*143*/	and $r7 $r5 /*144*/	pop $r5 /*145*/146#define i2c_trace_exit() /*147*/	shl b32 $r6 4 /*148*/149#define i2c_trace_next() /*150*/	add b32 $r7 $r6 /*151*/152#define i2c_trace_call(func) /*153*/	i2c_trace_next() /*154*/	i2c_trace_down() /*155*/	call(func) /*156*/	i2c_trace_exit() /*157*/158 159i2c_raise_scl:160	push $r4161	mov $r4 (T_TIMEOUT / T_RISEFALL)162	i2c_drive_scl(1)163	i2c_raise_scl_wait:164		i2c_delay(T_RISEFALL)165		i2c_sense_scl()166		bra $p1 #i2c_raise_scl_done167		sub b32 $r4 1168		bra nz #i2c_raise_scl_wait169	i2c_raise_scl_done:170	pop $r4171	ret172 173i2c_start:174	i2c_sense_scl()175	bra not $p1 #i2c_start_rep176	i2c_sense_sda()177	bra not $p1 #i2c_start_rep178	bra #i2c_start_send179	i2c_start_rep:180		i2c_drive_scl(0)181		i2c_drive_sda(1)182		i2c_trace_call(i2c_raise_scl)183		bra not $p1 #i2c_start_out184	i2c_start_send:185	i2c_drive_sda(0)186	i2c_delay(T_HOLD)187	i2c_drive_scl(0)188	i2c_delay(T_HOLD)189	i2c_start_out:190	ret191 192i2c_stop:193	i2c_drive_scl(0)194	i2c_drive_sda(0)195	i2c_delay(T_RISEFALL)196	i2c_drive_scl(1)197	i2c_delay(T_HOLD)198	i2c_drive_sda(1)199	i2c_delay(T_HOLD)200	ret201 202// $r3  - value203// $r2  - sda line204// $r1  - scl line205// $r0  - zero206i2c_bitw:207	call(i2c_drive_sda)208	i2c_delay(T_RISEFALL)209	i2c_trace_call(i2c_raise_scl)210	bra not $p1 #i2c_bitw_out211	i2c_delay(T_HOLD)212	i2c_drive_scl(0)213	i2c_delay(T_HOLD)214	i2c_bitw_out:215	ret216 217// $r3  - value (out)218// $r2  - sda line219// $r1  - scl line220// $r0  - zero221i2c_bitr:222	i2c_drive_sda(1)223	i2c_delay(T_RISEFALL)224	i2c_trace_call(i2c_raise_scl)225	bra not $p1 #i2c_bitr_done226	i2c_sense_sda()227	i2c_drive_scl(0)228	i2c_delay(T_HOLD)229	xbit $r3 $flags $p1230	bset $flags $p1231	i2c_bitr_done:232	ret233 234i2c_get_byte:235	mov $r5 0236	mov $r4 8237	i2c_get_byte_next:238		shl b32 $r5 1239		i2c_trace_call(i2c_bitr)240		bra not $p1 #i2c_get_byte_done241		or $r5 $r3242		sub b32 $r4 1243		bra nz #i2c_get_byte_next244	mov $r3 1245	i2c_trace_call(i2c_bitw)246	i2c_get_byte_done:247	ret248 249i2c_put_byte:250	mov $r4 8251	i2c_put_byte_next:252		sub b32 $r4 1253		xbit $r3 $r5 $r4254		i2c_trace_call(i2c_bitw)255		bra not $p1 #i2c_put_byte_done256		cmp b32 $r4 0257		bra ne #i2c_put_byte_next258	i2c_trace_call(i2c_bitr)259	bra not $p1 #i2c_put_byte_done260	i2c_trace_next()261	cmp b32 $r3 1262	bra ne #i2c_put_byte_done263	bclr $flags $p1	// nack264	i2c_put_byte_done:265	ret266 267i2c_addr:268	i2c_trace_call(i2c_start)269	bra not $p1 #i2c_addr_done270	extr $r3 $r12 I2C__MSG_DATA0_ADDR271	shl b32 $r3 1272	or $r5 $r3273	i2c_trace_call(i2c_put_byte)274	i2c_addr_done:275	ret276 277i2c_acquire_addr:278	extr $r14 $r12 I2C__MSG_DATA0_PORT279#if NVKM_PPWR_CHIPSET < GF119280	shl b32 $r14 2281	add b32 $r14 #i2c_ctrl282	ld b32 $r14 D[$r14]283#else284	shl b32 $r14 5285	add b32 $r14 0x00d014286#endif287	ret288 289i2c_acquire:290	call(i2c_acquire_addr)291	call(rd32)292	bset $r13 3293	call(wr32)294	ret295 296i2c_release:297	call(i2c_acquire_addr)298	call(rd32)299	bclr $r13 3300	call(wr32)301	ret302 303// description304//305// $r15 - current (i2c)306// $r14 - sender process name307// $r13 - message308// $r12 - data0309// $r11 - data1310// $r0  - zero311i2c_recv:312	bclr $flags $p1313	extr $r1 $r12 I2C__MSG_DATA0_PORT314	shl b32 $r1 2315	cmp b32 $r1 (#i2c_sda_map - #i2c_scl_map)316	bra ge #i2c_recv_done317	add b32 $r3 $r1 #i2c_sda_map318	ld b32 $r2 D[$r3]319	add b32 $r3 $r1 #i2c_scl_map320	ld b32 $r1 D[$r3]321 322	bset $flags $p2323	push $r13324	push $r14325 326	push $r13327	i2c_trace_init()328	i2c_trace_call(i2c_acquire)329	pop $r13330 331	cmp b32 $r13 I2C__MSG_RD08332	bra ne #i2c_recv_not_rd08333		mov $r5 0334		i2c_trace_call(i2c_addr)335		bra not $p1 #i2c_recv_done336		extr $r5 $r12 I2C__MSG_DATA0_RD08_REG337		i2c_trace_call(i2c_put_byte)338		bra not $p1 #i2c_recv_done339		mov $r5 1340		i2c_trace_call(i2c_addr)341		bra not $p1 #i2c_recv_done342		i2c_trace_call(i2c_get_byte)343		bra not $p1 #i2c_recv_done344		ins $r11 $r5 I2C__MSG_DATA1_RD08_VAL345		i2c_trace_call(i2c_stop)346		mov b32 $r11 $r5347		clear b32 $r7348		bra #i2c_recv_done349 350	i2c_recv_not_rd08:351	cmp b32 $r13 I2C__MSG_WR08352	bra ne #i2c_recv_not_wr08353		mov $r5 0354		call(i2c_addr)355		bra not $p1 #i2c_recv_done356		extr $r5 $r12 I2C__MSG_DATA0_WR08_REG357		call(i2c_put_byte)358		bra not $p1 #i2c_recv_done359		mov $r5 0360		call(i2c_addr)361		bra not $p1 #i2c_recv_done362		extr $r5 $r11 I2C__MSG_DATA1_WR08_VAL363		call(i2c_put_byte)364		bra not $p1 #i2c_recv_done365		call(i2c_stop)366		clear b32 $r7367		extr $r5 $r12 I2C__MSG_DATA0_WR08_SYNC368		bra nz #i2c_recv_done369		bclr $flags $p2370		bra #i2c_recv_done371 372	i2c_recv_not_wr08:373 374	i2c_recv_done:375	extr $r14 $r12 I2C__MSG_DATA0_PORT376	call(i2c_release)377 378	pop $r14379	pop $r13380	bra not $p2 #i2c_recv_exit381	mov b32 $r12 $r7382	call(send)383 384	i2c_recv_exit:385	ret386 387// description388//389// $r15 - current (i2c)390// $r0  - zero391i2c_init:392	ret393#endif394