Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Shark LED and I2C drivers



Hi all,

I was looking at the DNARD User Guide and noticed that it mentioned an I2C
bus connected to the Sequoia chip to communicate with the DIMM's, and also
mentioned which pins were used.  After a bit of experimentation, I have a
working bit-bang I2C bus.  While looking at our sequoia code, it seemed
easy to manipulate the front and debug LED's too.

I've attached a patch that:

  adds the additional devices (shark_machdep.c)
  configures the additional devices (ofisa.c)
  handles register configuration for the I2C bus and the LED's (sequoia.c)
  adds glue for the devices (shark_iic.c and shark_led.c)

Output on my 64MB shark is:

[   1.0000000] sharkled0 at ofisa0: front, debug
[   1.0000000] sharkiic0 at ofisa0
[   1.0000000] iic0 at sharkiic0: I2C bus
[   1.0000000] spdmem0 at iic0 addr 0x50
[   1.0000000] spdmem0: SDRAM, no parity or ECC, 32MB, 100MHz (PC-100)
[   1.0000000] spdmem1 at iic0 addr 0x51
[   1.0000000] spdmem1: SDRAM, no parity or ECC, 32MB, 100MHz (PC-100)

and my 32MB shark:

[   1.0000000] sharkled0 at ofisa0: front, debug
[   1.0000000] sharkiic0 at ofisa0
[   1.0000000] iic0 at sharkiic0: I2C bus
[   1.0000000] seeprom0 at iic0 addr 0x50: AT24Cxx or compatible EEPROM: size 256
[   1.0000000] seeprom1 at iic0 addr 0x51: AT24Cxx or compatible EEPROM: size 256

Seeprom attaches because the DIMM's are not SPD-compatible.  I was however,
able to inspect their contents using:

  for i in 0 1; do dd if=/dev/seeprom$i bs=256k count=1 | hexdump -C; done

and see that it has 2 Samsung KMM366S203BTN-G2 (16MB PC-66) DIMM's installed.

Comments appreciated.

Regards,

Julian
Index: src/sys/dev/ofisa/ofisa.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofisa/ofisa.c,v
retrieving revision 1.27
diff -u -r1.27 ofisa.c
--- src/sys/dev/ofisa/ofisa.c	19 Jan 2021 14:39:20 -0000	1.27
+++ src/sys/dev/ofisa/ofisa.c	21 Apr 2021 07:09:13 -0000
@@ -102,6 +102,8 @@
 	struct isabus_attach_args iba;
 	struct ofisa_attach_args aa;
 	int child;
+	prop_dictionary_t props;
+	prop_array_t child_devices = NULL;
 
 	if (ofisa_get_isabus_data(oba->oba_phandle, &iba) < 0) {
 		printf(": couldn't get essential bus data\n");
@@ -133,6 +135,27 @@
 
 		config_found(self, &aa, ofisaprint);
 	}
+
+	props = device_properties(self);
+	child_devices = prop_dictionary_get(props, "ofisa-child-devices");
+	if (child_devices) {
+		unsigned int i, count;
+		prop_dictionary_t dev;
+		const char *name;
+
+		count = prop_array_count(child_devices);
+		for (i = 0; i < count; i++) {
+			dev = prop_array_get(child_devices, i);
+			if (!dev) continue;
+			if (prop_dictionary_get_cstring_nocopy(dev,
+			    "name", &name)) {
+				memset(&aa, 0, sizeof aa);
+				aa.oba.oba_busname = "ofw";	/* XXX */
+				strcpy(aa.oba.oba_ofname, name);
+				config_found_ia(self, "ofisa", &aa, NULL);
+			}
+		}
+	}
 }
 
 int
Index: src/sys/arch/shark/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/conf/GENERIC,v
retrieving revision 1.136
diff -u -r1.136 GENERIC
--- src/sys/arch/shark/conf/GENERIC	16 Aug 2020 10:27:47 -0000	1.136
+++ src/sys/arch/shark/conf/GENERIC	21 Apr 2021 07:09:13 -0000
@@ -268,6 +268,13 @@
 #vlpci*		at ofbus?
 #pci*		at vlpci?
 
+sharkled* 	at ofisa?		# Front and debug LED's
+
+sharkiic* 	at ofisa?		# SDRAM I2C bus
+iic* 		at sharkiic?
+spdmem* 	at iic? addr?		# SPD-compatible DIMM's
+seeprom* 	at iic? addr? flags 0x2	# Older, non-SPD-compatible DIMM's
+
 # Pull in optional local configuration
 cinclude "arch/shark/conf/GENERIC.local"
 
Index: src/sys/arch/shark/conf/files.shark
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/conf/files.shark,v
retrieving revision 1.21
diff -u -r1.21 files.shark
--- src/sys/arch/shark/conf/files.shark	18 Dec 2017 15:53:39 -0000	1.21
+++ src/sys/arch/shark/conf/files.shark	21 Apr 2021 07:09:13 -0000
@@ -146,4 +146,14 @@
 file	arch/shark/shark/scr.c			scr needs-flag
 attach	scr at ofisascr
 
+# LED
+device	sharkled: leds
+file	arch/shark/shark/shark_led.c		sharkled needs-flag
+attach	sharkled at ofisa
+
+# IIC
+device	sharkiic: i2cexec, i2c_bitbang, i2cbus
+file	arch/shark/shark/shark_iic.c		sharkiic needs-flag
+attach	sharkiic at ofisa
+
 include "arch/shark/conf/majors.shark"
Index: src/sys/arch/shark/shark/sequoia.c
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/shark/sequoia.c,v
retrieving revision 1.14
diff -u -r1.14 sequoia.c
--- src/sys/arch/shark/shark/sequoia.c	20 Oct 2016 09:53:08 -0000	1.14
+++ src/sys/arch/shark/shark/sequoia.c	21 Apr 2021 07:09:14 -0000
@@ -50,6 +50,7 @@
 #include <sys/bus.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
+#include <sys/device.h>
 
 
 #include <dev/isa/isareg.h>
@@ -58,6 +59,9 @@
 #include <shark/shark/shark_fiq.h>
 #include <arm/cpufunc.h>
 
+#if NSHARKLED > 0
+#include <dev/led.h>
+#endif
 
 
 
@@ -98,6 +102,14 @@
 #define SCR_BUGB_DIR        OGPIOCR_M_GPIODIR7
 #define SCR_BUGB            OGPIOCR_M_GPIODATA7
 
+
+/* define pins on sequoia that talk to the DIMM I2C bus */
+#define IIC_CLK		    FOMPCR_M_PCON9
+
+#define IIC_DATA_IN_DIR	    GPCR_M_GPIODIR3
+#define IIC_DATA_IN	    GPCR_M_GPIODATA3
+
+#define IIC_DATA_OUT_DIR    GPIOCR2_M_GPIOBDIR1
                                  
 
 /* define pins on sequoia that talk to leds */
@@ -109,11 +121,16 @@
 
 
 /* define biled colors */
-#define  LED_BILED_NONE     0
-#define  LED_BILED_GREEN    1
-#define  LED_BILED_YELLOW   2
-#define  LED_BILED_RED      3
+#define  LED_BILED_NONE              0
+#define  LED_BILED_GREEN             1
+#define  LED_BILED_YELLOW            2
+#define  LED_BILED_RED               3	/* Green + Yellow */
+
+#define  LED_BILED_GREEN_OFF         4
+#define  LED_BILED_GREEN_ON          5
 
+#define  LED_BILED_YELLOW_OFF        6
+#define  LED_BILED_YELLOW_ON         7
     
 #define LED_TIMEOUT    hz / 20                       /* 20 times a second */
 #define LED_NET_ACTIVE (1000000/hz) * LED_TIMEOUT   /* delay in us for net activity */
@@ -129,7 +146,8 @@
 static bus_space_handle_t sequoia_ioh;
 
 static struct timeval ledLastActive;      /* last time we get net activity */
-static int      ledColor;           /* present color of led */
+static int      ledColor;           /* present color of front led */
+static int      debugColor;         /* present color of debug led */
 static int      ledBlockCount;      /* reference count of block calles */                            
 int sequoia_index_cache = -1;       /* set to silly value so that we dont cache on init */
 
@@ -191,6 +209,7 @@
     CLR(seqReg,LED_DEBUG_GREEN_BIT);
     sequoiaWrite(PMC_FOMPCR_REG, seqReg);
 
+    debugColor = LED_DEBUG_STATE_1;
     
     /* setup the biled info */
     ledColor = LED_BILED_GREEN;
@@ -198,6 +217,7 @@
     ledLastActive.tv_sec = 0;
     ledBlockCount = 0;
     callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL);
+    ledSetBiled(ledColor);
     /* 
     ** 
     ** setup the pins associated with the smart card reader *
@@ -516,13 +536,13 @@
     /* check if we are blocked */
     if(ledBlockCount)
     {
-        if(ledColor == LED_BILED_YELLOW)
+        if(ledColor & LED_BILED_YELLOW)
         {
-            ledSetBiled(LED_BILED_NONE);
+            ledSetBiled(LED_BILED_YELLOW_OFF);
         }
         else
         {
-            ledSetBiled(LED_BILED_YELLOW);
+            ledSetBiled(LED_BILED_YELLOW_ON);
         }
     }
 
@@ -530,22 +550,22 @@
     /* check if we have network activity */
     else if (timeSpan < LED_NET_ACTIVE)
     {
-        if(ledColor == LED_BILED_GREEN)
+        if(ledColor & LED_BILED_GREEN)
         {
-            ledSetBiled(LED_BILED_NONE);
+            ledSetBiled(LED_BILED_GREEN_OFF);
         }
         else
         {
-            ledSetBiled(LED_BILED_GREEN);
+            ledSetBiled(LED_BILED_GREEN_ON);
         }
     }
 
     /* normal operating mode */        
     else
     {
-        if(ledColor != LED_BILED_GREEN)
+        if(!(ledColor & LED_BILED_GREEN))
         {
-            ledSetBiled(LED_BILED_GREEN);
+            ledSetBiled(LED_BILED_GREEN_ON);
         }
     }
 
@@ -563,7 +583,6 @@
 
     savedints = disable_interrupts(I32_bit | F32_bit);
 #endif
-    ledColor = color;
 
 
     sequoiaRead (PMC_FOMPCR_REG, &seqReg);
@@ -572,21 +591,45 @@
         case LED_BILED_NONE:
             SET(seqReg,LED_BILED_YELLOW_BIT);
             SET(seqReg,LED_BILED_GREEN_BIT);
+            ledColor = color;
             break;
     
         case LED_BILED_YELLOW:
             CLR(seqReg,LED_BILED_YELLOW_BIT);
             SET(seqReg,LED_BILED_GREEN_BIT);
+            ledColor = color;
             break;
     
         case LED_BILED_GREEN:
             SET(seqReg,LED_BILED_YELLOW_BIT);
             CLR(seqReg,LED_BILED_GREEN_BIT);
+            ledColor = color;
             break;
     
         case LED_BILED_RED:
             CLR(seqReg,LED_BILED_YELLOW_BIT);
             CLR(seqReg,LED_BILED_GREEN_BIT);
+            ledColor = color;
+            break;
+    
+        case LED_BILED_YELLOW_ON:
+            CLR(seqReg,LED_BILED_YELLOW_BIT);
+            ledColor |= LED_BILED_YELLOW;
+            break;
+    
+        case LED_BILED_YELLOW_OFF:
+            SET(seqReg,LED_BILED_YELLOW_BIT);
+            ledColor &= ~LED_BILED_YELLOW;
+            break;
+    
+        case LED_BILED_GREEN_ON:
+            CLR(seqReg,LED_BILED_GREEN_BIT);
+            ledColor |= LED_BILED_GREEN;
+            break;
+    
+        case LED_BILED_GREEN_OFF:
+            SET(seqReg,LED_BILED_GREEN_BIT);
+            ledColor &= ~LED_BILED_GREEN;
             break;
     
         default:
@@ -688,37 +731,45 @@
         case LED_DEBUG_STATE_0:    
             CLR(seqReg,LED_DEBUG_YELLOW_BIT);
             CLR(seqReg,LED_DEBUG_GREEN_BIT);
+            debugColor = LED_DEBUG_STATE_0;
             break;
 
         case LED_DEBUG_STATE_1:
             SET(seqReg,LED_DEBUG_YELLOW_BIT);
             CLR(seqReg,LED_DEBUG_GREEN_BIT);
+            debugColor = LED_DEBUG_STATE_1;
             break;
 
         case LED_DEBUG_STATE_2:
             CLR(seqReg,LED_DEBUG_YELLOW_BIT);
             SET(seqReg,LED_DEBUG_GREEN_BIT);
+            debugColor = LED_DEBUG_STATE_2;
             break;
 
         case LED_DEBUG_STATE_3:
             SET(seqReg,LED_DEBUG_YELLOW_BIT);
             SET(seqReg,LED_DEBUG_GREEN_BIT);
+            debugColor = LED_DEBUG_STATE_3;
             break;
 
         case LED_DEBUG_YELLOW_ON:
             SET(seqReg,LED_DEBUG_YELLOW_BIT);
+            debugColor |= LED_DEBUG_STATE_1;
             break;
 
         case LED_DEBUG_YELLOW_OFF:
             CLR(seqReg,LED_DEBUG_YELLOW_BIT);
+            debugColor &= ~LED_DEBUG_STATE_1;
             break;
 
         case LED_DEBUG_GREEN_ON:
             SET(seqReg,LED_DEBUG_GREEN_BIT);
+            debugColor |= LED_DEBUG_STATE_2;
             break;
 
         case LED_DEBUG_GREEN_OFF:
             CLR(seqReg,LED_DEBUG_GREEN_BIT);
+            debugColor &= ~LED_DEBUG_STATE_2;
             break;
 
         default:
@@ -776,3 +827,180 @@
 #endif
 }
 
+#if NSHARKLED > 0
+int sequoiaGetLed(int led)
+{
+
+	if (led == SHARK_LED0_NUM) {
+		if (ledColor & LED_BILED_YELLOW)
+			return 1;
+		else
+			return 0;
+	}
+	if (led == SHARK_LED1_NUM) {
+		if (debugColor & LED_DEBUG_STATE_1)
+			return 1;
+		else
+			return 0;
+	}
+	return 0;
+}
+
+void sequoiaSetLed(int led, int val)
+{
+
+
+	if (led == SHARK_LED0_NUM) {
+		if (val)
+			ledSetBiled(LED_BILED_YELLOW_ON);
+		else
+			ledSetBiled(LED_BILED_YELLOW_OFF);
+	}
+	if (led == SHARK_LED1_NUM) {
+		if (val)
+			ledSetDebug(LED_DEBUG_YELLOW_ON);
+		else
+			ledSetDebug(LED_DEBUG_YELLOW_OFF);
+	}
+}
+#endif
+
+#if NSHARKIIC > 0
+void
+sequoiaBBSetBits(u_int32_t bits)
+{
+	u_int16_t  seqRegSDA, seqRegSCL;
+#ifdef SHARK
+	u_int savedints;
+
+	savedints = disable_interrupts(I32_bit | F32_bit);
+#endif
+
+	sequoiaRead(PMC_FOMPCR_REG, &seqRegSCL);
+	sequoiaRead(SEQR_SEQPSR2_REG, &seqRegSDA);
+
+	/*
+	 * For SCL and SDA:
+	 * - output is the inverse of the desired signal
+	 * - the pin enable bit drives the signal
+	 */
+	if (bits & SHARK_IIC_BIT_SCL) {
+		CLR(seqRegSCL, IIC_CLK);
+	}
+	if (!(bits & SHARK_IIC_BIT_SCL)) {
+		SET(seqRegSCL, IIC_CLK);
+	}
+
+	if (bits & SHARK_IIC_BIT_SDA) {
+		CLR(seqRegSDA, SEQPSR2_M_GPIOB1PINEN);
+	}
+	if (!(bits & SHARK_IIC_BIT_SDA)) {
+		SET(seqRegSDA, SEQPSR2_M_GPIOB1PINEN);
+	}
+
+	sequoiaWrite(PMC_FOMPCR_REG, seqRegSCL);
+	sequoiaWrite(SEQR_SEQPSR2_REG, seqRegSDA);
+#ifdef SHARK
+	restore_interrupts(savedints);
+#endif
+}
+
+void
+sequoiaBBSetDir(u_int32_t dir)
+{
+	u_int16_t  seqReg;
+#ifdef SHARK
+	u_int savedints;
+
+	savedints = disable_interrupts(I32_bit | F32_bit);
+#endif
+	
+	/*
+	 * For direction = Input, set SDA (Output) direction to input,
+	 * otherwise we'll only read our own signal on SDA (Input)
+	 */
+	sequoiaRead(PMC_GPIOCR2_REG, &seqReg);
+	if (dir & SHARK_IIC_BIT_OUTPUT)
+		SET(seqReg, IIC_DATA_OUT_DIR);
+	if (dir == SHARK_IIC_BIT_INPUT)
+		CLR(seqReg, IIC_DATA_OUT_DIR);
+	sequoiaWrite(PMC_GPIOCR2_REG, seqReg);
+
+#ifdef SHARK
+	restore_interrupts(savedints);
+#endif
+}
+
+u_int32_t
+sequoiaBBRead(void)
+{
+	u_int16_t  seqRegSDA, seqRegSCL;
+	u_int32_t  bits = 0;
+#ifdef SHARK
+	u_int savedints;
+
+	savedints = disable_interrupts(I32_bit | F32_bit);
+#endif
+	
+	sequoiaRead(SEQUOIA_1GPIO, &seqRegSDA);
+	sequoiaRead(PMC_FOMPCR_REG, &seqRegSCL);
+
+	if (ISSET(seqRegSDA, IIC_DATA_IN))
+		bits |= SHARK_IIC_BIT_SDA;
+	if (!ISSET(seqRegSCL, IIC_CLK))
+		bits |= SHARK_IIC_BIT_SCL;
+#ifdef SHARK
+	restore_interrupts(savedints);
+#endif
+	return bits;
+}
+
+void
+sequoiaBBInit(void)
+{
+	u_int16_t  seqReg;
+#ifdef SHARK
+	u_int savedints;
+
+	savedints = disable_interrupts(I32_bit | F32_bit);
+#endif
+
+	/*
+	 * SCL initialization
+	 * - enable pc[9]
+	 * - set pin to low (0)
+	 */
+	sequoiaRead(SEQR_SEQPSR3_REG, &seqReg);
+	CLR(seqReg, SEQPSR3_M_PC9PINEN);
+	sequoiaWrite(SEQR_SEQPSR3_REG, seqReg);
+	sequoiaRead(PMC_FOMPCR_REG, &seqReg);
+	SET(seqReg, IIC_CLK);
+	sequoiaWrite(PMC_FOMPCR_REG, seqReg);
+
+	/* SDA (Output) initialization
+	 * - set direction to output
+	 * - enable GPIO B1 (sets pin to low)
+	 */
+	sequoiaRead(PMC_GPIOCR2_REG, &seqReg);
+	SET(seqReg, IIC_DATA_OUT_DIR);
+	sequoiaWrite(PMC_GPIOCR2_REG, seqReg);
+	sequoiaRead(SEQR_SEQPSR2_REG, &seqReg);
+	SET(seqReg, SEQPSR2_M_GPIOB1PINEN);
+	sequoiaWrite(SEQR_SEQPSR2_REG, seqReg);
+
+	/* SDA (Input) initialization
+	 * - enable GPIO
+	 * - set direction to input
+	 */
+	sequoiaRead(SEQ2_SEQ2PSR_REG, &seqReg);
+	CLR(seqReg, SEQ2PSR_M_GPIOPINEN);
+	sequoiaWrite(SEQ2_SEQ2PSR_REG, seqReg);
+	sequoiaRead(SEQUOIA_1GPIO, &seqReg);
+	CLR(seqReg, IIC_DATA_IN_DIR);
+	sequoiaWrite(SEQUOIA_1GPIO, seqReg);
+
+#ifdef SHARK
+	restore_interrupts(savedints);
+#endif
+}
+#endif
Index: src/sys/arch/shark/shark/sequoia.h
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/shark/sequoia.h,v
retrieving revision 1.4
diff -u -r1.4 sequoia.h
--- src/sys/arch/shark/shark/sequoia.h	22 Aug 2017 21:23:58 -0000	1.4
+++ src/sys/arch/shark/shark/sequoia.h	21 Apr 2021 07:09:14 -0000
@@ -33,6 +33,9 @@
  *    even if advised of the possibility of such damage.
  */
 
+#include "sharkled.h"
+#include "sharkiic.h"
+
 /*
 **
 **  MODULE DESCRIPTION:
@@ -5067,6 +5070,31 @@
 void sequoiaWrite(int reg,u_int16_t value);     
 void sequoiaRead(int reg,u_int16_t * value_ptr);     
 
+/* LED functions */
+#if NSHARKLED > 0
+#define SHARK_LED_NAME	"shark_led"
+#define SHARK_LED0_NUM		0
+#define SHARK_LED1_NUM		1
+#define SHARK_LED0_NAME		"front"
+#define SHARK_LED1_NAME		"debug"
+#define SHARK_LED_NUMLED	2
+int  sequoiaGetLed(int led);
+void sequoiaSetLed(int led, int val);
+#endif
+
+/* IIC functions */
+#if NSHARKIIC > 0
+#define SHARK_IIC_NAME	"shark_iic"
+#define SHARK_IIC_BIT_SDA	0x01
+#define SHARK_IIC_BIT_SCL	0x02
+#define SHARK_IIC_BIT_OUTPUT	0x04
+#define SHARK_IIC_BIT_INPUT	0x08
+void     sequoiaBBSetBits(u_int32_t bits);
+void     sequoiaBBSetDir(u_int32_t dir);
+u_int32_t sequoiaBBRead(void);
+void sequoiaBBInit(void);
+#endif
+
 /* x console functions */
 void    consXTvOn(void);
 void    consXTvOff(void);
Index: src/sys/arch/shark/shark/shark_iic.c
===================================================================
RCS file: src/sys/arch/shark/shark/shark_iic.c
diff -N src/sys/arch/shark/shark/shark_iic.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/sys/arch/shark/shark/shark_iic.c	21 Apr 2021 07:09:14 -0000
@@ -0,0 +1,170 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2021 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julian Coleman.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/isa/isavar.h>
+#include <dev/ofisa/ofisavar.h>
+
+#include <shark/shark/sequoia.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/i2c_bitbang.h>
+#include <dev/i2c/ddcvar.h>
+
+struct sharkiic_softc {
+	device_t	sc_dev;
+	struct		i2c_controller sc_i2c;
+};
+
+/* I2C glue */
+static int sharkiic_send_start(void *, int);
+static int sharkiic_send_stop(void *, int);
+static int sharkiic_initiate_xfer(void *, i2c_addr_t, int);
+static int sharkiic_read_byte(void *, uint8_t *, int);
+static int sharkiic_write_byte(void *, uint8_t, int);
+
+/* I2C bitbang glue */
+static void sharkiicbb_set_bits(void *, uint32_t);
+static void sharkiicbb_set_dir(void *, uint32_t);
+static uint32_t sharkiicbb_read(void *);
+
+static const struct i2c_bitbang_ops sharkiicbb_ops = {
+	sharkiicbb_set_bits,
+	sharkiicbb_set_dir,
+	sharkiicbb_read,
+	{
+		SHARK_IIC_BIT_SDA,
+		SHARK_IIC_BIT_SCL,
+		SHARK_IIC_BIT_OUTPUT,
+		SHARK_IIC_BIT_INPUT
+	}
+};
+
+static int sharkiic_match(device_t, cfdata_t, void *);
+static void sharkiic_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(sharkiic, sizeof(struct sharkiic_softc),
+        sharkiic_match, sharkiic_attach, NULL, NULL);
+
+static int 
+sharkiic_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct ofisa_attach_args *ia = aux;
+
+	if (device_is_a(parent, "ofisa") &&
+	    !strcmp(ia->oba.oba_ofname, SHARK_IIC_NAME))
+		return 1;
+	else
+		return 0;
+}
+
+static void
+sharkiic_attach(device_t parent, device_t self, void *aux)
+{
+	struct sharkiic_softc *sc = device_private(self);
+	struct i2cbus_attach_args iba;
+
+	printf("\n");
+	sequoiaBBInit();
+	iic_tag_init(&sc->sc_i2c);
+	sc->sc_i2c.ic_cookie = sc;
+	sc->sc_i2c.ic_send_start = sharkiic_send_start;
+	sc->sc_i2c.ic_send_stop = sharkiic_send_stop;
+	sc->sc_i2c.ic_initiate_xfer = sharkiic_initiate_xfer;
+	sc->sc_i2c.ic_read_byte = sharkiic_read_byte;
+	sc->sc_i2c.ic_write_byte = sharkiic_write_byte;
+
+	memset(&iba, 0, sizeof(iba));
+	iba.iba_tag = &sc->sc_i2c;
+
+	/* Child devices are discovered by iic_search() */
+	config_found_ia(self, "i2cbus", &iba, iicbus_print);
+
+}
+
+/* I2C bitbanging */
+static void
+sharkiicbb_set_bits(void *cookie, uint32_t bits)
+{
+	sequoiaBBSetBits(bits);
+}
+
+static void
+sharkiicbb_set_dir(void *cookie, uint32_t dir)
+{
+	sequoiaBBSetDir(dir);
+}
+
+static uint32_t
+sharkiicbb_read(void *cookie)
+{
+	return sequoiaBBRead();
+}
+
+/* higher level I2C stuff */
+static int
+sharkiic_send_start(void *cookie, int flags)
+{
+	return (i2c_bitbang_send_start(cookie, flags, &sharkiicbb_ops));
+}
+
+static int
+sharkiic_send_stop(void *cookie, int flags)
+{
+	return (i2c_bitbang_send_stop(cookie, flags, &sharkiicbb_ops));
+}
+
+static int
+sharkiic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
+{
+	return (i2c_bitbang_initiate_xfer(cookie, addr, flags, 
+	    &sharkiicbb_ops));
+}
+
+static int
+sharkiic_read_byte(void *cookie, uint8_t *valp, int flags)
+{
+	return (i2c_bitbang_read_byte(cookie, valp, flags, &sharkiicbb_ops));
+}
+
+static int
+sharkiic_write_byte(void *cookie, uint8_t val, int flags)
+{
+	return (i2c_bitbang_write_byte(cookie, val, flags, &sharkiicbb_ops));
+}
Index: src/sys/arch/shark/shark/shark_led.c
===================================================================
RCS file: src/sys/arch/shark/shark/shark_led.c
diff -N src/sys/arch/shark/shark/shark_led.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/sys/arch/shark/shark/shark_led.c	21 Apr 2021 07:09:14 -0000
@@ -0,0 +1,114 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2021 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julian Coleman.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/isa/isavar.h>
+#include <dev/ofisa/ofisavar.h>
+
+#include <shark/shark/sequoia.h>
+
+#include <dev/led.h>
+
+struct sharkled_led {
+	void *cookie;
+	struct led_device *led;
+	int num;
+};
+
+struct sharkled_softc {
+	device_t		sc_dev;
+	struct sharkled_led	sc_leds[SHARK_LED_NUMLED];
+};
+
+static int sharkled_match(device_t, cfdata_t, void *);
+static void sharkled_attach(device_t, device_t, void *);
+int sharkled_get_led(void *cookie);
+void sharkled_set_led(void *cookie, int val);
+
+CFATTACH_DECL_NEW(sharkled, sizeof(struct sharkled_softc),
+        sharkled_match, sharkled_attach, NULL, NULL);
+
+static int 
+sharkled_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct ofisa_attach_args *ia = aux;
+
+	if (device_is_a(parent, "ofisa") &&
+	    !strcmp(ia->oba.oba_ofname, SHARK_LED_NAME))
+		return 1;
+	else
+		return 0;
+}
+
+static void
+sharkled_attach(device_t parent, device_t self, void *aux)
+{
+	struct sharkled_softc *sc = device_private(self);
+	struct sharkled_led *l;
+
+	sc->sc_dev = self;
+	aprint_normal(": %s, %s\n", SHARK_LED0_NAME,
+		SHARK_LED1_NAME);
+	
+	l = &sc->sc_leds[0];
+	l->cookie = sc;
+	l->num = SHARK_LED0_NUM;
+	led_attach(SHARK_LED0_NAME, l, sharkled_get_led, sharkled_set_led);
+	
+	l = &sc->sc_leds[1];
+	l->cookie = sc;
+	l->num = SHARK_LED1_NUM;
+	led_attach(SHARK_LED1_NAME, l, sharkled_get_led, sharkled_set_led);
+}
+
+int
+sharkled_get_led(void *cookie)
+{
+	struct sharkled_led *l = cookie;
+
+	return sequoiaGetLed(l->num);
+}
+
+void
+sharkled_set_led(void *cookie, int val)
+{
+	struct sharkled_led *l = cookie;
+
+	return sequoiaSetLed(l->num, val);
+}
Index: src/sys/arch/shark/shark/shark_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/shark/shark_machdep.c,v
retrieving revision 1.46
diff -u -r1.46 shark_machdep.c
--- src/sys/arch/shark/shark/shark_machdep.c	16 Jul 2019 14:41:49 -0000	1.46
+++ src/sys/arch/shark/shark/shark_machdep.c	21 Apr 2021 07:09:14 -0000
@@ -147,6 +147,10 @@
 CFATTACH_DECL_NEW(ofbus_root, 0,
     ofbus_match, ofbus_attach, NULL, NULL);
 
+#if NSHARKLED > 0 || NSHARKIIC > 0
+static void add_sequoia_devices(device_t busdev);
+#endif
+
 /*
  *  Exported routines
  */
@@ -412,6 +416,11 @@
 
 	if (device_is_a(dev, "ofbus") || device_is_a(dev, "ofisa")) {
 		oba = aux;
+#if NSHARKLED > 0 || NSHARKIIC > 0
+		if (device_is_a(dev, "ofisa") && \
+		    device_is_a(device_parent(dev), "ofbus"))
+			add_sequoia_devices(dev);
+#endif
 	} else if (parent == NULL) {
 		return;
 	} else if (parent == device_parent(dev)
@@ -470,3 +479,33 @@
 		}
 	}
 }
+
+#if NSHARKLED > 0 || NSHARKIIC > 0
+/* Add devices connected to the Sequoia chip, but not in the OFW tree */
+static void
+add_sequoia_devices(device_t busdev)
+{
+	prop_dictionary_t props = device_properties(busdev);
+	prop_array_t cfg;
+	prop_dictionary_t dev;
+
+	cfg = prop_array_create();
+	prop_dictionary_set(props, "ofisa-child-devices", cfg);
+
+#if NSHARKLED > 0
+	dev = prop_dictionary_create();
+	prop_dictionary_set_string(dev, "name", SHARK_LED_NAME);
+	prop_array_add(cfg, dev);
+	prop_object_release(dev);
+#endif
+
+#if NSHARKIIC > 0
+	dev = prop_dictionary_create();
+	prop_dictionary_set_string(dev, "name", SHARK_IIC_NAME);
+	prop_array_add(cfg, dev);
+	prop_object_release(dev);
+#endif
+
+	prop_object_release(cfg);
+}
+#endif


Home | Main Index | Thread Index | Old Index