diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 1088ca6c8b..37c6c159c5 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -40,7 +40,7 @@ case "$LINUX" in PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET imx6-status-led imx6-soc-fan" ;; *) - PKG_VERSION="4.1.12" + PKG_VERSION="4.3" PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/$PKG_NAME-$PKG_VERSION.tar.xz" ;; esac diff --git a/packages/linux/patches/4.1.12/linux-224-STK1160-addFramescaling.patch b/packages/linux/patches/4.1.12/linux-224-STK1160-addFramescaling.patch deleted file mode 100644 index 2b6f59c9a0..0000000000 --- a/packages/linux/patches/4.1.12/linux-224-STK1160-addFramescaling.patch +++ /dev/null @@ -1,284 +0,0 @@ -From edf8977b62ae86859cccf3d0ea4883333ea4d138 Mon Sep 17 00:00:00 2001 -From: Dale Hamel -Date: Tue, 24 Feb 2015 10:31:04 -0500 -Subject: [PATCH] Add framescaling support to stk1160 - -Implements frame scaling support for stk1160 to support format changes instead of a static frame size. - -This is effectively a dumb sampling, and could perhaps benefit from being an averaging instead. - -This was a requested "TO DO" for this driver, and allows support for userspace programs like Hyperion and Boblight. - -Submitted on behalf of the original author, Michael Stegemann ---- - drivers/media/usb/stk1160/stk1160-core.c | 1 + - drivers/media/usb/stk1160/stk1160-reg.h | 26 +++++++ - drivers/media/usb/stk1160/stk1160-v4l.c | 112 +++++++++++++++++++++++------- - drivers/media/usb/stk1160/stk1160-video.c | 17 ++++- - drivers/media/usb/stk1160/stk1160.h | 1 + - 5 files changed, 130 insertions(+), 27 deletions(-) - -diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c -index 03504dc..1881770 100644 ---- a/drivers/media/usb/stk1160/stk1160-core.c -+++ b/drivers/media/usb/stk1160/stk1160-core.c -@@ -418,6 +418,7 @@ static void stk1160_disconnect(struct usb_interface *interface) - stk1160_ac97_unregister(dev); - - stk1160_clear_queue(dev); -+ vb2_queue_release(&dev->vb_vidq); - - video_unregister_device(&dev->vdev); - v4l2_device_disconnect(&dev->v4l2_dev); -diff --git a/drivers/media/usb/stk1160/stk1160-reg.h b/drivers/media/usb/stk1160/stk1160-reg.h -index 3e49da6..b1fa11d 100644 ---- a/drivers/media/usb/stk1160/stk1160-reg.h -+++ b/drivers/media/usb/stk1160/stk1160-reg.h -@@ -33,6 +33,32 @@ - */ - #define STK1160_DCTRL 0x100 - -+/* -+ * Decimation Control Register: -+ * Byte 104: -+ * Horizontal Decimation Line Unit Count -+ * Byte 105: -+ * Vertical Decimation Line Unit Count -+ * Byte 106: -+ * Bit 0 - Horizontal Decimation Control -+ * 0 Horizontal decimation is disabled. -+ * 1 Horizontal decimation is enabled. -+ * Bit 1 - Decimates Half or More Column -+ * 0 Decimates less than half from original column, -+ * -> send count unit (0x105) before each unit skipped. -+ * 1 Decimates half or more from original column, -+ * -> skip count unit (0x105) before each unit sent. -+ * Bit 2 - Vertical Decimation Control -+ * see Bit 0, only vertical -+ * Bit 3 - Vertical Greater or Equal to Half -+ * see Bit 1, only vertical -+ * Bit 4 - Decimation Unit -+ * 0 Decimation will work with 2 rows or columns per unit. -+ * 1 Decimation will work with 4 rows or columns per unit. -+ */ -+#define STK1160_DMCTRL 0x104 -+ -+ - /* Capture Frame Start Position */ - #define STK116_CFSPO 0x110 - #define STK116_CFSPO_STX_L 0x110 -diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c -index 65a326c..94dafeb 100644 ---- a/drivers/media/usb/stk1160/stk1160-v4l.c -+++ b/drivers/media/usb/stk1160/stk1160-v4l.c -@@ -106,6 +106,76 @@ static void stk1160_set_std(struct stk1160 *dev) - - } - -+static void stk1160_try_fmt(struct stk1160 *dev, struct v4l2_format *f, bool try) -+{ -+ int base_width, base_height; -+ -+ if (dev->norm & V4L2_STD_525_60){ -+ base_width = 720; -+ base_height = 480; -+ } else { -+ base_width = 720; -+ base_height = 576; -+ } -+ -+ if (f->fmt.pix.width <= (base_width / 3) -+ || f->fmt.pix.height <= (base_height / 3)){ -+ f->fmt.pix.width = base_width / 3; -+ f->fmt.pix.height = base_height / 3; -+ if (!try){ -+ dev->decimate = 3; -+ } -+ } else if ((f->fmt.pix.width >= base_width >> 1 -+ && f->fmt.pix.width < base_width) -+ ||((f->fmt.pix.height >= base_height >> 1 -+ && f->fmt.pix.height < base_height))){ -+ f->fmt.pix.width = base_width >> 1; -+ f->fmt.pix.height = base_height >> 1; -+ if (!try){ -+ dev->decimate = 2; -+ } -+ } else { -+ f->fmt.pix.width = base_width; -+ f->fmt.pix.height = base_height; -+ if (!try){ -+ dev->decimate = 0; -+ } -+ } -+} -+ -+static void stk1160_set_fmt(struct stk1160 *dev) -+{ -+ if (dev->norm & V4L2_STD_525_60){ -+ dev->width = 720; -+ dev->height = 480; -+ } else { -+ dev->width = 720; -+ dev->height = 576; -+ } -+ -+ switch (dev->decimate){ -+ case 0: -+ stk1160_write_reg(dev, STK1160_DMCTRL, 0x00); -+ stk1160_write_reg(dev, STK1160_DMCTRL+1, 0x00); -+ stk1160_write_reg(dev, STK1160_DMCTRL+2, 0x00); -+ break; -+ case 2: -+ stk1160_write_reg(dev, STK1160_DMCTRL, 0x01); -+ stk1160_write_reg(dev, STK1160_DMCTRL+1, 0x01); -+ stk1160_write_reg(dev, STK1160_DMCTRL+2, 0x1f); -+ dev->width = dev->width >> 1; -+ dev->height = dev->height >> 1; -+ break; -+ case 3: -+ stk1160_write_reg(dev, STK1160_DMCTRL, 0x02); -+ stk1160_write_reg(dev, STK1160_DMCTRL+1, 0x02); -+ stk1160_write_reg(dev, STK1160_DMCTRL+2, 0x1f); -+ dev->width = dev->width / 3; -+ dev->height = dev->height / 3; -+ break; -+ } -+} -+ - /* - * Set a new alternate setting. - * Returns true is dev->max_pkt_size has changed, false otherwise. -@@ -321,17 +391,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - { - struct stk1160 *dev = video_drvdata(file); - -- /* -- * User can't choose size at his own will, -- * so we just return him the current size chosen -- * at standard selection. -- * TODO: Implement frame scaling? -- */ -+ stk1160_try_fmt(dev, f, true); - -- f->fmt.pix.pixelformat = dev->fmt->fourcc; -- f->fmt.pix.width = dev->width; -- f->fmt.pix.height = dev->height; - f->fmt.pix.field = V4L2_FIELD_INTERLACED; -+ f->fmt.pix.pixelformat = dev->fmt->fourcc; - f->fmt.pix.bytesperline = dev->width * 2; - f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; -@@ -348,9 +411,14 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - if (vb2_is_busy(q)) - return -EBUSY; - -- vidioc_try_fmt_vid_cap(file, priv, f); -+ stk1160_try_fmt(dev, f, false); -+ stk1160_set_fmt(dev); - -- /* We don't support any format changes */ -+ f->fmt.pix.field = V4L2_FIELD_INTERLACED; -+ f->fmt.pix.pixelformat = dev->fmt->fourcc; -+ f->fmt.pix.bytesperline = dev->width * 2; -+ f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline; -+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - - return 0; - } -@@ -389,23 +457,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) - dev->norm = norm; - - /* This is taken from saa7115 video decoder */ -- if (dev->norm & V4L2_STD_525_60) { -- dev->width = 720; -- dev->height = 480; -- } else if (dev->norm & V4L2_STD_625_50) { -- dev->width = 720; -- dev->height = 576; -+ if (dev->norm & V4L2_STD_525_60 || dev->norm & V4L2_STD_625_50) { -+ stk1160_set_std(dev); -+ stk1160_set_fmt(dev); -+ -+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, -+ dev->norm); -+ -+ return 0; - } else { - stk1160_err("invalid standard\n"); - return -EINVAL; - } -- -- stk1160_set_std(dev); -- -- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, -- dev->norm); -- -- return 0; - } - - -@@ -671,6 +734,7 @@ int stk1160_video_register(struct stk1160 *dev) - dev->norm = V4L2_STD_NTSC_M; - dev->width = 720; - dev->height = 480; -+ dev->decimate = 0; - - /* set default format */ - dev->fmt = &format[0]; -diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c -index 39f1aae..5a55028 100644 ---- a/drivers/media/usb/stk1160/stk1160-video.c -+++ b/drivers/media/usb/stk1160/stk1160-video.c -@@ -84,7 +84,6 @@ struct stk1160_buffer *stk1160_next_buffer(struct stk1160 *dev) - if (!list_empty(&dev->avail_bufs)) { - buf = list_first_entry(&dev->avail_bufs, - struct stk1160_buffer, list); -- list_del(&buf->list); - } - spin_unlock_irqrestore(&dev->buf_lock, flags); - -@@ -95,7 +94,7 @@ static inline - void stk1160_buffer_done(struct stk1160 *dev) - { - struct stk1160_buffer *buf = dev->isoc_ctl.buf; -- -+ unsigned long flags = 0; - dev->field_count++; - - buf->vb.v4l2_buf.sequence = dev->field_count >> 1; -@@ -104,7 +103,19 @@ void stk1160_buffer_done(struct stk1160 *dev) - v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); - - vb2_set_plane_payload(&buf->vb, 0, buf->bytesused); -- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); -+ -+ spin_lock_irqsave(&dev->buf_lock, flags); -+ if (buf->bytesused == vb2_plane_size(&buf->vb, 0)) -+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); -+ else -+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); -+ -+ if (!list_empty(&dev->avail_bufs)) { -+ list_del(&buf->list); -+ } -+ -+ spin_unlock_irqrestore(&dev->buf_lock, flags); -+ - - dev->isoc_ctl.buf = NULL; - } -diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h -index abdea48..895ed35 100644 ---- a/drivers/media/usb/stk1160/stk1160.h -+++ b/drivers/media/usb/stk1160/stk1160.h -@@ -150,6 +150,7 @@ struct stk1160 { - unsigned int ctl_input; /* selected input */ - v4l2_std_id norm; /* current norm */ - struct stk1160_fmt *fmt; /* selected format */ -+ int decimate; - - unsigned int field_count; /* not sure ??? */ - enum v4l2_field field; /* also not sure :/ */ --- -2.1.1 - diff --git a/packages/linux/patches/4.1.12/linux-228-fix-tt-s2-4600.patch b/packages/linux/patches/4.1.12/linux-228-fix-tt-s2-4600.patch deleted file mode 100644 index b3ab7ad94c..0000000000 --- a/packages/linux/patches/4.1.12/linux-228-fix-tt-s2-4600.patch +++ /dev/null @@ -1,63 +0,0 @@ -diff -urN a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c ---- a/drivers/media/usb/dvb-usb/dw2102.c 2015-06-22 08:05:43.000000000 +0300 -+++ b/drivers/media/usb/dvb-usb/dw2102.c 2015-06-24 14:36:13.236830491 +0300 -@@ -117,8 +117,13 @@ - - struct dw2102_state { - u8 initialized; -+ u8 last_lock; - struct i2c_client *i2c_client_tuner; -+ -+ /* fe hook functions*/ - int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); -+ int (*fe_read_status)(struct dvb_frontend *fe, -+ fe_status_t *status); - }; - - /* debug */ -@@ -928,8 +933,6 @@ - break; - else - mac[i] = ibuf[0]; -- -- debug_dump(mac, 6, printk); - } - - return 0; -@@ -1001,6 +1004,23 @@ - i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); - } - -+static int tt_s2_4600_read_status(struct dvb_frontend *fe, fe_status_t *status) -+{ -+ struct dvb_usb_adapter *d = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; -+ int ret; -+ -+ ret = st->fe_read_status(fe, status); -+ -+ /* resync slave fifo when signal change from unlock to lock */ -+ if ((*status & FE_HAS_LOCK) && (!st->last_lock)) -+ su3000_streaming_ctrl(d, 1); -+ -+ st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; -+ return ret; -+} -+ - static struct stv0299_config sharp_z0194a_config = { - .demod_address = 0x68, - .inittab = sharp_z0194a_inittab, -@@ -1553,6 +1573,12 @@ - - state->i2c_client_tuner = client; - -+ /* hook fe: need to resync the slave fifo when signal locks */ -+ state->fe_read_status = adap->fe_adap[0].fe->ops.read_status; -+ adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status; -+ -+ state->last_lock = 0; -+ - return 0; - } - diff --git a/packages/linux/patches/4.1.12/linux-229-hauppauge-hvr-2205-and-2255.patch b/packages/linux/patches/4.1.12/linux-229-hauppauge-hvr-2205-and-2255.patch deleted file mode 100644 index eff856b98f..0000000000 --- a/packages/linux/patches/4.1.12/linux-229-hauppauge-hvr-2205-and-2255.patch +++ /dev/null @@ -1,590 +0,0 @@ -diff -urN a/drivers/media/pci/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c ---- a/drivers/media/pci/saa7164/saa7164-cards.c 2015-06-22 08:05:43.000000000 +0300 -+++ b/drivers/media/pci/saa7164/saa7164-cards.c 2015-06-24 18:39:26.842373718 +0300 -@@ -30,6 +30,7 @@ - * attached I2C devices, so we can simplify the virtual i2c mechansms - * and keep the -i2c.c implementation clean. - */ -+#define REGLEN_0bit 0 - #define REGLEN_8bit 1 - #define REGLEN_16bit 2 - -@@ -499,6 +500,144 @@ - .i2c_reg_len = REGLEN_8bit, - } }, - }, -+ [SAA7164_BOARD_HAUPPAUGE_HVR2255proto] = { -+ .name = "Hauppauge WinTV-HVR2255(proto)", -+ .porta = SAA7164_MPEG_DVB, -+ .portb = SAA7164_MPEG_DVB, -+ .portc = SAA7164_MPEG_ENCODER, -+ .portd = SAA7164_MPEG_ENCODER, -+ .porte = SAA7164_MPEG_VBI, -+ .portf = SAA7164_MPEG_VBI, -+ .chiprev = SAA7164_CHIP_REV3, -+ .unit = {{ -+ .id = 0x27, -+ .type = SAA7164_UNIT_EEPROM, -+ .name = "4K EEPROM", -+ .i2c_bus_nr = SAA7164_I2C_BUS_0, -+ .i2c_bus_addr = 0xa0 >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ }, { -+ .id = 0x04, -+ .type = SAA7164_UNIT_TUNER, -+ .name = "SI2157-1", -+ .i2c_bus_nr = SAA7164_I2C_BUS_0, -+ .i2c_bus_addr = 0xc0 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x06, -+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, -+ .name = "LGDT3306", -+ .i2c_bus_nr = SAA7164_I2C_BUS_2, -+ .i2c_bus_addr = 0xb2 >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ }, { -+ .id = 0x24, -+ .type = SAA7164_UNIT_TUNER, -+ .name = "SI2157-2", -+ .i2c_bus_nr = SAA7164_I2C_BUS_1, -+ .i2c_bus_addr = 0xc0 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x26, -+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, -+ .name = "LGDT3306-2", -+ .i2c_bus_nr = SAA7164_I2C_BUS_2, -+ .i2c_bus_addr = 0x1c >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ } }, -+ }, -+ [SAA7164_BOARD_HAUPPAUGE_HVR2255] = { -+ .name = "Hauppauge WinTV-HVR2255", -+ .porta = SAA7164_MPEG_DVB, -+ .portb = SAA7164_MPEG_DVB, -+ .portc = SAA7164_MPEG_ENCODER, -+ .portd = SAA7164_MPEG_ENCODER, -+ .porte = SAA7164_MPEG_VBI, -+ .portf = SAA7164_MPEG_VBI, -+ .chiprev = SAA7164_CHIP_REV3, -+ .unit = {{ -+ .id = 0x28, -+ .type = SAA7164_UNIT_EEPROM, -+ .name = "4K EEPROM", -+ .i2c_bus_nr = SAA7164_I2C_BUS_0, -+ .i2c_bus_addr = 0xa0 >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ }, { -+ .id = 0x04, -+ .type = SAA7164_UNIT_TUNER, -+ .name = "SI2157-1", -+ .i2c_bus_nr = SAA7164_I2C_BUS_0, -+ .i2c_bus_addr = 0xc0 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x06, -+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, -+ .name = "LGDT3306-1", -+ .i2c_bus_nr = SAA7164_I2C_BUS_2, -+ .i2c_bus_addr = 0xb2 >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ }, { -+ .id = 0x25, -+ .type = SAA7164_UNIT_TUNER, -+ .name = "SI2157-2", -+ .i2c_bus_nr = SAA7164_I2C_BUS_1, -+ .i2c_bus_addr = 0xc0 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x27, -+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, -+ .name = "LGDT3306-2", -+ .i2c_bus_nr = SAA7164_I2C_BUS_2, -+ .i2c_bus_addr = 0x1c >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ } }, -+ }, -+ [SAA7164_BOARD_HAUPPAUGE_HVR2205] = { -+ .name = "Hauppauge WinTV-HVR2205", -+ .porta = SAA7164_MPEG_DVB, -+ .portb = SAA7164_MPEG_DVB, -+ .portc = SAA7164_MPEG_ENCODER, -+ .portd = SAA7164_MPEG_ENCODER, -+ .porte = SAA7164_MPEG_VBI, -+ .portf = SAA7164_MPEG_VBI, -+ .chiprev = SAA7164_CHIP_REV3, -+ .unit = {{ -+ .id = 0x28, -+ .type = SAA7164_UNIT_EEPROM, -+ .name = "4K EEPROM", -+ .i2c_bus_nr = SAA7164_I2C_BUS_0, -+ .i2c_bus_addr = 0xa0 >> 1, -+ .i2c_reg_len = REGLEN_8bit, -+ }, { -+ .id = 0x04, -+ .type = SAA7164_UNIT_TUNER, -+ .name = "SI2157-1", -+ .i2c_bus_nr = SAA7164_I2C_BUS_0, -+ .i2c_bus_addr = 0xc0 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x06, -+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, -+ .name = "SI2168-1", -+ .i2c_bus_nr = SAA7164_I2C_BUS_2, -+ .i2c_bus_addr = 0xc8 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x25, -+ .type = SAA7164_UNIT_TUNER, -+ .name = "SI2157-2", -+ .i2c_bus_nr = SAA7164_I2C_BUS_1, -+ .i2c_bus_addr = 0xc0 >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ }, { -+ .id = 0x27, -+ .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, -+ .name = "SI2168-2", -+ .i2c_bus_nr = SAA7164_I2C_BUS_2, -+ .i2c_bus_addr = 0xcc >> 1, -+ .i2c_reg_len = REGLEN_0bit, -+ } }, -+ }, - }; - const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards); - -@@ -546,6 +685,21 @@ - .subvendor = 0x0070, - .subdevice = 0x8953, - .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_5, -+ }, { -+ .subvendor = 0x0070, -+ .subdevice = 0xf111, -+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2255, -+ /* Prototype card left here for documenation purposes. -+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2255proto, -+ */ -+ }, { -+ .subvendor = 0x0070, -+ .subdevice = 0xf123, -+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2205, -+ }, { -+ .subvendor = 0x0070, -+ .subdevice = 0xf120, -+ .card = SAA7164_BOARD_HAUPPAUGE_HVR2205, - }, - }; - const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); -@@ -594,12 +748,26 @@ - case SAA7164_BOARD_HAUPPAUGE_HVR2250: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2255: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2205: - /* -+ HVR2200 / HVR2250 - GPIO 2: s5h1411 / tda10048-1 demod reset - GPIO 3: s5h1411 / tda10048-2 demod reset - GPIO 7: IRBlaster Zilog reset - */ - -+ /* HVR2255 -+ * GPIO 2: lgdg3306-1 demod reset -+ * GPIO 3: lgdt3306-2 demod reset -+ */ -+ -+ /* HVR2205 -+ * GPIO 2: si2168-1 demod reset -+ * GPIO 3: si2168-2 demod reset -+ */ -+ - /* Reset parts by going in and out of reset */ - saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); - saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); -@@ -647,6 +815,21 @@ - /* WinTV-HVR2200 (PCIe, Retail, half-height) - * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ - break; -+ case 151009: -+ /* First production board rev B2I6 */ -+ /* WinTV-HVR2205 (PCIe, Retail, full-height bracket) -+ * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */ -+ break; -+ case 151609: -+ /* First production board rev B2I6 */ -+ /* WinTV-HVR2205 (PCIe, Retail, half-height bracket) -+ * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */ -+ break; -+ case 151061: -+ /* First production board rev B1I6 */ -+ /* WinTV-HVR2255 (PCIe, Retail, full-height bracket) -+ * ATSC/QAM (SI2157/LGDT3306) and basic analog, FM */ -+ break; - default: - printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n", - dev->name, tv.model); -@@ -676,6 +859,9 @@ - case SAA7164_BOARD_HAUPPAUGE_HVR2250: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: - case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2255: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2205: - hauppauge_eeprom(dev, &eeprom[0]); - break; - } -diff -urN a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c ---- a/drivers/media/pci/saa7164/saa7164-dvb.c 2015-06-22 08:05:43.000000000 +0300 -+++ b/drivers/media/pci/saa7164/saa7164-dvb.c 2015-06-24 18:42:30.090377859 +0300 -@@ -24,6 +24,9 @@ - #include "tda10048.h" - #include "tda18271.h" - #include "s5h1411.h" -+#include "si2157.h" -+#include "si2168.h" -+#include "lgdt3306a.h" - - #define DRIVER_NAME "saa7164" - -@@ -82,6 +85,64 @@ - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, - }; - -+static struct lgdt3306a_config hauppauge_hvr2255a_config = { -+ .i2c_addr = 0xb2 >> 1, -+ .qam_if_khz = 4000, -+ .vsb_if_khz = 3250, -+ .deny_i2c_rptr = 1, /* Disabled */ -+ .spectral_inversion = 0, /* Disabled */ -+ .mpeg_mode = LGDT3306A_MPEG_SERIAL, -+ .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, -+ .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, -+ .xtalMHz = 25, /* 24 or 25 */ -+}; -+ -+static struct lgdt3306a_config hauppauge_hvr2255b_config = { -+ .i2c_addr = 0x1c >> 1, -+ .qam_if_khz = 4000, -+ .vsb_if_khz = 3250, -+ .deny_i2c_rptr = 1, /* Disabled */ -+ .spectral_inversion = 0, /* Disabled */ -+ .mpeg_mode = LGDT3306A_MPEG_SERIAL, -+ .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, -+ .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, -+ .xtalMHz = 25, /* 24 or 25 */ -+}; -+ -+static struct si2157_config hauppauge_hvr2255_tuner_config = { -+ .inversion = 1, -+}; -+ -+static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter, -+ struct dvb_frontend *fe, u8 addr8bit, struct si2157_config *cfg) -+{ -+ struct i2c_board_info bi; -+ struct i2c_client *tuner; -+ -+ cfg->fe = fe; -+ -+ memset(&bi, 0, sizeof(bi)); -+ -+ strlcpy(bi.type, "si2157", I2C_NAME_SIZE); -+ bi.platform_data = cfg; -+ bi.addr = addr8bit >> 1; -+ -+ request_module(bi.type); -+ -+ tuner = i2c_new_device(adapter, &bi); -+ if (tuner == NULL || tuner->dev.driver == NULL) -+ return -ENODEV; -+ -+ if (!try_module_get(tuner->dev.driver->owner)) { -+ i2c_unregister_device(tuner); -+ return -ENODEV; -+ } -+ -+ port->i2c_client_tuner = tuner; -+ -+ return 0; -+} -+ - static int saa7164_dvb_stop_port(struct saa7164_port *port) - { - struct saa7164_dev *dev = port->dev; -@@ -242,14 +303,16 @@ - if (!demux->dmx.frontend) - return -EINVAL; - -- mutex_lock(&dvb->lock); -- if (dvb->feeding++ == 0) { -- /* Start transport */ -- ret = saa7164_dvb_start_port(port); -- } -- mutex_unlock(&dvb->lock); -- dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", -- __func__, port->nr, dvb->feeding); -+ if (dvb) { -+ mutex_lock(&dvb->lock); -+ if (dvb->feeding++ == 0) { -+ /* Start transport */ -+ ret = saa7164_dvb_start_port(port); -+ } -+ mutex_unlock(&dvb->lock); -+ dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", -+ __func__, port->nr, dvb->feeding); -+ } - - return ret; - } -@@ -264,14 +327,16 @@ - - dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - -- mutex_lock(&dvb->lock); -- if (--dvb->feeding == 0) { -- /* Stop transport */ -- ret = saa7164_dvb_stop_streaming(port); -- } -- mutex_unlock(&dvb->lock); -- dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", -- __func__, port->nr, dvb->feeding); -+ if (dvb) { -+ mutex_lock(&dvb->lock); -+ if (--dvb->feeding == 0) { -+ /* Stop transport */ -+ ret = saa7164_dvb_stop_streaming(port); -+ } -+ mutex_unlock(&dvb->lock); -+ dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", -+ __func__, port->nr, dvb->feeding); -+ } - - return ret; - } -@@ -425,6 +490,7 @@ - struct saa7164_dev *dev = port->dev; - struct saa7164_buffer *b; - struct list_head *c, *n; -+ struct i2c_client *client; - - dprintk(DBGLVL_DVB, "%s()\n", __func__); - -@@ -443,6 +509,20 @@ - if (dvb->frontend == NULL) - return 0; - -+ /* remove I2C client for tuner */ -+ client = port->i2c_client_tuner; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ /* remove I2C client for demodulator */ -+ client = port->i2c_client_demod; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ - dvb_net_release(&dvb->net); - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); -@@ -462,6 +542,12 @@ - struct saa7164_dev *dev = port->dev; - struct saa7164_dvb *dvb = &port->dvb; - struct saa7164_i2c *i2c_bus = NULL; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ struct i2c_adapter *adapter; -+ struct i2c_board_info info; -+ struct i2c_client *client_demod; -+ struct i2c_client *client_tuner; - int ret; - - dprintk(DBGLVL_DVB, "%s()\n", __func__); -@@ -528,6 +614,124 @@ - } - - break; -+ case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: -+ case SAA7164_BOARD_HAUPPAUGE_HVR2255: -+ i2c_bus = &dev->i2c_bus[2]; -+ -+ if (port->nr == 0) { -+ port->dvb.frontend = dvb_attach(lgdt3306a_attach, -+ &hauppauge_hvr2255a_config, &i2c_bus->i2c_adap); -+ } else { -+ port->dvb.frontend = dvb_attach(lgdt3306a_attach, -+ &hauppauge_hvr2255b_config, &i2c_bus->i2c_adap); -+ } -+ -+ if (port->dvb.frontend != NULL) { -+ -+ if (port->nr == 0) { -+ si2157_attach(port, &dev->i2c_bus[0].i2c_adap, -+ port->dvb.frontend, 0xc0, -+ &hauppauge_hvr2255_tuner_config); -+ } else { -+ si2157_attach(port, &dev->i2c_bus[1].i2c_adap, -+ port->dvb.frontend, 0xc0, -+ &hauppauge_hvr2255_tuner_config); -+ } -+ } -+ break; -+ case SAA7164_BOARD_HAUPPAUGE_HVR2205: -+ -+ if (port->nr == 0) { -+ /* attach frontend */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.fe = &port->dvb.frontend; -+ si2168_config.ts_mode = SI2168_TS_SERIAL; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0xc8 >> 1; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, -+ &info); -+ if (!client_demod || !client_demod->dev.driver) -+ goto frontend_detach; -+ -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_detach; -+ } -+ port->i2c_client_demod = client_demod; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = port->dvb.frontend; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0xc0 >> 1; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(&dev->i2c_bus[0].i2c_adap, -+ &info); -+ if (!client_tuner || !client_tuner->dev.driver) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ goto frontend_detach; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ goto frontend_detach; -+ } -+ port->i2c_client_tuner = client_tuner; -+ } else { -+ /* attach frontend */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.fe = &port->dvb.frontend; -+ si2168_config.ts_mode = SI2168_TS_SERIAL; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0xcc >> 1; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, -+ &info); -+ if (!client_demod || !client_demod->dev.driver) -+ goto frontend_detach; -+ -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_detach; -+ } -+ port->i2c_client_demod = client_demod; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = port->dvb.frontend; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0xc0 >> 1; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, -+ &info); -+ if (!client_tuner || !client_tuner->dev.driver) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ goto frontend_detach; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ goto frontend_detach; -+ } -+ port->i2c_client_tuner = client_tuner; -+ } -+ -+ break; - default: - printk(KERN_ERR "%s: The frontend isn't supported\n", - dev->name); -@@ -548,5 +752,9 @@ - } - - return 0; -+ -+frontend_detach: -+ printk(KERN_ERR "%s() Frontend/I2C initialization failed\n", __func__); -+ return -1; - } - -diff -urN a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h ---- a/drivers/media/pci/saa7164/saa7164.h 2015-06-22 08:05:43.000000000 +0300 -+++ b/drivers/media/pci/saa7164/saa7164.h 2015-06-24 18:41:57.246377117 +0300 -@@ -83,6 +83,9 @@ - #define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8 - #define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9 - #define SAA7164_BOARD_HAUPPAUGE_HVR2200_5 10 -+#define SAA7164_BOARD_HAUPPAUGE_HVR2255proto 11 -+#define SAA7164_BOARD_HAUPPAUGE_HVR2255 12 -+#define SAA7164_BOARD_HAUPPAUGE_HVR2205 13 - - #define SAA7164_MAX_UNITS 8 - #define SAA7164_TS_NUMBER_OF_LINES 312 -@@ -371,6 +374,8 @@ - - /* --- DVB Transport Specific --- */ - struct saa7164_dvb dvb; -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; - - /* --- Encoder/V4L related attributes --- */ - /* Encoder */ -@@ -459,6 +464,7 @@ - /* Interrupt status and ack registers */ - u32 int_status; - u32 int_ack; -+ bool msi; - - struct cmd cmds[SAA_CMD_MAX_MSG_UNITS]; - struct mutex lock; -diff -urN a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c ---- a/drivers/media/pci/saa7164/saa7164-i2c.c -+++ b/drivers/media/pci/saa7164/saa7164-i2c.c -@@ -39,9 +39,10 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) - dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n", - __func__, num, msgs[i].addr, msgs[i].len); - if (msgs[i].flags & I2C_M_RD) { -- /* Unsupported - Yet*/ -- printk(KERN_ERR "%s() Unsupported - Yet\n", __func__); -- continue; -+ retval = saa7164_api_i2c_read(bus, -+ msgs[i].addr, -+ 0 /* reglen */, -+ NULL /* reg */, msgs[i].len, msgs[i].buf); - } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && - msgs[i].addr == msgs[i + 1].addr) { - /* write then read from same address */ - diff --git a/packages/linux/patches/4.1.12/linux-995-CX24120-13Z_frontend.patch b/packages/linux/patches/4.1.12/linux-995-CX24120-13Z_frontend.patch deleted file mode 100644 index 41d0f1d9d2..0000000000 --- a/packages/linux/patches/4.1.12/linux-995-CX24120-13Z_frontend.patch +++ /dev/null @@ -1,1577 +0,0 @@ -http://patchwork.linuxtv.org/patch/10575/ -modified for 3.7.10 - -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-common.h linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-common.h ---- linux-3.4-r1/drivers/media/common/b2c2/flexcop-common.h 2012-04-03 15:23:44.824143495 +0400 -+++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-common.h 2012-04-03 15:26:40.756140116 +0400 -@@ -91,6 +91,8 @@ - int feedcount; - int pid_filtering; - int fullts_streaming_state; -+ /* the stream will be activated by an externally (by the fe for example) */ -+ int need_external_stream_control; - - /* bus specific callbacks */ - flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *, -@@ -177,6 +179,8 @@ - struct dvb_demux_feed *dvbdmxfeed, int onoff); - void flexcop_hw_filter_init(struct flexcop_device *fc); - -+extern void flexcop_external_stream_control(struct dvb_frontend *fe, u8 onoff); -+ - void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); - - void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]); -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-fe-tuner.c linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-fe-tuner.c ---- linux-3.4-r1/drivers/media/common/b2c2/flexcop-fe-tuner.c 2012-04-03 15:23:44.828143388 +0400 -+++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-fe-tuner.c 2012-04-03 15:26:40.760141513 +0400 -@@ -12,6 +12,7 @@ - #include "cx24113.h" - #include "cx24123.h" - #include "isl6421.h" -+#include "cx24120.h" - #include "mt352.h" - #include "bcm3510.h" - #include "nxt200x.h" -@@ -26,6 +27,15 @@ - #define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \ - (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE))) - -+#if FE_SUPPORTED(BCM3510) || FE_SUPPORTED(CX24120) -+static int flexcop_fe_request_firmware(struct dvb_frontend *fe, -+ const struct firmware **fw, char* name) -+{ -+ struct flexcop_device *fc = fe->dvb->priv; -+ return request_firmware(fw, name, fc->dev); -+} -+#endif -+ - /* lnb control */ - #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) - static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -@@ -445,13 +455,6 @@ - - /* AirStar ATSC 1st generation */ - #if FE_SUPPORTED(BCM3510) --static int flexcop_fe_request_firmware(struct dvb_frontend *fe, -- const struct firmware **fw, char* name) --{ -- struct flexcop_device *fc = fe->dvb->priv; -- return request_firmware(fw, name, fc->dev); --} -- - static struct bcm3510_config air2pc_atsc_first_gen_config = { - .demod_address = 0x0f, - .request_firmware = flexcop_fe_request_firmware, -@@ -619,10 +622,40 @@ - #define cablestar2_attach NULL - #endif - -+/* SkyStar S2 PCI DVB-S/S2 card based on Conexant cx24120/cx24118 */ -+#if FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421) -+static const struct cx24120_config skystar2_rev3_3_cx24120_config = { -+ .i2c_addr = 0x55, -+ .request_firmware = flexcop_fe_request_firmware, -+}; -+ -+static int skystarS2_rev33_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) -+{ -+// struct dvb_frontend_ops *ops; -+ -+ fc->fe = dvb_attach(cx24120_attach, -+ &skystar2_rev3_3_cx24120_config, i2c); -+ if (fc->fe == NULL) return 0; -+ fc->dev_type = FC_SKYS2_REV33; -+ fc->fc_i2c_adap[2].no_base_addr = 1; -+ if ( (dvb_attach(isl6421_attach, fc->fe, -+ &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0, false) == NULL) ) { -+ err("ISL6421 could NOT be attached!"); -+ return 0; -+ } -+ info("ISL6421 successfully attached."); -+// ops = &fc->fe->ops; -+ return 1; -+} -+#else -+#define skystarS2_rev33_attach NULL -+#endif -+ - static struct { - flexcop_device_type_t type; - int (*attach)(struct flexcop_device *, struct i2c_adapter *); - } flexcop_frontends[] = { -+ { FC_SKYS2_REV33, skystarS2_rev33_attach }, - { FC_SKY_REV27, skystar2_rev27_attach }, - { FC_SKY_REV28, skystar2_rev28_attach }, - { FC_SKY_REV26, skystar2_rev26_attach }, -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-hw-filter.c linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-hw-filter.c ---- linux-3.4-r1/drivers/media/common/b2c2/flexcop-hw-filter.c 2012-04-03 15:23:44.828143388 +0400 -+++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-hw-filter.c 2012-04-03 15:26:40.760141513 +0400 -@@ -11,6 +11,12 @@ - deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off"); - } - -+void flexcop_external_stream_control(struct dvb_frontend *fe, u8 onoff) -+{ -+ struct flexcop_device *fc = fe->dvb->priv; -+ flexcop_rcv_data_ctrl(fc, onoff); -+} -+ - void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) - { - flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff); -@@ -199,6 +205,7 @@ - - /* if it was the first or last feed request change the stream-status */ - if (fc->feedcount == onoff) { -+ if (!fc->need_external_stream_control) - flexcop_rcv_data_ctrl(fc, onoff); - if (fc->stream_control) /* device specific stream control */ - fc->stream_control(fc, onoff); -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-misc.c linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-misc.c ---- linux-3.4-r1/drivers/media/common/b2c2/flexcop-misc.c 2012-04-03 15:23:44.832143280 +0400 -+++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-misc.c 2012-04-03 15:26:40.760141513 +0400 -@@ -56,6 +56,7 @@ - [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6", - [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", - [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8", -+ [FC_SKYS2_REV33]= "Sky2PC/SkyStar S2 DVB-S/S2 rev 3.3", - }; - - static const char *flexcop_bus_names[] = { -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-reg.h linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-reg.h ---- linux-3.4-r1/drivers/media/common/b2c2/flexcop-reg.h 2012-04-03 15:23:44.832143280 +0400 -+++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-reg.h 2012-04-03 15:26:40.760141513 +0400 -@@ -24,6 +24,7 @@ - FC_SKY_REV26, - FC_SKY_REV27, - FC_SKY_REV28, -+ FC_SKYS2_REV33, - } flexcop_device_type_t; - - typedef enum { -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/Kconfig linux-3.4-r1-S2/drivers/media/common/b2c2/Kconfig ---- linux-3.4-r1/drivers/media/common/b2c2/Kconfig 2012-04-03 15:23:44.824143495 +0400 -+++ linux-3.4-r1-S2/drivers/media/common/b2c2/Kconfig 2012-04-03 15:26:40.760141513 +0400 -@@ -3,6 +3,7 @@ - depends on DVB_CORE && I2C - depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB - default y -+ select DVB_CX24120 if !DVB_FE_CUSTOMISE - select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/cx24120.c linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.c ---- linux-3.4-r1/drivers/media/dvb-frontends/cx24120.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.c 2012-04-03 16:10:59.000000000 +0400 -@@ -0,0 +1,1053 @@ -+/* -+ Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner driver -+ Version 0.0.4a 03.04.2012 -+ -+ Copyright (C) 2009 Sergey Tyurin -+ Updated 2012 by Jannis Achstetter -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "dvb_frontend.h" -+#include "cx24120.h" -+#include "cx24120_const.h" -+ -+//========================== -+#define dbginfo(args...) do { if(cx24120_debug) { printk(KERN_DEBUG "CX24120: %s: >>> ", __func__); \ -+ printk(args); } } while (0) -+#define info(args...) do { printk(KERN_INFO "CX24120: %s: -> ", __func__); \ -+ printk(args); } while (0) -+#define err(args...) do { printk(KERN_ERR "CX24120: %s: ### ERROR: ", __func__); \ -+ printk(args); } while (0) -+//========================== -+ -+static int cx24120_debug=0; -+static int reg_debug=0; -+MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24120/CX24118 hardware"); -+module_param(cx24120_debug, int, 0644); -+MODULE_PARM_DESC(cx24120_debug, "Activates frontend debugging (default:0)"); -+ -+// ############################## -+struct cx24120_state { -+ struct i2c_adapter *i2c; -+ const struct cx24120_config *config; -+ struct dvb_frontend frontend; -+ u8 need_set_mpeg_out; -+ u8 attached; -+ u8 dvb_s2_mode; -+ u8 cold_init; -+}; -+// ##################################### -+// #### Command message to firmware #### -+struct cx24120_cmd { // total size = 36 -+ u8 id; // [00] - message id -+ u8 arg[30]; // [04] - message first byte -+ u8 len; // [34] - message lengh or first registers to read -+ u8 reg; // [35] - number of registers to read -+}; -+ -+//=================================================================== -+static int cx24120_readreg(struct cx24120_state *state, u8 reg) -+{ -+ int ret; -+ u8 buf = 0; -+ struct i2c_msg msg[] = { -+ { .addr = state->config->i2c_addr, -+ .flags = 0, -+ .len = 1, -+ .buf = ® }, -+ -+ { .addr = state->config->i2c_addr, -+ .flags = I2C_M_RD, -+ .len = 1, -+ .buf = &buf } -+ }; -+ ret = i2c_transfer(state->i2c, msg, 2); -+ if (ret != 2) { -+ err("Read error: reg=0x%02x, ret=0x%02x)\n", reg, ret); -+ return ret; -+ } -+ if (reg_debug) dbginfo("reg=0x%02x; data=0x%02x\n", reg, buf); -+ return buf; -+} // end cx24120_readreg -+//=================================================================== -+static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) -+{ -+ u8 buf[] = { reg, data }; -+ struct i2c_msg msg = { -+ .addr = state->config->i2c_addr, -+ .flags = 0, -+ .buf = buf, -+ .len = 2 }; -+ int ret; -+ ret = i2c_transfer(state->i2c, &msg, 1); -+ if (ret != 1) { -+ err("Write error: i2c_write error(err == %i, 0x%02x: 0x%02x)\n", ret, reg, data); -+ return ret; -+ } -+ if (reg_debug) dbginfo("reg=0x%02x; data=0x%02x\n", reg, data); -+ return 0; -+} // end cx24120_writereg -+//=================================================================== -+static int cx24120_writeregN(struct cx24120_state *state, u8 reg, const u8 *values, u16 len, u8 incr) -+{ -+ u8 buf[5]; /* maximum 4 data bytes at once - flexcop limitation (very limited i2c-interface this one) */ -+ struct i2c_msg msg = { -+ .addr = state->config->i2c_addr, -+ .flags = 0, -+ .buf = buf, -+ .len = len }; -+ int ret; -+ -+ do { -+ buf[0] = reg; -+ msg.len = len > 4 ? 4 : len; -+ memcpy(&buf[1], values, msg.len); -+ len -= msg.len; // data length revers counter -+ values += msg.len; // incr data pointer -+ if (incr) reg += msg.len; -+ msg.len++; /* don't forget the addr byte */ -+ ret = i2c_transfer(state->i2c, &msg, 1); -+ if (ret != 1) { -+ err("i2c_write error(err == %i, 0x%02x)\n", ret, reg); -+ return ret; -+ } -+ if (reg_debug) { -+ if( !(reg == 0xFA) && !(reg == 0x20) && !(reg == 0x21)) { // Exclude firmware upload & diseqc messages -+ dbginfo("reg=0x%02x; data=0x%02x,0x%02x,0x%02x,0x%02x\n", // from debug -+ reg, buf[1], buf[2], buf[3], buf[4]); -+ } -+ } -+ } while (len); -+ return 0; -+} // end cx24120_writeregN -+//=================================================================== -+static struct dvb_frontend_ops cx24120_ops; -+//=================================================================== -+struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, struct i2c_adapter *i2c) -+{ -+ struct cx24120_state *state = NULL; -+ int demod_rev; -+ -+ info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n"); -+ info("Driver version: 'SVT - 0.0.4a 03.04.2012'\n"); -+ state = kzalloc(sizeof(struct cx24120_state), -+ GFP_KERNEL); -+ if (state == NULL) { -+ err("### Unable to allocate memory for cx24120_state structure. :(\n"); -+ goto error; -+ } -+ /* setup the state */ -+ state->config = config; -+ state->i2c = i2c; -+ /* check if the demod is present and has proper type */ -+ demod_rev = cx24120_readreg(state, CX24120_REG_REVISION); -+ switch (demod_rev) { -+ case 0x07: -+ info("Demod CX24120 rev. 0x07 detected.\n"); -+ break; -+ case 0x05: -+ info("Demod CX24120 rev. 0x05 detected.\n"); -+ break; -+ default: -+ err("### Unsupported demod revision: 0x%x detected. Exit.\n", demod_rev); -+ goto error; -+ } -+ /* create dvb_frontend */ -+ state->attached = 0x10; // set attached flag -+ state->cold_init=0; -+ memcpy(&state->frontend.ops, &cx24120_ops, sizeof(struct dvb_frontend_ops)); -+ state->frontend.demodulator_priv = state; -+ info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner ATTACHED.\n"); -+ return &state->frontend; -+ -+error: -+ kfree(state); -+ return NULL; -+} -+EXPORT_SYMBOL(cx24120_attach); // end cx24120_attach -+//=================================================================== -+static int cx24120_test_rom(struct cx24120_state *state) -+{ -+ int err, ret; -+ err = cx24120_readreg(state, 0xFD); -+ if (err & 4 ) -+ { -+ ret = cx24120_readreg(state, 0xDF) & 0xFE; -+ err = cx24120_writereg(state, 0xDF, ret); -+ } -+ return err; -+} // end cx24120_test_rom -+//=================================================================== -+static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ -+ *snr = (cx24120_readreg(state, CX24120_REG_QUALITY_H)<<8) | -+ (cx24120_readreg(state, CX24120_REG_QUALITY_L)); -+ dbginfo("read SNR index = %d\n", *snr); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_read_snr); // end cx24120_read_snr -+//=================================================================== -+static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ -+ *ber = (cx24120_readreg(state, CX24120_REG_BER_HH) << 24) | // BER high byte of high word -+ (cx24120_readreg(state, CX24120_REG_BER_HL) << 16) | // BER low byte of high word -+ (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | // BER high byte of low word -+ cx24120_readreg(state, CX24120_REG_BER_LL); // BER low byte of low word -+ dbginfo("read BER index = %d\n", *ber); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_read_ber); // end cx24120_read_ber -+//=================================================================== -+static int cx24120_message_send(struct cx24120_state *state, struct cx24120_cmd *cmd); -+//=================================================================== -+static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, u8 flag) -+{ -+ u8 tristate; -+ struct cx24120_cmd cmd; -+ -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ -+ cmd.id = 0x13; // (19) message Enable/Disable mpeg output ??? -+ cmd.arg[0] = 1; -+ cmd.arg[1] = 0; -+ tristate = flag ? 0 : (u8)(-1); -+ cmd.arg[2] = tristate; -+ cmd.arg[3] = 1; -+ cmd.len = 4; -+ -+ if(flag) dbginfo("MPEG output DISABLED\n"); -+ else dbginfo("MPEG output ENABLED\n"); -+ -+ return cx24120_message_send(state, &cmd); -+} // end cx24120_msg_mpeg_output_global_config -+//=================================================================== -+static int cx24120_message_send(struct cx24120_state *state, struct cx24120_cmd *cmd) -+{ -+ u8 xxzz; -+ u32 msg_cmd_mask; -+ int ret, ficus; -+ -+ if(state->dvb_s2_mode & 0x02) { // is MPEG enabled? -+ // if yes: -+ xxzz = cmd->id - 0x11; // look for specific message id -+ if ( xxzz <= 0x13 ) { -+ msg_cmd_mask = 1 << xxzz; -+ //0x0F8021 // if cmd_id 17 or 22 or 33-36, 42, 47, 57-61 etc. disable mpeg output -+ if ( msg_cmd_mask & 0x0F8021 ) { // 000011111000000000100001b -+ cx24120_msg_mpeg_output_global_config(state, 0); -+ msleep(100); -+ state->dvb_s2_mode &= 0xFD; // reset mpeg out enable flag -+ } -+ } -+ } -+ ret = cx24120_writereg(state, 0x00 /* reg id*/, cmd->id /* value */); // message start & target -+ ret = cx24120_writeregN(state, 0x01 /* reg msg*/, &cmd->arg[0], cmd->len /* len*/, 1 /* incr */); // message data -+ ret = cx24120_writereg(state, 0x1F /* reg msg_end */, 0x01 /* value */); // message end -+ -+ ficus = 1000; -+ while ( cx24120_readreg(state, 0x1F)) { // is command done??? -+ msleep(1); -+ if( !(--ficus)) { -+ err("Too long waiting 'done' state from reg(0x1F). :(\n"); -+ return -EREMOTEIO; -+ } -+ } -+ dbginfo("Successfully send message 0x%02x\n", cmd->id); -+ -+ if ( cmd->reg > 30 ) { -+ err("Too much registers to read. cmd->reg = %d", cmd->reg); -+ return -EREMOTEIO; -+ } -+ ficus = 0; -+ if ( cmd->reg ) { // cmd->reg - qty consecutive regs to read -+ while ( ficus < cmd->reg ){ // starts from reg No cmd->len -+ // number of registers to read is cmd->reg -+ // and write results starts from cmd->arg[0]. -+ cmd->arg[ficus] = cx24120_readreg(state, (cmd->len+ficus+1)); -+ ++ficus; -+ } -+ } -+ return 0; -+} // end cx24120_message_send -+//=================================================================== -+static int cx24120_set_frontend(struct dvb_frontend *fe) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ u32 srate, freq; -+ fe_code_rate_t fec; -+ fe_spectral_inversion_t inversion; -+ u8 smbr1, smbr2; -+ int ret; -+ -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ -+ cmd.id = CMD_TUNEREQUEST; // 0x11 set tuner parametrs -+ cmd.len = 15; -+ -+ freq = p->frequency; -+ srate = p->symbol_rate; -+ fec = p->fec_inner; -+ inversion = p->inversion; -+ -+ // check symbol rate -+ if ( srate > 31000000 ) { // if symbol rate > 31 000 -+ smbr1 = (-(srate < 31000001) & 3) + 2; // ebp -+ smbr2 = (-(srate < 31000001) & 6) + 4; // edi -+ } else { -+ smbr1 = 3; -+ smbr2 = 6; -+ } -+ -+ ret = cx24120_writereg(state, 0xE6, smbr1); -+ ret = cx24120_readreg(state, 0xF0); -+ ret &= 0xFFFFFFF0; -+ ret |= smbr2; -+ ret = cx24120_writereg(state, 0xF0, ret); -+ -+ cmd.arg[0] = 0; // CMD_TUNER_REQUEST -+ -+ // Frequency -+ cmd.arg[1] = (freq & 0xFF0000) >> 16; /* intermediate frequency in kHz */ -+ cmd.arg[2] = (freq & 0x00FF00) >> 8; -+ cmd.arg[3] = (freq & 0x0000FF); -+ -+ // Symbol Rate -+ cmd.arg[4] = ((srate/1000) & 0xFF00) >> 8; -+ cmd.arg[5] = ((srate/1000) & 0x00FF); -+ -+ // Inversion -+ if ( inversion ) { -+ if ( inversion == 1 ) cmd.arg[6] = 4; -+ else cmd.arg[6] = 0x0C; -+ } else { -+ cmd.arg[6] = 0; -+ } -+ -+ // FEC -+ switch ( fec ) // fec = p->u.qpsk.fec_inner -+ { -+ case 1: // FEC_1_2 -+ cmd.arg[7] = 0x2E; break; // [11] = 0 by memset -+ case 2: // FEC_2_3 -+ cmd.arg[7] = 0x2F; break; -+ case 3: // FEC_3_4 -+ cmd.arg[7] = 0x30; break; -+ case 5: // FEC_5_6 -+ cmd.arg[7] = 0x31; break; -+ case 7: // FEC_7_8 -+ cmd.arg[7] = 0x32; break; -+ default: // FEC_NONE, FEC_4_5, FEC_6_7, FEC_8_9, -+ // FEC_AUTO, FEC_3_5, FEC_9_10 -+ if ( state->dvb_s2_mode & 1 ) { // if DVB-S2 mode -+ cmd.arg[7] = 0; -+ cmd.arg[11] = 0; -+ } else { -+ cmd.arg[7] = 0x2E; -+ cmd.arg[11] = 0xAC; -+ } -+ break; -+ } -+ cmd.arg[8] = 0x13; -+ cmd.arg[9] = 0x88; -+ cmd.arg[10] = 0; -+ cmd.arg[12] = smbr2; -+ cmd.arg[13] = smbr1; -+ cmd.arg[14] = 0; -+ -+ state->need_set_mpeg_out |= 0x01; // after tune we need restart mpeg out ????? -+ -+ return cx24120_message_send(state, &cmd); -+ -+} -+EXPORT_SYMBOL(cx24120_set_frontend); // end cx24120_set_frontend -+//=================================================================== -+void cx24120_message_fill(struct cx24120_cmd *cmd, -+ u8 msg_id, -+ u8 *msg_addr, -+ u8 msg_len, -+ u8 num_regs) -+{ -+ cmd->id = msg_id; -+ memcpy(&cmd->arg[0], msg_addr, msg_len); -+ cmd->len = msg_len; -+ cmd->reg = num_regs; -+} // end cx24120_message_fill -+//=================================================================== -+static int cx24120_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ int result, sigstr_h, sigstr_l; -+ -+ cx24120_message_fill(&cmd, 0x1A/*msg_id*/, &cx24120_msg_read_sigstr[0], 1/*msg_len*/, 0/*num_regs*/); -+ -+ if( !(cx24120_message_send(state, &cmd)) ) { -+ sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; -+ sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L ); -+ dbginfo("Signal strength from firmware= 0x%x\n", (sigstr_h | sigstr_l)); -+ *signal_strength = ((sigstr_h | sigstr_l) << 5) & 0x0000FFFF; -+ dbginfo("Signal strength= 0x%x\n", *signal_strength); -+ result = 0; -+ } else { -+ err("error reading signal strength\n"); -+ result = -EREMOTEIO; -+ } -+ return result; -+} -+EXPORT_SYMBOL(cx24120_read_signal_strength); // end cx24120_read_signal_strength -+//=================================================================== -+static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 num, -+ struct cx24120_skystar2_mpeg_config *config_msg) -+{ -+ struct cx24120_cmd cmd; -+ -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ -+ cmd.id = CMD_MPEG_INIT; // cmd->id=20 - message id -+ cmd.len = 7; -+ cmd.arg[0] = num; // sequental number - can be 0,1,2 -+ cmd.arg[1] = ((config_msg->x1 & 0x01) << 1) | -+ ((config_msg->x1 >> 1) & 0x01); -+ cmd.arg[2] = 0x05; -+ cmd.arg[3] = 0x02; -+ cmd.arg[4] = ((config_msg->x2 >> 1) & 0x01); -+ cmd.arg[5] = (config_msg->x2 & 0xF0) | (config_msg->x3 & 0x0F); -+ cmd.arg[6] = state->attached; /* 0x10 if succesfully attached */ -+ -+ return cx24120_message_send(state, &cmd); -+} // end cx24120_msg_mpeg_output_config -+//=================================================================== -+static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ -+ cmd.id = CMD_DISEQC_BURST; -+ cmd.arg[0] = 0x00; -+ if (burst) -+ cmd.arg[1] = 0x01; -+ dbginfo("burst sent.\n"); -+ -+ return cx24120_message_send(state, &cmd); -+} -+EXPORT_SYMBOL(cx24120_diseqc_send_burst); // end cx24120_diseqc_send_burst -+//=================================================================== -+static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ -+ dbginfo("cmd(0x23,4) - tone = %d\n", tone); -+ if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { -+ err("Invalid tone=%d\n", tone); -+ return -EINVAL; -+ } -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ cmd.id = CMD_SETTONE; // 0x23 -+ cmd.len = 4; -+ if (!tone) -+ cmd.arg[3] = 0x01; -+ return cx24120_message_send(state, &cmd); -+} -+EXPORT_SYMBOL(cx24120_set_tone); // end cx24120_set_tone -+//=================================================================== -+static int cx24120_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ cmd.id = CMD_SETVOLTAGE; // -+ cmd.len = 2; -+ if (!(voltage - 1)) -+ cmd.arg[1] = 0x01; -+ return cx24120_message_send(state, &cmd); -+} -+EXPORT_SYMBOL(cx24120_set_voltage); // end cx24120_set_voltage -+//=================================================================== -+static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *d) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ int back_count; -+ -+ dbginfo("Start sending diseqc sequence===============\n"); -+ -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ -+ cmd.id = CMD_DISEQC_MSG1; // 0x20 -+ cmd.len = 11; -+ cmd.arg[0] = 0x00; -+ cmd.arg[1] = 0x00; -+ cmd.arg[2] = 0x03; -+ cmd.arg[3] = 0x16; -+ cmd.arg[4] = 0x28; -+ cmd.arg[5] = 0x01; -+ cmd.arg[6] = 0x01; -+ cmd.arg[7] = 0x14; -+ cmd.arg[8] = 0x19; -+ cmd.arg[9] = 0x14; -+ cmd.arg[10] = 0x1E; -+ if ( cx24120_message_send(state, &cmd) ) { -+ err("send 1st message(0x%x) filed==========\n", cmd.id); -+ return -EREMOTEIO; -+ } -+ cmd.id = CMD_DISEQC_MSG2; // 0x21 -+ cmd.len = d->msg_len + 6; -+ cmd.arg[0] = 0x00; -+ cmd.arg[1] = 0x01; -+ cmd.arg[2] = 0x02; -+ cmd.arg[3] = 0x00; -+ cmd.arg[4] = 0x00; -+ cmd.arg[5] = d->msg_len; -+ -+ memcpy(&cmd.arg[6], &d->msg, d->msg_len); -+ -+ if ( cx24120_message_send(state, &cmd) ) { -+ err("send 2d message(0x%x) filed========\n", cmd.id); -+ return -EREMOTEIO; -+ } -+ back_count = 100; -+ do { -+ if ( !(cx24120_readreg(state, 0x93) & 0x01) ) { -+ dbginfo("diseqc sequence sent success==========.\n"); -+ return 0; -+ } -+ msleep(5); -+ --back_count; -+ } while ( back_count ); -+ err("Too long waiting for diseqc.=============\n"); -+ return -ETIMEDOUT; -+} -+EXPORT_SYMBOL(cx24120_send_diseqc_msg); // end cx24120_send_diseqc_msg -+//=================================================================== -+static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ int ret, clock_seq_num, GettedFEC; -+ u8 mode_code, mode_8PSK_flag, attached_flag, clock_id; -+ -+ ret = cx24120_readreg(state, CX24120_REG_STATUS); //0x3A -+ dbginfo("status = 0x%x\n", ret); -+ *status = 0; -+ if ( ret & CX24120_HAS_SIGNAL ) *status = FE_HAS_SIGNAL; -+ if ( ret & CX24120_HAS_CARRIER) *status |= FE_HAS_CARRIER; -+ if ( ret & CX24120_HAS_VITERBI) *status |= (FE_HAS_VITERBI + FE_HAS_SYNC); -+ -+ if ( ret & CX24120_HAS_LOCK ) { // 0x08 -+ *status |= FE_HAS_LOCK; -+ if ( state->need_set_mpeg_out & 1 ) { // just tuned??? -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ cmd.id = CMD_CLOCK_READ; -+ cmd.arg[0] = 0x00; -+ cmd.len = 1; // cmd.reg != 0, so it is first register to read -+ cmd.reg = 6; // number of registers to read (0x01-0x06) -+ if ( !cx24120_message_send(state, &cmd) ) { // in cmd[0]-[5] - result -+ // 0x02-0x07 -+ ret = cx24120_readreg(state, CX24120_REG_FECMODE) & 0x3F; // ntv - 0x8E(142) & 3F = 14 -+ GettedFEC = ret; // 0x0d= 13 -+ dbginfo("Get FEC: %d\n", ret); -+ if ( state->dvb_s2_mode & 0x01 ) { // is DVB-S2? -+ switch (ret-4) { -+ case 0: -+ mode_code = 0x01; goto mode_QPSK; // FEC_1_2 - qpsk only -+ case 1: -+ case 8: -+ mode_code = 0x64; goto mode_8PSK; // FEC_3_5 (10)- 8PSK only -+ case 2: -+ case 9: -+ mode_code = 0x02; goto mode_8PSK; // FEC_2_3 -+ case 3: -+ case 10: -+ mode_code = 0x03; goto mode_8PSK; // FEC_3_4 // 14-4=10 - ntv+ -+ case 4: -+ mode_code = 0x04; goto mode_QPSK; // FEC_4_5 - qpsk only -+ case 5: -+ case 11: -+ mode_code = 0x05; goto mode_8PSK; // FEC_5_6 -+ case 6: -+ case 12: -+ mode_code = 0x08; goto mode_8PSK; // FEC_8_9 -+ case 7: -+ case 13: -+ mode_code = 0x65; goto mode_8PSK; // FEC_9_10 (11)- 8PSK only -+ default: -+ info("Unknown DVB-S2 modefec (not QPSK or 8PSK): %d\n", ret-4); -+ mode_code = 0x01; // set like for mode 0 -+ mode_8PSK: -+ if ( ret > 11 ) { // 14 -+ mode_8PSK_flag = 0x63; // DVB-S2-8PSK flag -+ dbginfo("DVB-S2: 8PSK mode: %d, mode_code= 0x%x\n", ret-4, mode_code); -+ } else { -+ mode_QPSK: -+ mode_8PSK_flag = 0x00; -+ dbginfo("DVB-S2: QPSK mode: %d\n", ret-4); -+ } -+ break; -+ } // end switch -+ } // end if dvb_s2_mode // dvb-s2 -+ else { // state->dvb_s2_mode & 1 = 0 -> #### DVB-S -+ switch ( ret - 2 ) { -+ case 0: -+ mode_code = 2; break; // FEC_2_3 -+ case 1: -+ mode_code = 3; break; // FEC_3_4 -+ case 2: -+ mode_code = 4; break; // FEC_4_5 -+ case 3: -+ mode_code = 5; break; // FEC_5_6 -+ case 4: -+ mode_code = 6; break; // FEC_6_7 -+ case 5: -+ mode_code = 7; break; // FEC_7_8 -+ default: -+ mode_code = 1;break; // FEC_1_2 -+ } -+ mode_8PSK_flag = 0; -+ } // end of switch for dvb-s -+ -+ attached_flag = 0x10; -+ if (state->attached == 0x10) // must be 0x10 if successfully attached in flexcop_fe_tuner -+ attached_flag = 0; -+ ret = 0; -+ if ( state->dvb_s2_mode & 0x01 ) // if dvb-s2 -+ ret = (cx24120_readreg(state, CX24120_REG_FECMODE) >> 7) & 0x01; // QPSK or 8PSK ??? -+ // bit 4 bit 5 bit 0 bit 3 -+ clock_id = (ret << 3) | attached_flag | (state->dvb_s2_mode & 1) | 4; // possible id: 4, 5, 13. 12-impossible, -+ // ntv S2 = 0x8E -> 8 | 1 | 4 = 13 // because 7th bit of ret - is S2 flag -+ // 1/2 S2 = 0x0d -> 0 | 1 | 4 = 5 -+ dbginfo("Check clock table for: clock_id=0x%x, 8PSK_mask=0x%x, mode_code=0x%x\n", -+ clock_id, mode_8PSK_flag, mode_code); -+ -+ clock_seq_num = 0; -+ while ( (clock_ratios_table[clock_seq_num].ratio_id != clock_id) || -+ (clock_ratios_table[clock_seq_num].mode_xPSK != mode_8PSK_flag) || -+ (clock_ratios_table[clock_seq_num].fec_mode != mode_code) ) -+ { -+ /* dbginfo("Check table string(%d): clock_id=%d, 8PSK_flag=%d, mode_code=%d\n", clock_seq_num, -+ * clock_ratios_table[clock_seq_num].ratio_id, -+ * clock_ratios_table[clock_seq_num].mode_xPSK, -+ * clock_ratios_table[clock_seq_num].fec_mode); -+ */ -+ ++clock_seq_num; -+ if ( clock_seq_num == ARRAY_SIZE(clock_ratios_table) ) { -+ info("Check in clock table filed: unsupported modulation tuned - data reception in danger. :(\n"); -+ goto settings_end; -+ } -+ } -+ //############################### -+ dbginfo("Check succesful: GetFEC: %d; post lock: m=%d, n=%d; clock_seq_idx: %d m=%d, n=%d, rate=%d\n", -+ GettedFEC, -+ cmd.arg[2] | (cmd.arg[1] << 8) | (cmd.arg[0] << 16), // registers was readed early -+ cmd.arg[5] | (cmd.arg[4] << 8) | (cmd.arg[3] << 16), // in message with id = 0x16 -+ clock_seq_num, -+ clock_ratios_table[clock_seq_num].m_rat, -+ clock_ratios_table[clock_seq_num].n_rat, -+ clock_ratios_table[clock_seq_num].rate); -+ //############################### -+ cmd.id = CMD_CLOCK_SET; -+ cmd.len = 10; -+ cmd.reg = 0; -+ cmd.arg[0] = 0; -+ cmd.arg[1] = state->attached; // must be 0x10 if successfully attached in flexcop_fe_tuner -+ -+ cmd.arg[2] = (clock_ratios_table[clock_seq_num].m_rat >> 16) & 0xFF; -+ cmd.arg[3] = (clock_ratios_table[clock_seq_num].m_rat >> 8) & 0xFF; -+ cmd.arg[4] = (clock_ratios_table[clock_seq_num].m_rat >> 0) & 0xFF; -+ -+ cmd.arg[5] = (clock_ratios_table[clock_seq_num].n_rat >> 16) & 0xFF; -+ cmd.arg[6] = (clock_ratios_table[clock_seq_num].n_rat >> 8) & 0xFF; -+ cmd.arg[7] = (clock_ratios_table[clock_seq_num].n_rat >> 0) & 0xFF; -+ -+ cmd.arg[8] = (clock_ratios_table[clock_seq_num].rate >> 8) & 0xFF; -+ cmd.arg[9] = (clock_ratios_table[clock_seq_num].rate >> 0) & 0xFF; -+ -+ cx24120_message_send(state, &cmd); -+ -+ settings_end: -+ msleep(200); -+ cx24120_msg_mpeg_output_global_config(state, 1); -+ state->dvb_s2_mode |= 0x02; // set mpeg flag -+ state->need_set_mpeg_out &= 0xFE; // clocks set done -> clear flag -+ } -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_read_status); // end cx24120_read_status -+//=================================================================== -+int cx24120_init(struct dvb_frontend *fe) -+{ -+ const struct firmware *fw; -+ struct cx24120_state *state = fe->demodulator_priv; -+ struct cx24120_cmd cmd; -+ u8 ret, ret_EA, reg1, fL, fH; -+ u32 vco, xtal_khz; -+ u64 inv_vco, res, xxyyzz; -+ int reset_result; -+ -+ if( state->cold_init ) return 0; -+ -+ ret = cx24120_writereg(state, 0xEA, 0x00); -+ ret = cx24120_test_rom(state); -+ ret = cx24120_readreg(state, 0xFB) & 0xFE; -+ ret = cx24120_writereg(state, 0xFB, ret); -+ ret = cx24120_readreg(state, 0xFC) & 0xFE; -+ ret = cx24120_writereg(state, 0xFC, ret); -+ ret = cx24120_writereg(state, 0xC3, 0x04); -+ ret = cx24120_writereg(state, 0xC4, 0x04); -+ ret = cx24120_writereg(state, 0xCE, 0x00); -+ ret = cx24120_writereg(state, 0xCF, 0x00); -+ ret_EA = cx24120_readreg(state, 0xEA) & 0xFE; -+ ret = cx24120_writereg(state, 0xEA, ret_EA); -+ ret = cx24120_writereg(state, 0xEB, 0x0C); -+ ret = cx24120_writereg(state, 0xEC, 0x06); -+ ret = cx24120_writereg(state, 0xED, 0x05); -+ ret = cx24120_writereg(state, 0xEE, 0x03); -+ ret = cx24120_writereg(state, 0xEF, 0x05); -+ ret = cx24120_writereg(state, 0xF3, 0x03); -+ ret = cx24120_writereg(state, 0xF4, 0x44); -+ -+ reg1 = 0xF0; -+ do { -+ cx24120_writereg(state, reg1, 0x04); -+ cx24120_writereg(state, reg1 - 10, 0x02); -+ ++reg1; -+ } while ( reg1 != 0xF3 ); -+ -+ ret = cx24120_writereg(state, 0xEA, (ret_EA | 0x01)); -+ reg1 = 0xC5; -+ do { -+ ret = cx24120_writereg(state, reg1, 0x00); -+ ret = cx24120_writereg(state, reg1 + 1, 0x00); -+ reg1 += 2; -+ } while ( reg1 != 0xCB ); -+ -+ ret = cx24120_writereg(state, 0xE4, 0x03); -+ ret = cx24120_writereg(state, 0xEB, 0x0A); -+ -+ dbginfo("Requesting firmware (%s) to download...\n", CX24120_FIRMWARE); -+ ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE); -+ if (ret) { -+ err("Could not load firmware (%s): %d\n", CX24120_FIRMWARE, ret); -+ return ret; -+ } -+ dbginfo("Firmware found and it size is %d bytes (%02x %02x .. %02x %02x)\n", -+ (int)fw->size, // firmware_size in bytes u32* -+ fw->data[0], // fw 1st byte -+ fw->data[1], // fw 2d byte -+ fw->data[fw->size - 2], // fw before last byte -+ fw->data[fw->size - 1]); // fw last byte -+ -+ ret = cx24120_test_rom(state); -+ ret = cx24120_readreg(state, 0xFB) & 0xFE; -+ ret = cx24120_writereg(state, 0xFB, ret); -+ ret = cx24120_writereg(state, 0xE0, 0x76); -+ ret = cx24120_writereg(state, 0xF7, 0x81); -+ ret = cx24120_writereg(state, 0xF8, 0x00); -+ ret = cx24120_writereg(state, 0xF9, 0x00); -+ ret = cx24120_writeregN(state, 0xFA, fw->data, (fw->size - 1), 0x00); -+ ret = cx24120_writereg(state, 0xF7, 0xC0); -+ ret = cx24120_writereg(state, 0xE0, 0x00); -+ ret = (fw->size - 2) & 0x00FF; -+ ret = cx24120_writereg(state, 0xF8, ret); // ret now is 0x7a -+ ret = ((fw->size - 2) >> 8) & 0x00FF; -+ ret = cx24120_writereg(state, 0xF9, ret); // ret now is 0xaf -+ ret = cx24120_writereg(state, 0xF7, 0x00); -+ ret = cx24120_writereg(state, 0xDC, 0x00); -+ ret = cx24120_writereg(state, 0xDC, 0x07); -+ msleep(500); -+ -+ ret = cx24120_readreg(state, 0xE1); // now is 0xd5 - last byte of the firmware -+ if ( ret == fw->data[fw->size - 1] ) { -+ dbginfo("Firmware uploaded successfully\n"); -+ reset_result = 0; -+ } else { -+ err("Firmware upload failed. Last byte returned=0x%x\n", ret ); -+ reset_result = -EREMOTEIO; -+ } -+ ret = cx24120_writereg(state, 0xDC, 0x00); -+ release_firmware(fw); -+ if (reset_result) -+ return reset_result; -+ -+ //================== Start tuner -+ cx24120_message_fill(&cmd, CMD_START_TUNER, &cx24120_msg_tuner_init[0], 3, 0); // 0x1B -+ if(cx24120_message_send(state, &cmd)) { -+ err("Error tuner start! :(\n"); -+ return -EREMOTEIO; -+ } -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ -+ cmd.id = CMD_VCO_SET; // 0x10 -+ cmd.len = 12; -+ -+ // ###################### -+ // Calc VCO -+ xtal_khz = 10111; -+ xxyyzz = 0x400000000ULL; // 17179869184 -+ vco = xtal_khz * 10 * 4; // 404440 -+ inv_vco = xxyyzz / vco; // 42478 = 0x00A5EE -+ res = xxyyzz % vco; // 66864 = 0x010530 -+ -+ if( inv_vco > xtal_khz * 10 * 2) ++inv_vco; -+ -+ fH = (inv_vco >> 8) & 0xFF; -+ fL = (inv_vco) & 0xFF; -+ dbginfo("vco= %d, inv_vco= %lld, res= %lld, fL= 0x%x, fH= 0x%x\n", vco, inv_vco, res, fL, fH); -+ // ###################### -+ -+ cmd.arg[0] = 0x06; -+ cmd.arg[1] = 0x2B; -+ cmd.arg[2] = 0xD8; -+ cmd.arg[3] = fH; // 0xA5 -+ cmd.arg[4] = fL; // 0xEE -+ cmd.arg[5] = 0x03; -+ cmd.arg[6] = 0x9D; -+ cmd.arg[7] = 0xFC; -+ cmd.arg[8] = 0x06; -+ cmd.arg[9] = 0x03; -+ cmd.arg[10] = 0x27; -+ cmd.arg[11] = 0x7F; -+ -+ if(cx24120_message_send(state, &cmd)) { -+ err("Error set VCO! :(\n"); -+ return -EREMOTEIO; -+ } -+ memset(&cmd, 0, sizeof(struct cx24120_cmd)); -+ // set bandwidth -+ cmd.id = CMD_BANDWIDTH; // 0x15 -+ cmd.len = 12; -+ cmd.arg[0] = 0x00; -+ cmd.arg[1] = 0x00; -+ cmd.arg[2] = 0x00; -+ cmd.arg[3] = 0x00; -+ cmd.arg[4] = 0x05; -+ cmd.arg[5] = 0x02; -+ cmd.arg[6] = 0x02; -+ cmd.arg[7] = 0x00; -+ cmd.arg[8] = 0x05; -+ cmd.arg[9] = 0x02; -+ cmd.arg[10] = 0x02; -+ cmd.arg[11] = 0x00; -+ -+ if ( cx24120_message_send(state, &cmd) ) { -+ err("Error set bandwidth! :(\n"); -+ return -EREMOTEIO; -+ } -+ ret = cx24120_readreg(state, 0xBA); -+ if ( ret > 3) { -+ dbginfo("Reset-readreg 0xBA: %x\n", ret); -+ err("Error intitilizing tuner! :(\n"); -+ return -EREMOTEIO; -+ } -+ dbginfo("Tuner initialized correctly.\n"); -+ -+ ret = cx24120_writereg(state, 0xEB, 0x0A); -+ if (cx24120_msg_mpeg_output_global_config(state, 0) || -+ cx24120_msg_mpeg_output_config(state, 0, &initial_mpeg_config) || -+ cx24120_msg_mpeg_output_config(state, 1, &initial_mpeg_config) || -+ cx24120_msg_mpeg_output_config(state, 2, &initial_mpeg_config) ) -+ { -+ err("Error initilizing mpeg output. :(\n"); -+ return -EREMOTEIO; -+ } else { -+ cmd.id = 0x3C; // 60 -+ cmd.len = 0x03; -+ cmd.arg[0] = 0x00; -+ cmd.arg[1] = 0x10; -+ cmd.arg[2] = 0x10; -+ if(cx24120_message_send(state, &cmd)) { -+ err("Error sending final init message. :(\n"); -+ return -EREMOTEIO; -+ } -+ } -+ state->cold_init=1; -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_init); // end cx24120_reset -+//=================================================================== -+static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, -+ unsigned int mode_flags, unsigned int *delay, fe_status_t *p_status) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ struct cx24120_state *state = fe->demodulator_priv; -+ int delay_cnt, sd_idx = 0; -+ fe_status_t status; -+ -+ if (re_tune) { -+ -+// dbginfo("Compare symrate with table: symrate= %d, in table= %d\n", -+// p->u.qpsk.symbol_rate, symrates_pairs[sd_idx].symrate); -+ -+ while ( p->symbol_rate > symrates_pairs[sd_idx].symrate ) { -+ ++sd_idx; -+ } -+ dbginfo("Found symrate delay = %d\n", symrates_pairs[sd_idx].delay); -+ state->dvb_s2_mode &= 0xFE; // clear bit -> try not DVB-S2 -+ dbginfo("trying DVB-S =================\n"); -+ cx24120_set_frontend(fe); -+ -+ delay_cnt = symrates_pairs[sd_idx].delay; -+ dbginfo("Wait for LOCK for DVB-S =================\n"); -+ while (delay_cnt >= 0) { -+ cx24120_read_status(fe, &status); -+ if (status & FE_HAS_LOCK) { -+ dbginfo("DVB-S LOCKED================\n"); -+ break; -+ } -+ msleep(100); -+ delay_cnt -=100; -+ } -+ dbginfo("Waiting finished - NO lock for DVB-S =================\n"); -+ -+ cx24120_read_status(fe, &status); -+ if ( !(status & FE_HAS_LOCK) ) { // if no lock on S -+ dbginfo("trying DVB-S2 ++++++++++++++++++++++++++\n"); -+ state->dvb_s2_mode |= 0x01; // may be it locked on S2 ? -+ p->fec_inner = FEC_AUTO; -+ cx24120_set_frontend(fe); -+ delay_cnt = symrates_pairs[sd_idx].delay; -+ dbginfo("Wait for LOCK for DVB-S2 ++++++++++++++++\n"); -+ while (delay_cnt >= 0) { -+ cx24120_read_status(fe, &status); -+ if (status & FE_HAS_LOCK) { -+ dbginfo("DVB-S2 LOCKED++++++++++++++++\n"); -+ break; -+ } -+ msleep(100); -+ delay_cnt -=100; -+ } -+ dbginfo("Waiting finished - NO lock for DVB-S2 ++++++++++++++++\n"); -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_tune); // end of cx24120_tune -+//=================================================================== -+static int cx24120_get_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+EXPORT_SYMBOL(cx24120_get_algo); -+//=================================================================== -+static int cx24120_sleep(struct dvb_frontend *fe) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_sleep); -+//=================================================================== -+/*static int cx24120_wakeup(struct dvb_frontend *fe) -+ * { -+ * return 0; -+ * } -+ * EXPORT_SYMBOL(cx24120_wakeup); -+ */ -+//=================================================================== -+static int cx24120_get_frontend(struct dvb_frontend *fe) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_get_frontend); -+//=================================================================== -+static void cx24120_release(struct dvb_frontend *fe) -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ dbginfo("Clear state structure\n"); -+ kfree(state); -+} -+EXPORT_SYMBOL(cx24120_release); -+//=================================================================== -+static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) // UNCORRECTED_BLOCKS -+{ -+ struct cx24120_state *state = fe->demodulator_priv; -+ -+ *ucblocks = (cx24120_readreg(state, CX24120_REG_UCB_H) << 8) | -+ cx24120_readreg(state, CX24120_REG_UCB_L); -+ dbginfo("Blocks = %d\n", *ucblocks); -+ return 0; -+} -+EXPORT_SYMBOL(cx24120_read_ucblocks); -+// ######################################################################################## -+static struct dvb_frontend_ops cx24120_ops = { -+ -+ .delsys = { SYS_DVBS2 }, -+ .info = { -+ .name = "Conexant CX24120/CX24118", -+ .frequency_min = 950000, -+ .frequency_max = 2150000, -+ .frequency_stepsize = 1011, /* kHz for QPSK frontends */ -+ .frequency_tolerance = 5000, -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 45000000, -+ .caps = // 0x500006ff -+ FE_CAN_INVERSION_AUTO | //0x00 000 001 -+ FE_CAN_FEC_1_2 | //0x00 000 002 -+ FE_CAN_FEC_2_3 | //0x00 000 004 -+ FE_CAN_FEC_3_4 | //0x00 000 008 -+ FE_CAN_FEC_4_5 | //0x00 000 010 -+ FE_CAN_FEC_5_6 | //0x00 000 020 -+ FE_CAN_FEC_6_7 | //0x00 000 040 -+ FE_CAN_FEC_7_8 | //0x00 000 080 -+ FE_CAN_FEC_AUTO | //0x00 000 200 -+ FE_CAN_QPSK | //0x00 000 400 -+//??? FE_HAS_EXTENDED_CAPS | //0x00 800 000 /* We need more bitspace for newer APIs, indicate this. */ -+ FE_CAN_2G_MODULATION | //0x10 000 000 /* frontend supports "2nd generation modulation" (DVB-S2) */ -+ FE_CAN_RECOVER //0x40 000 000 /* frontend can recover from a cable unplug automatically */ -+ }, //sum=50 000 6FF -+ .release = cx24120_release, -+ -+ .init = cx24120_init, -+ .sleep = cx24120_sleep, -+ -+ .tune = cx24120_tune, -+ .get_frontend_algo = cx24120_get_algo, -+ .set_frontend = cx24120_set_frontend, -+ -+ .get_frontend = cx24120_get_frontend, -+ .read_status = cx24120_read_status, -+ .read_ber = cx24120_read_ber, -+ .read_signal_strength = cx24120_read_signal_strength, -+ .read_snr = cx24120_read_snr, -+ .read_ucblocks = cx24120_read_ucblocks, -+ -+ .diseqc_send_master_cmd = cx24120_send_diseqc_msg, -+ -+ .diseqc_send_burst = cx24120_diseqc_send_burst, -+ .set_tone = cx24120_set_tone, -+ .set_voltage = cx24120_set_voltage, -+}; -+//=================================================================== -+MODULE_PARM_DESC(cx24120_debug, "prints some verbose debugging information (default:0)"); -+MODULE_AUTHOR("Sergey Tyurin"); -+MODULE_LICENSE("GPL"); -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/cx24120_const.h linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120_const.h ---- linux-3.4-r1/drivers/media/dvb-frontends/cx24120_const.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120_const.h 2012-04-03 16:37:20.684139905 +0400 -@@ -0,0 +1,259 @@ -+/* -+ * Conexant CX24120/CX24118 - DVB-S/S2 demod/tuner driver -+ * DVBS/S2 Satellite demod/tuner driver static definitins -+ * -+ * Copyright (C) 2009 Sergey Tyurin -+ * Updated 2012 by Jannis Achstetter -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#define CX24120_FIRMWARE "dvb-fe-cx24120-1.20.58.2.fw" -+ -+// ############################## -+// ### cx24120 i2c registers ### -+#define CX24120_REG_CMD_START (0x00) // write cmd_id, and then start write args to next register: -+#define CX24120_REG_CMD_ARGS (0x01) // write command arguments, max 4 at once, then next 4, etc. -+#define CX24120_REG_CMD_END (0x1F) // write 0x01 for end, and read it for command result -+ -+#define CX24120_REG_FECMODE (0x39) // FEC status -+#define CX24120_REG_STATUS (0x3A) // Tuner status - signal, carrier, sync, lock ... -+#define CX24120_REG_QUALITY_H (0x40) // SNR high byte -+#define CX24120_REG_QUALITY_L (0x41) // SNR low byte -+ -+#define CX24120_REG_BER_HH (0x47) // BER high byte of high word -+#define CX24120_REG_BER_HL (0x48) // BER low byte of high word -+#define CX24120_REG_BER_LH (0x49) // BER high byte of low word -+#define CX24120_REG_BER_LL (0x4A) // BER low byte of low word -+ -+#define CX24120_REG_SIGSTR_H (0x3A) // Signal strength high byte & ??? status register ??? -+#define CX24120_REG_SIGSTR_L (0x3B) // Signal strength low byte -+ -+#define CX24120_REG_UCB_H (0x50) // UCB high byte -+#define CX24120_REG_UCB_L (0x51) // UCB low byte -+ -+#define CX24120_REG_REVISION (0xFF) // Chip revision (ro). Must be 0x7 or 0x5 -+ -+// ############################## -+/* Command messages */ -+enum command_message_id { -+ CMD_VCO_SET = 0x10, // cmdlen = 12; -+ CMD_TUNEREQUEST = 0x11, // cmd.len = 15; -+ -+ CMD_MPEG_ONOFF = 0x13, // cmd.len = 4; -+ CMD_MPEG_INIT = 0x14, // cmd.len = 7; -+ CMD_BANDWIDTH = 0x15, // cmd.len = 12; -+ CMD_CLOCK_READ = 0x16, // read clock from registers 0x01-0x06 -+ CMD_CLOCK_SET = 0x17, // cmd.len = 10; -+ -+ CMD_DISEQC_MSG1 = 0x20, // cmd.len = 11; -+ CMD_DISEQC_MSG2 = 0x21, // cmd.len = d->msg_len + 6; -+ CMD_SETVOLTAGE = 0x22, // cmd.len = 2; -+ CMD_SETTONE = 0x23, // cmd.len = 4; -+ CMD_DISEQC_BURST = 0x24, // cmd.len not used !!! -+ -+ CMD_READ_SNR = 0x1A, // Read signal strength -+ CMD_START_TUNER = 0x1B, // ??? -+ -+ CMD_TUNER_INIT = 0x3C, // cmd.len = 0x03; -+}; -+// ############################## -+/* signal status */ -+#define CX24120_HAS_SIGNAL (0x01) -+#define CX24120_HAS_CARRIER (0x02) -+#define CX24120_HAS_VITERBI (0x04) -+#define CX24120_HAS_LOCK (0x08) -+#define CX24120_HAS_UNK1 (0x10) -+#define CX24120_HAS_UNK2 (0x20) -+#define CX24120_STATUS_MASK (0x0f) -+#define CX24120_SIGNAL_MASK (0xc0) -+ -+static u8 cx24120_msg_tuner_init[] = { 0,0,0,0,0,0 }; -+static u8 cx24120_msg_read_sigstr[] = {0,0}; -+ -+static struct cx24120_skystar2_mpeg_config { -+ u8 x1; -+ u8 x2; -+ u8 x3; -+} initial_mpeg_config = { -+ 0xA1, // 10100001 -+ 0x76, // 01110110 -+ 0x07, // 00000111 -+}; -+ -+static struct cx24120_symrate_delay { -+ u32 symrate; -+ u32 delay; -+} symrates_pairs[] = { -+ { 3000000, 15000 }, -+ { 6000000, 10000 }, -+ { 8000000, 5000 }, -+ { 10000000, 2000 }, -+ {0x0FFFFFFFF, 400 }, -+}; -+ -+static struct cx24120_clock_ratios_table { -+ u32 ratio_id; -+ u32 mode_xPSK; -+ u32 fec_mode; -+ u32 m_rat; -+ u32 n_rat; -+ u32 rate; -+} clock_ratios_table[] = { -+{ 21 , 0 , 1 , 770068 , 763515 , 258 }, -+{ 21 , 0 , 100 , 97409 , 80370 , 310 }, -+{ 21 , 0 , 2 , 137293 , 101802 , 345 }, -+{ 21 , 0 , 3 , 4633447 , 3054060 , 388 }, -+{ 21 , 0 , 4 , 2472041 , 1527030 , 414 }, -+{ 21 , 0 , 5 , 85904 , 50901 , 432 }, -+{ 21 , 0 , 8 , 2751229 , 1527030 , 461 }, -+{ 21 , 0 , 101 , 1392872 , 763515 , 467 }, -+{ 21 , 99 , 100 , 1850771 , 1019430 , 464 }, -+{ 21 , 99 , 2 , 137293 , 67962 , 517 }, -+{ 21 , 99 , 3 , 4633447 , 2038860 , 581 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 21 , 99 , 5 , 85904 , 33981 , 647 }, -+{ 21 , 99 , 8 , 2751229 , 1019430 , 690 }, -+{ 21 , 99 , 101 , 1392872 , 509715 , 699 }, -+{ 29 , 0 , 1 , 770068 , 782127 , 252 }, -+{ 29 , 0 , 100 , 1850771 , 1564254 , 302 }, -+{ 29 , 0 , 2 , 686465 , 521418 , 337 }, -+{ 29 , 0 , 3 , 4633447 , 3128508 , 379 }, -+{ 29 , 0 , 4 , 2472041 , 1564254 , 404 }, -+{ 29 , 0 , 5 , 429520 , 260709 , 421 }, -+{ 29 , 0 , 8 , 2751229 , 1564254 , 450 }, -+{ 29 , 0 , 101 , 1392872 , 782127 , 455 }, -+{ 29 , 99 , 100 , 1850771 , 1043118 , 454 }, -+{ 29 , 99 , 2 , 686465 , 347706 , 505 }, -+{ 29 , 99 , 3 , 4633447 , 2086236 , 568 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 29 , 99 , 5 , 429520 , 173853 , 632 }, -+{ 29 , 99 , 8 , 2751229 , 1043118 , 675 }, -+{ 29 , 99 , 101 , 1392872 , 521559 , 683 }, -+{ 17 , 0 , 1 , 766052 , 763515 , 256 }, -+{ 17 , 0 , 100 , 96901 , 80370 , 308 }, -+{ 17 , 0 , 2 , 136577 , 101802 , 343 }, -+{ 17 , 0 , 3 , 4609283 , 3054060 , 386 }, -+{ 17 , 0 , 4 , 2459149 , 1527030 , 412 }, -+{ 17 , 0 , 5 , 85456 , 50901 , 429 }, -+{ 17 , 0 , 8 , 2736881 , 1527030 , 458 }, -+{ 17 , 0 , 101 , 1385608 , 763515 , 464 }, -+{ 17 , 99 , 100 , 1841119 , 1019430 , 462 }, -+{ 17 , 99 , 2 , 136577 , 67962 , 514 }, -+{ 17 , 99 , 3 , 4609283 , 2038860 , 578 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 17 , 99 , 5 , 85456 , 33981 , 643 }, -+{ 17 , 99 , 8 , 2736881 , 1019430 , 687 }, -+{ 17 , 99 , 101 , 1385608 , 509715 , 695 }, -+{ 25 , 0 , 1 , 766052 , 782127 , 250 }, -+{ 25 , 0 , 100 , 1841119 , 1564254 , 301 }, -+{ 25 , 0 , 2 , 682885 , 521418 , 335 }, -+{ 25 , 0 , 3 , 4609283 , 3128508 , 377 }, -+{ 25 , 0 , 4 , 2459149 , 1564254 , 402 }, -+{ 25 , 0 , 5 , 427280 , 260709 , 419 }, -+{ 25 , 0 , 8 , 2736881 , 1564254 , 447 }, -+{ 25 , 0 , 101 , 1385608 , 782127 , 453 }, -+{ 25 , 99 , 100 , 1841119 , 1043118 , 451 }, -+{ 25 , 99 , 2 , 682885 , 347706 , 502 }, -+{ 25 , 99 , 3 , 4609283 , 2086236 , 565 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 25 , 99 , 5 , 427280 , 173853 , 629 }, -+{ 25 , 99 , 8 , 2736881 , 1043118 , 671 }, -+{ 25 , 99 , 101 , 1385608 , 521559 , 680 }, -+{ 5 , 0 , 1 , 273088 , 254505 , 274 }, -+{ 5 , 0 , 100 , 17272 , 13395 , 330 }, -+{ 5 , 0 , 2 , 24344 , 16967 , 367 }, -+{ 5 , 0 , 3 , 410788 , 254505 , 413 }, -+{ 5 , 0 , 4 , 438328 , 254505 , 440 }, -+{ 5 , 0 , 5 , 30464 , 16967 , 459 }, -+{ 5 , 0 , 8 , 487832 , 254505 , 490 }, -+{ 5 , 0 , 101 , 493952 , 254505 , 496 }, -+{ 5 , 99 , 100 , 328168 , 169905 , 494 }, -+{ 5 , 99 , 2 , 24344 , 11327 , 550 }, // work for 0x0d - 11278V - DVB-S2 - 8PSK MPEG-4/HD -+{ 5 , 99 , 3 , 410788 , 169905 , 618 }, // 0x0e S2 8psk // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 5 , 99 , 5 , 30464 , 11327 , 688 }, -+{ 5 , 99 , 8 , 487832 , 169905 , 735 }, -+{ 5 , 99 , 101 , 493952 , 169905 , 744 }, -+{ 13 , 0 , 1 , 273088 , 260709 , 268 }, -+{ 13 , 0 , 100 , 328168 , 260709 , 322 }, -+{ 13 , 0 , 2 , 121720 , 86903 , 358 }, -+{ 13 , 0 , 3 , 410788 , 260709 , 403 }, -+{ 13 , 0 , 4 , 438328 , 260709 , 430 }, -+{ 13 , 0 , 5 , 152320 , 86903 , 448 }, -+{ 13 , 0 , 8 , 487832 , 260709 , 479 }, -+{ 13 , 0 , 101 , 493952 , 260709 , 485 }, -+{ 13 , 99 , 100 , 328168 , 173853 , 483 }, -+{ 13 , 99 , 2 , 121720 , 57951 , 537 }, // work for 0x8d - dvb-s2 8psk -+{ 13 , 99 , 3 , 410788 , 173853 , 604 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 13 , 99 , 5 , 152320 , 57951 , 672 }, -+{ 13 , 99 , 8 , 487832 , 173853 , 718 }, -+{ 13 , 99 , 101 , 493952 , 173853 , 727 }, -+{ 1 , 0 , 1 , 815248 , 763515 , 273 }, -+{ 1 , 0 , 100 , 51562 , 40185 , 328 }, -+{ 1 , 0 , 2 , 72674 , 50901 , 365 }, -+{ 1 , 0 , 3 , 1226323 , 763515 , 411 }, -+{ 1 , 0 , 4 , 1308538 , 763515 , 438 }, -+{ 1 , 0 , 5 , 90944 , 50901 , 457 }, -+{ 1 , 0 , 8 , 1456322 , 763515 , 488 }, -+{ 1 , 0 , 101 , 1474592 , 763515 , 494 }, -+{ 1 , 99 , 100 , 979678 , 509715 , 492 }, -+{ 1 , 99 , 2 , 72674 , 33981 , 547 }, -+{ 1 , 99 , 3 , 1226323 , 509715 , 615 }, // was 4 - ERRORR!? FEC_4_5 not in DVB-S2 -+{ 1 , 99 , 5 , 90944 , 33981 , 685 }, -+{ 1 , 99 , 8 , 1456322 , 509715 , 731 }, -+{ 1 , 99 , 101 , 1474592 , 509715 , 740 }, -+{ 9 , 0 , 1 , 815248 , 782127 , 266 }, -+{ 9 , 0 , 100 , 979678 , 782127 , 320 }, -+{ 9 , 0 , 2 , 363370 , 260709 , 356 }, -+{ 9 , 0 , 3 , 1226323 , 782127 , 401 }, -+{ 9 , 0 , 4 , 1308538 , 782127 , 428 }, -+{ 9 , 0 , 5 , 454720 , 260709 , 446 }, -+{ 9 , 0 , 8 , 1456322 , 782127 , 476 }, -+{ 9 , 0 , 101 , 1474592 , 782127 , 482 }, -+{ 9 , 99 , 100 , 979678 , 521559 , 480 }, -+{ 9 , 99 , 2 , 363370 , 173853 , 535 }, -+{ 9 , 99 , 3 , 1226323 , 521559 , 601 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 -+{ 9 , 99 , 5 , 454720 , 173853 , 669 }, -+{ 9 , 99 , 8 , 1456322 , 521559 , 714 }, -+{ 9 , 99 , 101 , 1474592 , 521559 , 723 }, -+{ 18 , 0 , 1 , 535 , 588 , 233 }, -+{ 18 , 0 , 2 , 1070 , 882 , 311 }, -+{ 18 , 0 , 6 , 3210 , 2058 , 399 }, -+{ 16 , 0 , 1 , 763 , 816 , 239 }, -+{ 16 , 0 , 2 , 1526 , 1224 , 319 }, -+{ 16 , 0 , 3 , 2289 , 1632 , 359 }, -+{ 16 , 0 , 5 , 3815 , 2448 , 399 }, -+{ 16 , 0 , 7 , 5341 , 3264 , 419 }, -+{ 22 , 0 , 1 , 535 , 588 , 233 }, -+{ 22 , 0 , 2 , 1070 , 882 , 311 }, -+{ 22 , 0 , 6 , 3210 , 2058 , 399 }, -+{ 20 , 0 , 1 , 143429 , 152592 , 241 }, -+{ 20 , 0 , 2 , 286858 , 228888 , 321 }, -+{ 20 , 0 , 3 , 430287 , 305184 , 361 }, -+{ 20 , 0 , 5 , 717145 , 457776 , 401 }, -+{ 20 , 0 , 7 , 1004003 , 610368 , 421 }, -+{ 2 , 0 , 1 , 584 , 588 , 254 }, -+{ 2 , 0 , 2 , 1169 , 882 , 339 }, -+{ 2 , 0 , 6 , 3507 , 2058 , 436 }, -+{ 0 , 0 , 1 , 812 , 816 , 255 }, -+{ 0 , 0 , 2 , 1624 , 1224 , 340 }, -+{ 0 , 0 , 3 , 2436 , 1632 , 382 }, -+{ 0 , 0 , 5 , 4060 , 2448 , 425 }, -+{ 0 , 0 , 7 , 5684 , 3264 , 446 }, -+{ 6 , 0 , 1 , 584 , 588 , 254 }, -+{ 6 , 0 , 2 , 1168 , 882 , 339 }, -+{ 6 , 0 , 6 , 3504 , 2058 , 436 }, -+{ 4 , 0 , 1 , 152592 , 152592 , 256 }, -+{ 4 , 0 , 2 , 305184 , 228888 , 341 }, -+{ 4 , 0 , 3 , 457776 , 305184 , 384 }, -+{ 4 , 0 , 5 , 762960 , 457776 , 427 }, -+{ 4 , 0 , 7 , 1068144 , 610368 , 448 }, -+}; -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/cx24120.h linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.h ---- linux-3.4-r1/drivers/media/dvb-frontends/cx24120.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.h 2012-04-03 10:27:59.000000000 +0400 -@@ -0,0 +1,59 @@ -+/* -+ * Conexant CX24120/CX24118 - DVB-S/S2 demod/tuner driver -+ * -+ * Copyright (C) 2008 Patrick Boettcher -+ * Copyright (C) 2009 Sergey Tyurin -+ * Updated 2012 by Jannis Achstetter -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef CX24120_H -+#define CX24120_H -+ -+#include -+ -+struct firmware; -+struct dvb_frontend; -+struct i2c_adapter; -+ -+struct cx24120_config -+{ -+ u8 i2c_addr; -+ int (*request_firmware)(struct dvb_frontend *fe, const struct firmware **fw, char *name); -+ void (*stream_control)(struct dvb_frontend *fe, u8 onoff); -+}; -+ -+#if defined(CONFIG_DVB_CX24120) || \ -+ (defined(CONFIG_DVB_CX24120_MODULE) && defined(MODULE)) -+extern struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, -+ struct i2c_adapter *i2c); -+extern int cx24120_reset(struct dvb_frontend *fe); -+#else -+static inline -+struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, -+ struct i2c_adapter *i2c) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+static inline int cx24120_reset(struct dvb_frontend *fe) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return -ENODEV; -+} -+#endif -+ -+#endif -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/Kconfig linux-3.4-r1-S2/drivers/media/dvb-frontends/Kconfig ---- linux-3.4-r1/drivers/media/dvb-frontends/Kconfig 2012-04-03 15:23:44.976143444 +0400 -+++ linux-3.4-r1-S2/drivers/media/dvb-frontends/Kconfig 2012-04-03 15:26:40.760141513 +0400 -@@ -4,6 +4,13 @@ - comment "Multistandard (satellite) frontends" - depends on DVB_CORE - -+config DVB_CX24120 -+ tristate "Conexant CX24120 based" -+ depends on DVB_CORE && I2C -+ default m if DVB_FE_CUSTOMISE -+ help -+ A DVB-S/DVB-S2 tuner module. Say Y when you want to support this frontend. -+ - config DVB_STB0899 - tristate "STB0899 based" - depends on DVB_CORE && I2C -diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/Makefile linux-3.4-r1-S2/drivers/media/dvb-frontends/Makefile ---- linux-3.4-r1/drivers/media/dvb-frontends/Makefile 2012-04-03 15:23:44.976143444 +0400 -+++ linux-3.4-r1-S2/drivers/media/dvb-frontends/Makefile 2012-04-03 15:26:40.760141513 +0400 -@@ -19,6 +19,10 @@ - obj-$(CONFIG_DVB_CX22700) += cx22700.o - obj-$(CONFIG_DVB_S5H1432) += s5h1432.o - obj-$(CONFIG_DVB_CX24110) += cx24110.o -+ -+# inserted by Custler -+obj-$(CONFIG_DVB_CX24120) += cx24120.o -+ - obj-$(CONFIG_DVB_TDA8083) += tda8083.o - obj-$(CONFIG_DVB_L64781) += l64781.o - obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o diff --git a/packages/linux/patches/4.1.12/linux-999.20-mt7601u-support.patch b/packages/linux/patches/4.1.12/linux-999.20-mt7601u-support.patch deleted file mode 100644 index ced85aad74..0000000000 --- a/packages/linux/patches/4.1.12/linux-999.20-mt7601u-support.patch +++ /dev/null @@ -1,8192 +0,0 @@ -From 5d2b422d7f7d495c0710c17b195351f9b7be5f63 Mon Sep 17 00:00:00 2001 -From: Robert Nelson -Date: Mon, 20 Jul 2015 10:48:10 -0500 -Subject: [PATCH] backport: mediatek: mt7601u: from v4.2-rc3 - -Signed-off-by: Robert Nelson ---- - drivers/net/wireless/Kconfig | 1 + - drivers/net/wireless/Makefile | 2 + - drivers/net/wireless/mediatek/Kconfig | 10 + - drivers/net/wireless/mediatek/Makefile | 1 + - drivers/net/wireless/mediatek/mt7601u/Kconfig | 6 + - drivers/net/wireless/mediatek/mt7601u/Makefile | 9 + - drivers/net/wireless/mediatek/mt7601u/core.c | 78 ++ - drivers/net/wireless/mediatek/mt7601u/debugfs.c | 172 +++ - drivers/net/wireless/mediatek/mt7601u/dma.c | 505 ++++++++ - drivers/net/wireless/mediatek/mt7601u/dma.h | 127 ++ - drivers/net/wireless/mediatek/mt7601u/eeprom.c | 418 +++++++ - drivers/net/wireless/mediatek/mt7601u/eeprom.h | 151 +++ - drivers/net/wireless/mediatek/mt7601u/init.c | 628 ++++++++++ - drivers/net/wireless/mediatek/mt7601u/initvals.h | 164 +++ - .../net/wireless/mediatek/mt7601u/initvals_phy.h | 291 +++++ - drivers/net/wireless/mediatek/mt7601u/mac.c | 573 +++++++++ - drivers/net/wireless/mediatek/mt7601u/mac.h | 178 +++ - drivers/net/wireless/mediatek/mt7601u/main.c | 413 +++++++ - drivers/net/wireless/mediatek/mt7601u/mcu.c | 534 +++++++++ - drivers/net/wireless/mediatek/mt7601u/mcu.h | 94 ++ - drivers/net/wireless/mediatek/mt7601u/mt7601u.h | 390 ++++++ - drivers/net/wireless/mediatek/mt7601u/phy.c | 1251 ++++++++++++++++++++ - drivers/net/wireless/mediatek/mt7601u/regs.h | 636 ++++++++++ - drivers/net/wireless/mediatek/mt7601u/trace.c | 21 + - drivers/net/wireless/mediatek/mt7601u/trace.h | 400 +++++++ - drivers/net/wireless/mediatek/mt7601u/tx.c | 319 +++++ - drivers/net/wireless/mediatek/mt7601u/usb.c | 367 ++++++ - drivers/net/wireless/mediatek/mt7601u/usb.h | 77 ++ - drivers/net/wireless/mediatek/mt7601u/util.c | 42 + - drivers/net/wireless/mediatek/mt7601u/util.h | 77 ++ - 30 files changed, 7935 insertions(+) - create mode 100644 drivers/net/wireless/mediatek/Kconfig - create mode 100644 drivers/net/wireless/mediatek/Makefile - create mode 100644 drivers/net/wireless/mediatek/mt7601u/Kconfig - create mode 100644 drivers/net/wireless/mediatek/mt7601u/Makefile - create mode 100644 drivers/net/wireless/mediatek/mt7601u/core.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/debugfs.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/dma.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/dma.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/eeprom.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/eeprom.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/init.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/initvals.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/initvals_phy.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/mac.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/mac.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/main.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/mcu.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/mcu.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/mt7601u.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/phy.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/regs.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/trace.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/trace.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/tx.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/usb.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/usb.h - create mode 100644 drivers/net/wireless/mediatek/mt7601u/util.c - create mode 100644 drivers/net/wireless/mediatek/mt7601u/util.h - -diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig -index ea4d54f..8e0a4bb 100644 ---- a/drivers/net/wireless/Kconfig -+++ b/drivers/net/wireless/Kconfig -@@ -277,6 +277,7 @@ source "drivers/net/wireless/libertas/Kconfig" - source "drivers/net/wireless/orinoco/Kconfig" - source "drivers/net/wireless/p54/Kconfig" - source "drivers/net/wireless/rt2x00/Kconfig" -+source "drivers/net/wireless/mediatek/Kconfig" - source "drivers/net/wireless/rtlwifi/Kconfig" - source "drivers/net/wireless/ti/Kconfig" - source "drivers/net/wireless/zd1211rw/Kconfig" -diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile -index 2971041..8e007e3 100644 ---- a/drivers/net/wireless/Makefile -+++ b/drivers/net/wireless/Makefile -@@ -46,6 +46,8 @@ obj-$(CONFIG_IWLWIFI) += iwlwifi/ - obj-$(CONFIG_IWLEGACY) += iwlegacy/ - obj-$(CONFIG_RT2X00) += rt2x00/ - -+obj-$(CONFIG_WL_MEDIATEK) += mediatek/ -+ - obj-$(CONFIG_P54_COMMON) += p54/ - - obj-$(CONFIG_ATH_CARDS) += ath/ -diff --git a/drivers/net/wireless/mediatek/Kconfig b/drivers/net/wireless/mediatek/Kconfig -new file mode 100644 -index 0000000..cba300c ---- /dev/null -+++ b/drivers/net/wireless/mediatek/Kconfig -@@ -0,0 +1,10 @@ -+menuconfig WL_MEDIATEK -+ bool "Mediatek Wireless LAN support" -+ ---help--- -+ Enable community drivers for MediaTek WiFi devices. -+ Those drivers make use of the Linux mac80211 stack. -+ -+ -+if WL_MEDIATEK -+source "drivers/net/wireless/mediatek/mt7601u/Kconfig" -+endif # WL_MEDIATEK -diff --git a/drivers/net/wireless/mediatek/Makefile b/drivers/net/wireless/mediatek/Makefile -new file mode 100644 -index 0000000..9d5f182 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_MT7601U) += mt7601u/ -diff --git a/drivers/net/wireless/mediatek/mt7601u/Kconfig b/drivers/net/wireless/mediatek/mt7601u/Kconfig -new file mode 100644 -index 0000000..f46bed9 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/Kconfig -@@ -0,0 +1,6 @@ -+config MT7601U -+ tristate "MediaTek MT7601U (USB) support" -+ depends on MAC80211 -+ depends on USB -+ ---help--- -+ This adds support for MT7601U-based wireless USB dongles. -diff --git a/drivers/net/wireless/mediatek/mt7601u/Makefile b/drivers/net/wireless/mediatek/mt7601u/Makefile -new file mode 100644 -index 0000000..ea9ed8a ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/Makefile -@@ -0,0 +1,9 @@ -+ccflags-y += -D__CHECK_ENDIAN__ -+ -+obj-$(CONFIG_MT7601U) += mt7601u.o -+ -+mt7601u-objs = \ -+ usb.o init.o main.o mcu.o trace.o dma.o core.o eeprom.o phy.o \ -+ mac.o util.o debugfs.o tx.o -+ -+CFLAGS_trace.o := -I$(src) -diff --git a/drivers/net/wireless/mediatek/mt7601u/core.c b/drivers/net/wireless/mediatek/mt7601u/core.c -new file mode 100644 -index 0000000..0aabd79 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/core.c -@@ -0,0 +1,78 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+ -+int mt7601u_wait_asic_ready(struct mt7601u_dev *dev) -+{ -+ int i = 100; -+ u32 val; -+ -+ do { -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return -EIO; -+ -+ val = mt7601u_rr(dev, MT_MAC_CSR0); -+ if (val && ~val) -+ return 0; -+ -+ udelay(10); -+ } while (i--); -+ -+ return -EIO; -+} -+ -+bool mt76_poll(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, -+ int timeout) -+{ -+ u32 cur; -+ -+ timeout /= 10; -+ do { -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return false; -+ -+ cur = mt7601u_rr(dev, offset) & mask; -+ if (cur == val) -+ return true; -+ -+ udelay(10); -+ } while (timeout-- > 0); -+ -+ dev_err(dev->dev, "Error: Time out with reg %08x\n", offset); -+ -+ return false; -+} -+ -+bool mt76_poll_msec(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, -+ int timeout) -+{ -+ u32 cur; -+ -+ timeout /= 10; -+ do { -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return false; -+ -+ cur = mt7601u_rr(dev, offset) & mask; -+ if (cur == val) -+ return true; -+ -+ msleep(10); -+ } while (timeout-- > 0); -+ -+ dev_err(dev->dev, "Error: Time out with reg %08x\n", offset); -+ -+ return false; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/debugfs.c b/drivers/net/wireless/mediatek/mt7601u/debugfs.c -new file mode 100644 -index 0000000..fc008475 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/debugfs.c -@@ -0,0 +1,172 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+ -+#include "mt7601u.h" -+#include "eeprom.h" -+ -+static int -+mt76_reg_set(void *data, u64 val) -+{ -+ struct mt7601u_dev *dev = data; -+ -+ mt76_wr(dev, dev->debugfs_reg, val); -+ return 0; -+} -+ -+static int -+mt76_reg_get(void *data, u64 *val) -+{ -+ struct mt7601u_dev *dev = data; -+ -+ *val = mt76_rr(dev, dev->debugfs_reg); -+ return 0; -+} -+ -+DEFINE_SIMPLE_ATTRIBUTE(fops_regval, mt76_reg_get, mt76_reg_set, "0x%08llx\n"); -+ -+static int -+mt7601u_ampdu_stat_read(struct seq_file *file, void *data) -+{ -+ struct mt7601u_dev *dev = file->private; -+ int i, j; -+ -+#define stat_printf(grp, off, name) \ -+ seq_printf(file, #name ":\t%llu\n", dev->stats.grp[off]) -+ -+ stat_printf(rx_stat, 0, rx_crc_err); -+ stat_printf(rx_stat, 1, rx_phy_err); -+ stat_printf(rx_stat, 2, rx_false_cca); -+ stat_printf(rx_stat, 3, rx_plcp_err); -+ stat_printf(rx_stat, 4, rx_fifo_overflow); -+ stat_printf(rx_stat, 5, rx_duplicate); -+ -+ stat_printf(tx_stat, 0, tx_fail_cnt); -+ stat_printf(tx_stat, 1, tx_bcn_cnt); -+ stat_printf(tx_stat, 2, tx_success); -+ stat_printf(tx_stat, 3, tx_retransmit); -+ stat_printf(tx_stat, 4, tx_zero_len); -+ stat_printf(tx_stat, 5, tx_underflow); -+ -+ stat_printf(aggr_stat, 0, non_aggr_tx); -+ stat_printf(aggr_stat, 1, aggr_tx); -+ -+ stat_printf(zero_len_del, 0, tx_zero_len_del); -+ stat_printf(zero_len_del, 1, rx_zero_len_del); -+#undef stat_printf -+ -+ seq_puts(file, "Aggregations stats:\n"); -+ for (i = 0; i < 4; i++) { -+ for (j = 0; j < 8; j++) -+ seq_printf(file, "%08llx ", -+ dev->stats.aggr_n[i * 8 + j]); -+ seq_putc(file, '\n'); -+ } -+ -+ seq_printf(file, "recent average AMPDU len: %d\n", -+ atomic_read(&dev->avg_ampdu_len)); -+ -+ return 0; -+} -+ -+static int -+mt7601u_ampdu_stat_open(struct inode *inode, struct file *f) -+{ -+ return single_open(f, mt7601u_ampdu_stat_read, inode->i_private); -+} -+ -+static const struct file_operations fops_ampdu_stat = { -+ .open = mt7601u_ampdu_stat_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int -+mt7601u_eeprom_param_read(struct seq_file *file, void *data) -+{ -+ struct mt7601u_dev *dev = file->private; -+ struct mt7601u_rate_power *rp = &dev->ee->power_rate_table; -+ struct tssi_data *td = &dev->ee->tssi_data; -+ int i; -+ -+ seq_printf(file, "RF freq offset: %hhx\n", dev->ee->rf_freq_off); -+ seq_printf(file, "RSSI offset: %hhx %hhx\n", -+ dev->ee->rssi_offset[0], dev->ee->rssi_offset[1]); -+ seq_printf(file, "Reference temp: %hhx\n", dev->ee->ref_temp); -+ seq_printf(file, "LNA gain: %hhx\n", dev->ee->lna_gain); -+ seq_printf(file, "Reg channels: %hhu-%hhu\n", dev->ee->reg.start, -+ dev->ee->reg.start + dev->ee->reg.num - 1); -+ -+ seq_puts(file, "Per rate power:\n"); -+ for (i = 0; i < 2; i++) -+ seq_printf(file, "\t raw:%02hhx bw20:%02hhx bw40:%02hhx\n", -+ rp->cck[i].raw, rp->cck[i].bw20, rp->cck[i].bw40); -+ for (i = 0; i < 4; i++) -+ seq_printf(file, "\t raw:%02hhx bw20:%02hhx bw40:%02hhx\n", -+ rp->ofdm[i].raw, rp->ofdm[i].bw20, rp->ofdm[i].bw40); -+ for (i = 0; i < 4; i++) -+ seq_printf(file, "\t raw:%02hhx bw20:%02hhx bw40:%02hhx\n", -+ rp->ht[i].raw, rp->ht[i].bw20, rp->ht[i].bw40); -+ -+ seq_puts(file, "Per channel power:\n"); -+ for (i = 0; i < 7; i++) -+ seq_printf(file, "\t tx_power ch%u:%02hhx ch%u:%02hhx\n", -+ i * 2 + 1, dev->ee->chan_pwr[i * 2], -+ i * 2 + 2, dev->ee->chan_pwr[i * 2 + 1]); -+ -+ if (!dev->ee->tssi_enabled) -+ return 0; -+ -+ seq_puts(file, "TSSI:\n"); -+ seq_printf(file, "\t slope:%02hhx\n", td->slope); -+ seq_printf(file, "\t offset=%02hhx %02hhx %02hhx\n", -+ td->offset[0], td->offset[1], td->offset[2]); -+ seq_printf(file, "\t delta_off:%08x\n", td->tx0_delta_offset); -+ -+ return 0; -+} -+ -+static int -+mt7601u_eeprom_param_open(struct inode *inode, struct file *f) -+{ -+ return single_open(f, mt7601u_eeprom_param_read, inode->i_private); -+} -+ -+static const struct file_operations fops_eeprom_param = { -+ .open = mt7601u_eeprom_param_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+void mt7601u_init_debugfs(struct mt7601u_dev *dev) -+{ -+ struct dentry *dir; -+ -+ dir = debugfs_create_dir("mt7601u", dev->hw->wiphy->debugfsdir); -+ if (!dir) -+ return; -+ -+ debugfs_create_u8("temperature", S_IRUSR, dir, &dev->raw_temp); -+ debugfs_create_u32("temp_mode", S_IRUSR, dir, &dev->temp_mode); -+ -+ debugfs_create_u32("regidx", S_IRUSR | S_IWUSR, dir, &dev->debugfs_reg); -+ debugfs_create_file("regval", S_IRUSR | S_IWUSR, dir, dev, -+ &fops_regval); -+ debugfs_create_file("ampdu_stat", S_IRUSR, dir, dev, &fops_ampdu_stat); -+ debugfs_create_file("eeprom_param", S_IRUSR, dir, dev, -+ &fops_eeprom_param); -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c -new file mode 100644 -index 0000000..7217da4 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/dma.c -@@ -0,0 +1,505 @@ -+/* -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+#include "dma.h" -+#include "usb.h" -+#include "trace.h" -+ -+static int mt7601u_submit_rx_buf(struct mt7601u_dev *dev, -+ struct mt7601u_dma_buf_rx *e, gfp_t gfp); -+ -+static unsigned int ieee80211_get_hdrlen_from_buf(const u8 *data, unsigned len) -+{ -+ const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data; -+ unsigned int hdrlen; -+ -+ if (unlikely(len < 10)) -+ return 0; -+ hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ if (unlikely(hdrlen > len)) -+ return 0; -+ return hdrlen; -+} -+ -+static struct sk_buff * -+mt7601u_rx_skb_from_seg(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi, -+ void *data, u32 seg_len, u32 truesize, struct page *p) -+{ -+ struct sk_buff *skb; -+ u32 true_len, hdr_len = 0, copy, frag; -+ -+ skb = alloc_skb(p ? 128 : seg_len, GFP_ATOMIC); -+ if (!skb) -+ return NULL; -+ -+ true_len = mt76_mac_process_rx(dev, skb, data, rxwi); -+ if (!true_len || true_len > seg_len) -+ goto bad_frame; -+ -+ hdr_len = ieee80211_get_hdrlen_from_buf(data, true_len); -+ if (!hdr_len) -+ goto bad_frame; -+ -+ if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) { -+ memcpy(skb_put(skb, hdr_len), data, hdr_len); -+ -+ data += hdr_len + 2; -+ true_len -= hdr_len; -+ hdr_len = 0; -+ } -+ -+ /* If not doing paged RX allocated skb will always have enough space */ -+ copy = (true_len <= skb_tailroom(skb)) ? true_len : hdr_len + 8; -+ frag = true_len - copy; -+ -+ memcpy(skb_put(skb, copy), data, copy); -+ data += copy; -+ -+ if (frag) { -+ skb_add_rx_frag(skb, 0, p, data - page_address(p), -+ frag, truesize); -+ get_page(p); -+ } -+ -+ return skb; -+ -+bad_frame: -+ dev_err_ratelimited(dev->dev, "Error: incorrect frame len:%u hdr:%u\n", -+ true_len, hdr_len); -+ dev_kfree_skb(skb); -+ return NULL; -+} -+ -+static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data, -+ u32 seg_len, struct page *p) -+{ -+ struct sk_buff *skb; -+ struct mt7601u_rxwi *rxwi; -+ u32 fce_info, truesize = seg_len; -+ -+ /* DMA_INFO field at the beginning of the segment contains only some of -+ * the information, we need to read the FCE descriptor from the end. -+ */ -+ fce_info = get_unaligned_le32(data + seg_len - MT_FCE_INFO_LEN); -+ seg_len -= MT_FCE_INFO_LEN; -+ -+ data += MT_DMA_HDR_LEN; -+ seg_len -= MT_DMA_HDR_LEN; -+ -+ rxwi = (struct mt7601u_rxwi *) data; -+ data += sizeof(struct mt7601u_rxwi); -+ seg_len -= sizeof(struct mt7601u_rxwi); -+ -+ if (unlikely(rxwi->zero[0] || rxwi->zero[1] || rxwi->zero[2])) -+ dev_err_once(dev->dev, "Error: RXWI zero fields are set\n"); -+ if (unlikely(MT76_GET(MT_RXD_INFO_TYPE, fce_info))) -+ dev_err_once(dev->dev, "Error: RX path seen a non-pkt urb\n"); -+ -+ trace_mt_rx(dev, rxwi, fce_info); -+ -+ skb = mt7601u_rx_skb_from_seg(dev, rxwi, data, seg_len, truesize, p); -+ if (!skb) -+ return; -+ -+ ieee80211_rx_ni(dev->hw, skb); -+} -+ -+static u16 mt7601u_rx_next_seg_len(u8 *data, u32 data_len) -+{ -+ u32 min_seg_len = MT_DMA_HDR_LEN + MT_RX_INFO_LEN + -+ sizeof(struct mt7601u_rxwi) + MT_FCE_INFO_LEN; -+ u16 dma_len = get_unaligned_le16(data); -+ -+ if (data_len < min_seg_len || -+ WARN_ON(!dma_len) || -+ WARN_ON(dma_len + MT_DMA_HDRS > data_len) || -+ WARN_ON(dma_len & 0x3)) -+ return 0; -+ -+ return MT_DMA_HDRS + dma_len; -+} -+ -+static void -+mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e) -+{ -+ u32 seg_len, data_len = e->urb->actual_length; -+ u8 *data = page_address(e->p); -+ struct page *new_p = NULL; -+ int cnt = 0; -+ -+ if (!test_bit(MT7601U_STATE_INITIALIZED, &dev->state)) -+ return; -+ -+ /* Copy if there is very little data in the buffer. */ -+ if (data_len > 512) -+ new_p = dev_alloc_pages(MT_RX_ORDER); -+ -+ while ((seg_len = mt7601u_rx_next_seg_len(data, data_len))) { -+ mt7601u_rx_process_seg(dev, data, seg_len, new_p ? e->p : NULL); -+ -+ data_len -= seg_len; -+ data += seg_len; -+ cnt++; -+ } -+ -+ if (cnt > 1) -+ trace_mt_rx_dma_aggr(dev, cnt, !!new_p); -+ -+ if (new_p) { -+ /* we have one extra ref from the allocator */ -+ __free_pages(e->p, MT_RX_ORDER); -+ -+ e->p = new_p; -+ } -+} -+ -+static struct mt7601u_dma_buf_rx * -+mt7601u_rx_get_pending_entry(struct mt7601u_dev *dev) -+{ -+ struct mt7601u_rx_queue *q = &dev->rx_q; -+ struct mt7601u_dma_buf_rx *buf = NULL; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->rx_lock, flags); -+ -+ if (!q->pending) -+ goto out; -+ -+ buf = &q->e[q->start]; -+ q->pending--; -+ q->start = (q->start + 1) % q->entries; -+out: -+ spin_unlock_irqrestore(&dev->rx_lock, flags); -+ -+ return buf; -+} -+ -+static void mt7601u_complete_rx(struct urb *urb) -+{ -+ struct mt7601u_dev *dev = urb->context; -+ struct mt7601u_rx_queue *q = &dev->rx_q; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->rx_lock, flags); -+ -+ if (mt7601u_urb_has_error(urb)) -+ dev_err(dev->dev, "Error: RX urb failed:%d\n", urb->status); -+ if (WARN_ONCE(q->e[q->end].urb != urb, "RX urb mismatch")) -+ goto out; -+ -+ q->end = (q->end + 1) % q->entries; -+ q->pending++; -+ tasklet_schedule(&dev->rx_tasklet); -+out: -+ spin_unlock_irqrestore(&dev->rx_lock, flags); -+} -+ -+static void mt7601u_rx_tasklet(unsigned long data) -+{ -+ struct mt7601u_dev *dev = (struct mt7601u_dev *) data; -+ struct mt7601u_dma_buf_rx *e; -+ -+ while ((e = mt7601u_rx_get_pending_entry(dev))) { -+ if (e->urb->status) -+ continue; -+ -+ mt7601u_rx_process_entry(dev, e); -+ mt7601u_submit_rx_buf(dev, e, GFP_ATOMIC); -+ } -+} -+ -+static void mt7601u_complete_tx(struct urb *urb) -+{ -+ struct mt7601u_tx_queue *q = urb->context; -+ struct mt7601u_dev *dev = q->dev; -+ struct sk_buff *skb; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->tx_lock, flags); -+ -+ if (mt7601u_urb_has_error(urb)) -+ dev_err(dev->dev, "Error: TX urb failed:%d\n", urb->status); -+ if (WARN_ONCE(q->e[q->start].urb != urb, "TX urb mismatch")) -+ goto out; -+ -+ skb = q->e[q->start].skb; -+ trace_mt_tx_dma_done(dev, skb); -+ -+ mt7601u_tx_status(dev, skb); -+ -+ if (q->used == q->entries - q->entries / 8) -+ ieee80211_wake_queue(dev->hw, skb_get_queue_mapping(skb)); -+ -+ q->start = (q->start + 1) % q->entries; -+ q->used--; -+ -+ if (urb->status) -+ goto out; -+ -+ set_bit(MT7601U_STATE_MORE_STATS, &dev->state); -+ if (!test_and_set_bit(MT7601U_STATE_READING_STATS, &dev->state)) -+ queue_delayed_work(dev->stat_wq, &dev->stat_work, -+ msecs_to_jiffies(10)); -+out: -+ spin_unlock_irqrestore(&dev->tx_lock, flags); -+} -+ -+static int mt7601u_dma_submit_tx(struct mt7601u_dev *dev, -+ struct sk_buff *skb, u8 ep) -+{ -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ unsigned snd_pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[ep]); -+ struct mt7601u_dma_buf_tx *e; -+ struct mt7601u_tx_queue *q = &dev->tx_q[ep]; -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&dev->tx_lock, flags); -+ -+ if (WARN_ON(q->entries <= q->used)) { -+ ret = -ENOSPC; -+ goto out; -+ } -+ -+ e = &q->e[q->end]; -+ e->skb = skb; -+ usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len, -+ mt7601u_complete_tx, q); -+ ret = usb_submit_urb(e->urb, GFP_ATOMIC); -+ if (ret) { -+ /* Special-handle ENODEV from TX urb submission because it will -+ * often be the first ENODEV we see after device is removed. -+ */ -+ if (ret == -ENODEV) -+ set_bit(MT7601U_STATE_REMOVED, &dev->state); -+ else -+ dev_err(dev->dev, "Error: TX urb submit failed:%d\n", -+ ret); -+ goto out; -+ } -+ -+ q->end = (q->end + 1) % q->entries; -+ q->used++; -+ -+ if (q->used >= q->entries) -+ ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb)); -+out: -+ spin_unlock_irqrestore(&dev->tx_lock, flags); -+ -+ return ret; -+} -+ -+/* Map hardware Q to USB endpoint number */ -+static u8 q2ep(u8 qid) -+{ -+ /* TODO: take management packets to queue 5 */ -+ return qid + 1; -+} -+ -+/* Map USB endpoint number to Q id in the DMA engine */ -+static enum mt76_qsel ep2dmaq(u8 ep) -+{ -+ if (ep == 5) -+ return MT_QSEL_MGMT; -+ return MT_QSEL_EDCA; -+} -+ -+int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb, -+ struct mt76_wcid *wcid, int hw_q) -+{ -+ u8 ep = q2ep(hw_q); -+ u32 dma_flags; -+ int ret; -+ -+ dma_flags = MT_TXD_PKT_INFO_80211; -+ if (wcid->hw_key_idx == 0xff) -+ dma_flags |= MT_TXD_PKT_INFO_WIV; -+ -+ ret = mt7601u_dma_skb_wrap_pkt(skb, ep2dmaq(ep), dma_flags); -+ if (ret) -+ return ret; -+ -+ ret = mt7601u_dma_submit_tx(dev, skb, ep); -+ if (ret) { -+ ieee80211_free_txskb(dev->hw, skb); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void mt7601u_kill_rx(struct mt7601u_dev *dev) -+{ -+ int i; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->rx_lock, flags); -+ -+ for (i = 0; i < dev->rx_q.entries; i++) { -+ int next = dev->rx_q.end; -+ -+ spin_unlock_irqrestore(&dev->rx_lock, flags); -+ usb_poison_urb(dev->rx_q.e[next].urb); -+ spin_lock_irqsave(&dev->rx_lock, flags); -+ } -+ -+ spin_unlock_irqrestore(&dev->rx_lock, flags); -+} -+ -+static int mt7601u_submit_rx_buf(struct mt7601u_dev *dev, -+ struct mt7601u_dma_buf_rx *e, gfp_t gfp) -+{ -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ u8 *buf = page_address(e->p); -+ unsigned pipe; -+ int ret; -+ -+ pipe = usb_rcvbulkpipe(usb_dev, dev->in_eps[MT_EP_IN_PKT_RX]); -+ -+ usb_fill_bulk_urb(e->urb, usb_dev, pipe, buf, MT_RX_URB_SIZE, -+ mt7601u_complete_rx, dev); -+ -+ trace_mt_submit_urb(dev, e->urb); -+ ret = usb_submit_urb(e->urb, gfp); -+ if (ret) -+ dev_err(dev->dev, "Error: submit RX URB failed:%d\n", ret); -+ -+ return ret; -+} -+ -+static int mt7601u_submit_rx(struct mt7601u_dev *dev) -+{ -+ int i, ret; -+ -+ for (i = 0; i < dev->rx_q.entries; i++) { -+ ret = mt7601u_submit_rx_buf(dev, &dev->rx_q.e[i], GFP_KERNEL); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void mt7601u_free_rx(struct mt7601u_dev *dev) -+{ -+ int i; -+ -+ for (i = 0; i < dev->rx_q.entries; i++) { -+ __free_pages(dev->rx_q.e[i].p, MT_RX_ORDER); -+ usb_free_urb(dev->rx_q.e[i].urb); -+ } -+} -+ -+static int mt7601u_alloc_rx(struct mt7601u_dev *dev) -+{ -+ int i; -+ -+ memset(&dev->rx_q, 0, sizeof(dev->rx_q)); -+ dev->rx_q.dev = dev; -+ dev->rx_q.entries = N_RX_ENTRIES; -+ -+ for (i = 0; i < N_RX_ENTRIES; i++) { -+ dev->rx_q.e[i].urb = usb_alloc_urb(0, GFP_KERNEL); -+ dev->rx_q.e[i].p = dev_alloc_pages(MT_RX_ORDER); -+ -+ if (!dev->rx_q.e[i].urb || !dev->rx_q.e[i].p) -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static void mt7601u_free_tx_queue(struct mt7601u_tx_queue *q) -+{ -+ int i; -+ -+ WARN_ON(q->used); -+ -+ for (i = 0; i < q->entries; i++) { -+ usb_poison_urb(q->e[i].urb); -+ usb_free_urb(q->e[i].urb); -+ } -+} -+ -+static void mt7601u_free_tx(struct mt7601u_dev *dev) -+{ -+ int i; -+ -+ for (i = 0; i < __MT_EP_OUT_MAX; i++) -+ mt7601u_free_tx_queue(&dev->tx_q[i]); -+} -+ -+static int mt7601u_alloc_tx_queue(struct mt7601u_dev *dev, -+ struct mt7601u_tx_queue *q) -+{ -+ int i; -+ -+ q->dev = dev; -+ q->entries = N_TX_ENTRIES; -+ -+ for (i = 0; i < N_TX_ENTRIES; i++) { -+ q->e[i].urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!q->e[i].urb) -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int mt7601u_alloc_tx(struct mt7601u_dev *dev) -+{ -+ int i; -+ -+ dev->tx_q = devm_kcalloc(dev->dev, __MT_EP_OUT_MAX, -+ sizeof(*dev->tx_q), GFP_KERNEL); -+ -+ for (i = 0; i < __MT_EP_OUT_MAX; i++) -+ if (mt7601u_alloc_tx_queue(dev, &dev->tx_q[i])) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+int mt7601u_dma_init(struct mt7601u_dev *dev) -+{ -+ int ret = -ENOMEM; -+ -+ tasklet_init(&dev->rx_tasklet, mt7601u_rx_tasklet, (unsigned long) dev); -+ -+ ret = mt7601u_alloc_tx(dev); -+ if (ret) -+ goto err; -+ ret = mt7601u_alloc_rx(dev); -+ if (ret) -+ goto err; -+ -+ ret = mt7601u_submit_rx(dev); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ mt7601u_dma_cleanup(dev); -+ return ret; -+} -+ -+void mt7601u_dma_cleanup(struct mt7601u_dev *dev) -+{ -+ mt7601u_kill_rx(dev); -+ -+ tasklet_kill(&dev->rx_tasklet); -+ -+ mt7601u_free_rx(dev); -+ mt7601u_free_tx(dev); -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.h b/drivers/net/wireless/mediatek/mt7601u/dma.h -new file mode 100644 -index 0000000..978e8a9 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/dma.h -@@ -0,0 +1,127 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT7601U_DMA_H -+#define __MT7601U_DMA_H -+ -+#include -+#include -+ -+#include "util.h" -+ -+#define MT_DMA_HDR_LEN 4 -+#define MT_RX_INFO_LEN 4 -+#define MT_FCE_INFO_LEN 4 -+#define MT_DMA_HDRS (MT_DMA_HDR_LEN + MT_RX_INFO_LEN) -+ -+/* Common Tx DMA descriptor fields */ -+#define MT_TXD_INFO_LEN GENMASK(15, 0) -+#define MT_TXD_INFO_D_PORT GENMASK(29, 27) -+#define MT_TXD_INFO_TYPE GENMASK(31, 30) -+ -+enum mt76_msg_port { -+ WLAN_PORT, -+ CPU_RX_PORT, -+ CPU_TX_PORT, -+ HOST_PORT, -+ VIRTUAL_CPU_RX_PORT, -+ VIRTUAL_CPU_TX_PORT, -+ DISCARD, -+}; -+ -+enum mt76_info_type { -+ DMA_PACKET, -+ DMA_COMMAND, -+}; -+ -+/* Tx DMA packet specific flags */ -+#define MT_TXD_PKT_INFO_NEXT_VLD BIT(16) -+#define MT_TXD_PKT_INFO_TX_BURST BIT(17) -+#define MT_TXD_PKT_INFO_80211 BIT(19) -+#define MT_TXD_PKT_INFO_TSO BIT(20) -+#define MT_TXD_PKT_INFO_CSO BIT(21) -+#define MT_TXD_PKT_INFO_WIV BIT(24) -+#define MT_TXD_PKT_INFO_QSEL GENMASK(26, 25) -+ -+enum mt76_qsel { -+ MT_QSEL_MGMT, -+ MT_QSEL_HCCA, -+ MT_QSEL_EDCA, -+ MT_QSEL_EDCA_2, -+}; -+ -+/* Tx DMA MCU command specific flags */ -+#define MT_TXD_CMD_INFO_SEQ GENMASK(19, 16) -+#define MT_TXD_CMD_INFO_TYPE GENMASK(26, 20) -+ -+static inline int mt7601u_dma_skb_wrap(struct sk_buff *skb, -+ enum mt76_msg_port d_port, -+ enum mt76_info_type type, u32 flags) -+{ -+ u32 info; -+ -+ /* Buffer layout: -+ * | 4B | xfer len | pad | 4B | -+ * | TXINFO | pkt/cmd | zero pad to 4B | zero | -+ * -+ * length field of TXINFO should be set to 'xfer len'. -+ */ -+ -+ info = flags | -+ MT76_SET(MT_TXD_INFO_LEN, round_up(skb->len, 4)) | -+ MT76_SET(MT_TXD_INFO_D_PORT, d_port) | -+ MT76_SET(MT_TXD_INFO_TYPE, type); -+ -+ put_unaligned_le32(info, skb_push(skb, sizeof(info))); -+ return skb_put_padto(skb, round_up(skb->len, 4) + 4); -+} -+ -+static inline int -+mt7601u_dma_skb_wrap_pkt(struct sk_buff *skb, enum mt76_qsel qsel, u32 flags) -+{ -+ flags |= MT76_SET(MT_TXD_PKT_INFO_QSEL, qsel); -+ return mt7601u_dma_skb_wrap(skb, WLAN_PORT, DMA_PACKET, flags); -+} -+ -+/* Common Rx DMA descriptor fields */ -+#define MT_RXD_INFO_LEN GENMASK(13, 0) -+#define MT_RXD_INFO_PCIE_INTR BIT(24) -+#define MT_RXD_INFO_QSEL GENMASK(26, 25) -+#define MT_RXD_INFO_PORT GENMASK(29, 27) -+#define MT_RXD_INFO_TYPE GENMASK(31, 30) -+ -+/* Rx DMA packet specific flags */ -+#define MT_RXD_PKT_INFO_UDP_ERR BIT(16) -+#define MT_RXD_PKT_INFO_TCP_ERR BIT(17) -+#define MT_RXD_PKT_INFO_IP_ERR BIT(18) -+#define MT_RXD_PKT_INFO_PKT_80211 BIT(19) -+#define MT_RXD_PKT_INFO_L3L4_DONE BIT(20) -+#define MT_RXD_PKT_INFO_MAC_LEN GENMASK(23, 21) -+ -+/* Rx DMA MCU command specific flags */ -+#define MT_RXD_CMD_INFO_SELF_GEN BIT(15) -+#define MT_RXD_CMD_INFO_CMD_SEQ GENMASK(19, 16) -+#define MT_RXD_CMD_INFO_EVT_TYPE GENMASK(23, 20) -+ -+enum mt76_evt_type { -+ CMD_DONE, -+ CMD_ERROR, -+ CMD_RETRY, -+ EVENT_PWR_RSP, -+ EVENT_WOW_RSP, -+ EVENT_CARRIER_DETECT_RSP, -+ EVENT_DFS_DETECT_RSP, -+}; -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/eeprom.c b/drivers/net/wireless/mediatek/mt7601u/eeprom.c -new file mode 100644 -index 0000000..8d8ee03 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/eeprom.c -@@ -0,0 +1,418 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "mt7601u.h" -+#include "eeprom.h" -+ -+static bool -+field_valid(u8 val) -+{ -+ return val != 0xff; -+} -+ -+static s8 -+field_validate(u8 val) -+{ -+ if (!field_valid(val)) -+ return 0; -+ -+ return val; -+} -+ -+static int -+mt7601u_efuse_read(struct mt7601u_dev *dev, u16 addr, u8 *data, -+ enum mt7601u_eeprom_access_modes mode) -+{ -+ u32 val; -+ int i; -+ -+ val = mt76_rr(dev, MT_EFUSE_CTRL); -+ val &= ~(MT_EFUSE_CTRL_AIN | -+ MT_EFUSE_CTRL_MODE); -+ val |= MT76_SET(MT_EFUSE_CTRL_AIN, addr & ~0xf) | -+ MT76_SET(MT_EFUSE_CTRL_MODE, mode) | -+ MT_EFUSE_CTRL_KICK; -+ mt76_wr(dev, MT_EFUSE_CTRL, val); -+ -+ if (!mt76_poll(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000)) -+ return -ETIMEDOUT; -+ -+ val = mt76_rr(dev, MT_EFUSE_CTRL); -+ if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) { -+ /* Parts of eeprom not in the usage map (0x80-0xc0,0xf0) -+ * will not return valid data but it's ok. -+ */ -+ memset(data, 0xff, 16); -+ return 0; -+ } -+ -+ for (i = 0; i < 4; i++) { -+ val = mt76_rr(dev, MT_EFUSE_DATA(i)); -+ put_unaligned_le32(val, data + 4 * i); -+ } -+ -+ return 0; -+} -+ -+static int -+mt7601u_efuse_physical_size_check(struct mt7601u_dev *dev) -+{ -+ const int map_reads = DIV_ROUND_UP(MT_EFUSE_USAGE_MAP_SIZE, 16); -+ u8 data[map_reads * 16]; -+ int ret, i; -+ u32 start = 0, end = 0, cnt_free; -+ -+ for (i = 0; i < map_reads; i++) { -+ ret = mt7601u_efuse_read(dev, MT_EE_USAGE_MAP_START + i * 16, -+ data + i * 16, MT_EE_PHYSICAL_READ); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < MT_EFUSE_USAGE_MAP_SIZE; i++) -+ if (!data[i]) { -+ if (!start) -+ start = MT_EE_USAGE_MAP_START + i; -+ end = MT_EE_USAGE_MAP_START + i; -+ } -+ cnt_free = end - start + 1; -+ -+ if (MT_EFUSE_USAGE_MAP_SIZE - cnt_free < 5) { -+ dev_err(dev->dev, "Error: your device needs default EEPROM file and this driver doesn't support it!\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static bool -+mt7601u_has_tssi(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ u16 nic_conf1 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_1); -+ -+ return ~nic_conf1 && (nic_conf1 & MT_EE_NIC_CONF_1_TX_ALC_EN); -+} -+ -+static void -+mt7601u_set_chip_cap(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ u16 nic_conf0 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_0); -+ u16 nic_conf1 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_1); -+ -+ if (!field_valid(nic_conf1 & 0xff)) -+ nic_conf1 &= 0xff00; -+ -+ dev->ee->tssi_enabled = mt7601u_has_tssi(dev, eeprom) && -+ !(nic_conf1 & MT_EE_NIC_CONF_1_TEMP_TX_ALC); -+ -+ if (nic_conf1 & MT_EE_NIC_CONF_1_HW_RF_CTRL) -+ dev_err(dev->dev, -+ "Error: this driver does not support HW RF ctrl\n"); -+ -+ if (!field_valid(nic_conf0 >> 8)) -+ return; -+ -+ if (MT76_GET(MT_EE_NIC_CONF_0_RX_PATH, nic_conf0) > 1 || -+ MT76_GET(MT_EE_NIC_CONF_0_TX_PATH, nic_conf0) > 1) -+ dev_err(dev->dev, -+ "Error: device has more than 1 RX/TX stream!\n"); -+} -+ -+static int -+mt7601u_set_macaddr(struct mt7601u_dev *dev, const u8 *eeprom) -+{ -+ const void *src = eeprom + MT_EE_MAC_ADDR; -+ -+ ether_addr_copy(dev->macaddr, src); -+ -+ if (!is_valid_ether_addr(dev->macaddr)) { -+ eth_random_addr(dev->macaddr); -+ dev_info(dev->dev, -+ "Invalid MAC address, using random address %pM\n", -+ dev->macaddr); -+ } -+ -+ mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(dev->macaddr)); -+ mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(dev->macaddr + 4) | -+ MT76_SET(MT_MAC_ADDR_DW1_U2ME_MASK, 0xff)); -+ -+ return 0; -+} -+ -+static void mt7601u_set_channel_target_power(struct mt7601u_dev *dev, -+ u8 *eeprom, u8 max_pwr) -+{ -+ u8 trgt_pwr = eeprom[MT_EE_TX_TSSI_TARGET_POWER]; -+ -+ if (trgt_pwr > max_pwr || !trgt_pwr) { -+ dev_warn(dev->dev, "Error: EEPROM trgt power invalid %hhx!\n", -+ trgt_pwr); -+ trgt_pwr = 0x20; -+ } -+ -+ memset(dev->ee->chan_pwr, trgt_pwr, sizeof(dev->ee->chan_pwr)); -+} -+ -+static void -+mt7601u_set_channel_power(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ u32 i, val; -+ u8 max_pwr; -+ -+ val = mt7601u_rr(dev, MT_TX_ALC_CFG_0); -+ max_pwr = MT76_GET(MT_TX_ALC_CFG_0_LIMIT_0, val); -+ -+ if (mt7601u_has_tssi(dev, eeprom)) { -+ mt7601u_set_channel_target_power(dev, eeprom, max_pwr); -+ return; -+ } -+ -+ for (i = 0; i < 14; i++) { -+ s8 power = field_validate(eeprom[MT_EE_TX_POWER_OFFSET + i]); -+ -+ if (power > max_pwr || power < 0) -+ power = MT7601U_DEFAULT_TX_POWER; -+ -+ dev->ee->chan_pwr[i] = power; -+ } -+} -+ -+static void -+mt7601u_set_country_reg(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ /* Note: - region 31 is not valid for mt7601u (see rtmp_init.c) -+ * - comments in rtmp_def.h are incorrect (see rt_channel.c) -+ */ -+ static const struct reg_channel_bounds chan_bounds[] = { -+ /* EEPROM country regions 0 - 7 */ -+ { 1, 11 }, { 1, 13 }, { 10, 2 }, { 10, 4 }, -+ { 14, 1 }, { 1, 14 }, { 3, 7 }, { 5, 9 }, -+ /* EEPROM country regions 32 - 33 */ -+ { 1, 11 }, { 1, 14 } -+ }; -+ u8 val = eeprom[MT_EE_COUNTRY_REGION]; -+ int idx = -1; -+ -+ if (val < 8) -+ idx = val; -+ if (val > 31 && val < 33) -+ idx = val - 32 + 8; -+ -+ if (idx != -1) -+ dev_info(dev->dev, -+ "EEPROM country region %02hhx (channels %hhd-%hhd)\n", -+ val, chan_bounds[idx].start, -+ chan_bounds[idx].start + chan_bounds[idx].num - 1); -+ else -+ idx = 5; /* channels 1 - 14 */ -+ -+ dev->ee->reg = chan_bounds[idx]; -+ -+ /* TODO: country region 33 is special - phy should be set to B-mode -+ * before entering channel 14 (see sta/connect.c) -+ */ -+} -+ -+static void -+mt7601u_set_rf_freq_off(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ u8 comp; -+ -+ dev->ee->rf_freq_off = field_validate(eeprom[MT_EE_FREQ_OFFSET]); -+ comp = field_validate(eeprom[MT_EE_FREQ_OFFSET_COMPENSATION]); -+ -+ if (comp & BIT(7)) -+ dev->ee->rf_freq_off -= comp & 0x7f; -+ else -+ dev->ee->rf_freq_off += comp; -+} -+ -+static void -+mt7601u_set_rssi_offset(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ int i; -+ s8 *rssi_offset = dev->ee->rssi_offset; -+ -+ for (i = 0; i < 2; i++) { -+ rssi_offset[i] = eeprom[MT_EE_RSSI_OFFSET + i]; -+ -+ if (rssi_offset[i] < -10 || rssi_offset[i] > 10) { -+ dev_warn(dev->dev, -+ "Warning: EEPROM RSSI is invalid %02hhx\n", -+ rssi_offset[i]); -+ rssi_offset[i] = 0; -+ } -+ } -+} -+ -+static void -+mt7601u_extra_power_over_mac(struct mt7601u_dev *dev) -+{ -+ u32 val; -+ -+ val = ((mt7601u_rr(dev, MT_TX_PWR_CFG_1) & 0x0000ff00) >> 8); -+ val |= ((mt7601u_rr(dev, MT_TX_PWR_CFG_2) & 0x0000ff00) << 8); -+ mt7601u_wr(dev, MT_TX_PWR_CFG_7, val); -+ -+ val = ((mt7601u_rr(dev, MT_TX_PWR_CFG_4) & 0x0000ff00) >> 8); -+ mt7601u_wr(dev, MT_TX_PWR_CFG_9, val); -+} -+ -+static void -+mt7601u_set_power_rate(struct power_per_rate *rate, s8 delta, u8 value) -+{ -+ /* Invalid? Note: vendor driver does not handle this */ -+ if (value == 0xff) -+ return; -+ -+ rate->raw = s6_validate(value); -+ rate->bw20 = s6_to_int(value); -+ /* Note: vendor driver does cap the value to s6 right away */ -+ rate->bw40 = rate->bw20 + delta; -+} -+ -+static void -+mt7601u_save_power_rate(struct mt7601u_dev *dev, s8 delta, u32 val, int i) -+{ -+ struct mt7601u_rate_power *t = &dev->ee->power_rate_table; -+ -+ switch (i) { -+ case 0: -+ mt7601u_set_power_rate(&t->cck[0], delta, (val >> 0) & 0xff); -+ mt7601u_set_power_rate(&t->cck[1], delta, (val >> 8) & 0xff); -+ /* Save cck bw20 for fixups of channel 14 */ -+ dev->ee->real_cck_bw20[0] = t->cck[0].bw20; -+ dev->ee->real_cck_bw20[1] = t->cck[1].bw20; -+ -+ mt7601u_set_power_rate(&t->ofdm[0], delta, (val >> 16) & 0xff); -+ mt7601u_set_power_rate(&t->ofdm[1], delta, (val >> 24) & 0xff); -+ break; -+ case 1: -+ mt7601u_set_power_rate(&t->ofdm[2], delta, (val >> 0) & 0xff); -+ mt7601u_set_power_rate(&t->ofdm[3], delta, (val >> 8) & 0xff); -+ mt7601u_set_power_rate(&t->ht[0], delta, (val >> 16) & 0xff); -+ mt7601u_set_power_rate(&t->ht[1], delta, (val >> 24) & 0xff); -+ break; -+ case 2: -+ mt7601u_set_power_rate(&t->ht[2], delta, (val >> 0) & 0xff); -+ mt7601u_set_power_rate(&t->ht[3], delta, (val >> 8) & 0xff); -+ break; -+ } -+} -+ -+static s8 -+get_delta(u8 val) -+{ -+ s8 ret; -+ -+ if (!field_valid(val) || !(val & BIT(7))) -+ return 0; -+ -+ ret = val & 0x1f; -+ if (ret > 8) -+ ret = 8; -+ if (val & BIT(6)) -+ ret = -ret; -+ -+ return ret; -+} -+ -+static void -+mt7601u_config_tx_power_per_rate(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ u32 val; -+ s8 bw40_delta; -+ int i; -+ -+ bw40_delta = get_delta(eeprom[MT_EE_TX_POWER_DELTA_BW40]); -+ -+ for (i = 0; i < 5; i++) { -+ val = get_unaligned_le32(eeprom + MT_EE_TX_POWER_BYRATE(i)); -+ -+ mt7601u_save_power_rate(dev, bw40_delta, val, i); -+ -+ if (~val) -+ mt7601u_wr(dev, MT_TX_PWR_CFG_0 + i * 4, val); -+ } -+ -+ mt7601u_extra_power_over_mac(dev); -+} -+ -+static void -+mt7601u_init_tssi_params(struct mt7601u_dev *dev, u8 *eeprom) -+{ -+ struct tssi_data *d = &dev->ee->tssi_data; -+ -+ if (!dev->ee->tssi_enabled) -+ return; -+ -+ d->slope = eeprom[MT_EE_TX_TSSI_SLOPE]; -+ d->tx0_delta_offset = eeprom[MT_EE_TX_TSSI_OFFSET] * 1024; -+ d->offset[0] = eeprom[MT_EE_TX_TSSI_OFFSET_GROUP]; -+ d->offset[1] = eeprom[MT_EE_TX_TSSI_OFFSET_GROUP + 1]; -+ d->offset[2] = eeprom[MT_EE_TX_TSSI_OFFSET_GROUP + 2]; -+} -+ -+int -+mt7601u_eeprom_init(struct mt7601u_dev *dev) -+{ -+ u8 *eeprom; -+ int i, ret; -+ -+ ret = mt7601u_efuse_physical_size_check(dev); -+ if (ret) -+ return ret; -+ -+ dev->ee = devm_kzalloc(dev->dev, sizeof(*dev->ee), GFP_KERNEL); -+ if (!dev->ee) -+ return -ENOMEM; -+ -+ eeprom = kmalloc(MT7601U_EEPROM_SIZE, GFP_KERNEL); -+ if (!eeprom) -+ return -ENOMEM; -+ -+ for (i = 0; i + 16 <= MT7601U_EEPROM_SIZE; i += 16) { -+ ret = mt7601u_efuse_read(dev, i, eeprom + i, MT_EE_READ); -+ if (ret) -+ goto out; -+ } -+ -+ if (eeprom[MT_EE_VERSION_EE] > MT7601U_EE_MAX_VER) -+ dev_warn(dev->dev, -+ "Warning: unsupported EEPROM version %02hhx\n", -+ eeprom[MT_EE_VERSION_EE]); -+ dev_info(dev->dev, "EEPROM ver:%02hhx fae:%02hhx\n", -+ eeprom[MT_EE_VERSION_EE], eeprom[MT_EE_VERSION_FAE]); -+ -+ mt7601u_set_macaddr(dev, eeprom); -+ mt7601u_set_chip_cap(dev, eeprom); -+ mt7601u_set_channel_power(dev, eeprom); -+ mt7601u_set_country_reg(dev, eeprom); -+ mt7601u_set_rf_freq_off(dev, eeprom); -+ mt7601u_set_rssi_offset(dev, eeprom); -+ dev->ee->ref_temp = eeprom[MT_EE_REF_TEMP]; -+ dev->ee->lna_gain = eeprom[MT_EE_LNA_GAIN]; -+ -+ mt7601u_config_tx_power_per_rate(dev, eeprom); -+ -+ mt7601u_init_tssi_params(dev, eeprom); -+out: -+ kfree(eeprom); -+ return ret; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/eeprom.h b/drivers/net/wireless/mediatek/mt7601u/eeprom.h -new file mode 100644 -index 0000000..662d12703 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/eeprom.h -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT7601U_EEPROM_H -+#define __MT7601U_EEPROM_H -+ -+struct mt7601u_dev; -+ -+#define MT7601U_EE_MAX_VER 0x0c -+#define MT7601U_EEPROM_SIZE 256 -+ -+#define MT7601U_DEFAULT_TX_POWER 6 -+ -+enum mt76_eeprom_field { -+ MT_EE_CHIP_ID = 0x00, -+ MT_EE_VERSION_FAE = 0x02, -+ MT_EE_VERSION_EE = 0x03, -+ MT_EE_MAC_ADDR = 0x04, -+ MT_EE_NIC_CONF_0 = 0x34, -+ MT_EE_NIC_CONF_1 = 0x36, -+ MT_EE_COUNTRY_REGION = 0x39, -+ MT_EE_FREQ_OFFSET = 0x3a, -+ MT_EE_NIC_CONF_2 = 0x42, -+ -+ MT_EE_LNA_GAIN = 0x44, -+ MT_EE_RSSI_OFFSET = 0x46, -+ -+ MT_EE_TX_POWER_DELTA_BW40 = 0x50, -+ MT_EE_TX_POWER_OFFSET = 0x52, -+ -+ MT_EE_TX_TSSI_SLOPE = 0x6e, -+ MT_EE_TX_TSSI_OFFSET_GROUP = 0x6f, -+ MT_EE_TX_TSSI_OFFSET = 0x76, -+ -+ MT_EE_TX_TSSI_TARGET_POWER = 0xd0, -+ MT_EE_REF_TEMP = 0xd1, -+ MT_EE_FREQ_OFFSET_COMPENSATION = 0xdb, -+ MT_EE_TX_POWER_BYRATE_BASE = 0xde, -+ -+ MT_EE_USAGE_MAP_START = 0x1e0, -+ MT_EE_USAGE_MAP_END = 0x1fc, -+}; -+ -+#define MT_EE_NIC_CONF_0_RX_PATH GENMASK(3, 0) -+#define MT_EE_NIC_CONF_0_TX_PATH GENMASK(7, 4) -+#define MT_EE_NIC_CONF_0_BOARD_TYPE GENMASK(13, 12) -+ -+#define MT_EE_NIC_CONF_1_HW_RF_CTRL BIT(0) -+#define MT_EE_NIC_CONF_1_TEMP_TX_ALC BIT(1) -+#define MT_EE_NIC_CONF_1_LNA_EXT_2G BIT(2) -+#define MT_EE_NIC_CONF_1_LNA_EXT_5G BIT(3) -+#define MT_EE_NIC_CONF_1_TX_ALC_EN BIT(13) -+ -+#define MT_EE_NIC_CONF_2_RX_STREAM GENMASK(3, 0) -+#define MT_EE_NIC_CONF_2_TX_STREAM GENMASK(7, 4) -+#define MT_EE_NIC_CONF_2_HW_ANTDIV BIT(8) -+#define MT_EE_NIC_CONF_2_XTAL_OPTION GENMASK(10, 9) -+#define MT_EE_NIC_CONF_2_TEMP_DISABLE BIT(11) -+#define MT_EE_NIC_CONF_2_COEX_METHOD GENMASK(15, 13) -+ -+#define MT_EE_TX_POWER_BYRATE(i) (MT_EE_TX_POWER_BYRATE_BASE + \ -+ (i) * 4) -+ -+#define MT_EFUSE_USAGE_MAP_SIZE (MT_EE_USAGE_MAP_END - \ -+ MT_EE_USAGE_MAP_START + 1) -+ -+enum mt7601u_eeprom_access_modes { -+ MT_EE_READ = 0, -+ MT_EE_PHYSICAL_READ = 1, -+}; -+ -+struct power_per_rate { -+ u8 raw; /* validated s6 value */ -+ s8 bw20; /* sign-extended int */ -+ s8 bw40; /* sign-extended int */ -+}; -+ -+/* Power per rate - one value per two rates */ -+struct mt7601u_rate_power { -+ struct power_per_rate cck[2]; -+ struct power_per_rate ofdm[4]; -+ struct power_per_rate ht[4]; -+}; -+ -+struct reg_channel_bounds { -+ u8 start; -+ u8 num; -+}; -+ -+struct mt7601u_eeprom_params { -+ bool tssi_enabled; -+ u8 rf_freq_off; -+ s8 rssi_offset[2]; -+ s8 ref_temp; -+ s8 lna_gain; -+ -+ u8 chan_pwr[14]; -+ struct mt7601u_rate_power power_rate_table; -+ s8 real_cck_bw20[2]; -+ -+ /* TSSI stuff - only with internal TX ALC */ -+ struct tssi_data { -+ int tx0_delta_offset; -+ u8 slope; -+ u8 offset[3]; -+ } tssi_data; -+ -+ struct reg_channel_bounds reg; -+}; -+ -+int mt7601u_eeprom_init(struct mt7601u_dev *dev); -+ -+static inline u32 s6_validate(u32 reg) -+{ -+ WARN_ON(reg & ~GENMASK(5, 0)); -+ return reg & GENMASK(5, 0); -+} -+ -+static inline int s6_to_int(u32 reg) -+{ -+ int s6; -+ -+ s6 = s6_validate(reg); -+ if (s6 & BIT(5)) -+ s6 -= BIT(6); -+ -+ return s6; -+} -+ -+static inline u32 int_to_s6(int val) -+{ -+ if (val < -0x20) -+ return 0x20; -+ if (val > 0x1f) -+ return 0x1f; -+ -+ return val & 0x3f; -+} -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/init.c b/drivers/net/wireless/mediatek/mt7601u/init.c -new file mode 100644 -index 0000000..45eb079 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/init.c -@@ -0,0 +1,628 @@ -+/* -+ * (c) Copyright 2002-2010, Ralink Technology, Inc. -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+#include "eeprom.h" -+#include "trace.h" -+#include "mcu.h" -+ -+#include "initvals.h" -+ -+static void -+mt7601u_set_wlan_state(struct mt7601u_dev *dev, u32 val, bool enable) -+{ -+ int i; -+ -+ /* Note: we don't turn off WLAN_CLK because that makes the device -+ * not respond properly on the probe path. -+ * In case anyone (PSM?) wants to use this function we can -+ * bring the clock stuff back and fixup the probe path. -+ */ -+ -+ if (enable) -+ val |= (MT_WLAN_FUN_CTRL_WLAN_EN | -+ MT_WLAN_FUN_CTRL_WLAN_CLK_EN); -+ else -+ val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN); -+ -+ mt7601u_wr(dev, MT_WLAN_FUN_CTRL, val); -+ udelay(20); -+ -+ if (enable) { -+ set_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state); -+ } else { -+ clear_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state); -+ return; -+ } -+ -+ for (i = 200; i; i--) { -+ val = mt7601u_rr(dev, MT_CMB_CTRL); -+ -+ if (val & MT_CMB_CTRL_XTAL_RDY && val & MT_CMB_CTRL_PLL_LD) -+ break; -+ -+ udelay(20); -+ } -+ -+ /* Note: vendor driver tries to disable/enable wlan here and retry -+ * but the code which does it is so buggy it must have never -+ * triggered, so don't bother. -+ */ -+ if (!i) -+ dev_err(dev->dev, "Error: PLL and XTAL check failed!\n"); -+} -+ -+static void mt7601u_chip_onoff(struct mt7601u_dev *dev, bool enable, bool reset) -+{ -+ u32 val; -+ -+ mutex_lock(&dev->hw_atomic_mutex); -+ -+ val = mt7601u_rr(dev, MT_WLAN_FUN_CTRL); -+ -+ if (reset) { -+ val |= MT_WLAN_FUN_CTRL_GPIO_OUT_EN; -+ val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL; -+ -+ if (val & MT_WLAN_FUN_CTRL_WLAN_EN) { -+ val |= (MT_WLAN_FUN_CTRL_WLAN_RESET | -+ MT_WLAN_FUN_CTRL_WLAN_RESET_RF); -+ mt7601u_wr(dev, MT_WLAN_FUN_CTRL, val); -+ udelay(20); -+ -+ val &= ~(MT_WLAN_FUN_CTRL_WLAN_RESET | -+ MT_WLAN_FUN_CTRL_WLAN_RESET_RF); -+ } -+ } -+ -+ mt7601u_wr(dev, MT_WLAN_FUN_CTRL, val); -+ udelay(20); -+ -+ mt7601u_set_wlan_state(dev, val, enable); -+ -+ mutex_unlock(&dev->hw_atomic_mutex); -+} -+ -+static void mt7601u_reset_csr_bbp(struct mt7601u_dev *dev) -+{ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, (MT_MAC_SYS_CTRL_RESET_CSR | -+ MT_MAC_SYS_CTRL_RESET_BBP)); -+ mt7601u_wr(dev, MT_USB_DMA_CFG, 0); -+ msleep(1); -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, 0); -+} -+ -+static void mt7601u_init_usb_dma(struct mt7601u_dev *dev) -+{ -+ u32 val; -+ -+ val = MT76_SET(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, MT_USB_AGGR_TIMEOUT) | -+ MT76_SET(MT_USB_DMA_CFG_RX_BULK_AGG_LMT, MT_USB_AGGR_SIZE_LIMIT) | -+ MT_USB_DMA_CFG_RX_BULK_EN | -+ MT_USB_DMA_CFG_TX_BULK_EN; -+ if (dev->in_max_packet == 512) -+ val |= MT_USB_DMA_CFG_RX_BULK_AGG_EN; -+ mt7601u_wr(dev, MT_USB_DMA_CFG, val); -+ -+ val |= MT_USB_DMA_CFG_UDMA_RX_WL_DROP; -+ mt7601u_wr(dev, MT_USB_DMA_CFG, val); -+ val &= ~MT_USB_DMA_CFG_UDMA_RX_WL_DROP; -+ mt7601u_wr(dev, MT_USB_DMA_CFG, val); -+} -+ -+static int mt7601u_init_bbp(struct mt7601u_dev *dev) -+{ -+ int ret; -+ -+ ret = mt7601u_wait_bbp_ready(dev); -+ if (ret) -+ return ret; -+ -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, bbp_common_vals, -+ ARRAY_SIZE(bbp_common_vals)); -+ if (ret) -+ return ret; -+ -+ return mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, bbp_chip_vals, -+ ARRAY_SIZE(bbp_chip_vals)); -+} -+ -+static void -+mt76_init_beacon_offsets(struct mt7601u_dev *dev) -+{ -+ u16 base = MT_BEACON_BASE; -+ u32 regs[4] = {}; -+ int i; -+ -+ for (i = 0; i < 16; i++) { -+ u16 addr = dev->beacon_offsets[i]; -+ -+ regs[i / 4] |= ((addr - base) / 64) << (8 * (i % 4)); -+ } -+ -+ for (i = 0; i < 4; i++) -+ mt7601u_wr(dev, MT_BCN_OFFSET(i), regs[i]); -+} -+ -+static int mt7601u_write_mac_initvals(struct mt7601u_dev *dev) -+{ -+ int ret; -+ -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_WLAN, mac_common_vals, -+ ARRAY_SIZE(mac_common_vals)); -+ if (ret) -+ return ret; -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_WLAN, -+ mac_chip_vals, ARRAY_SIZE(mac_chip_vals)); -+ if (ret) -+ return ret; -+ -+ mt76_init_beacon_offsets(dev); -+ -+ mt7601u_wr(dev, MT_AUX_CLK_CFG, 0); -+ -+ return 0; -+} -+ -+static int mt7601u_init_wcid_mem(struct mt7601u_dev *dev) -+{ -+ u32 *vals; -+ int i, ret; -+ -+ vals = kmalloc(sizeof(*vals) * N_WCIDS * 2, GFP_KERNEL); -+ if (!vals) -+ return -ENOMEM; -+ -+ for (i = 0; i < N_WCIDS; i++) { -+ vals[i * 2] = 0xffffffff; -+ vals[i * 2 + 1] = 0x00ffffff; -+ } -+ -+ ret = mt7601u_burst_write_regs(dev, MT_WCID_ADDR_BASE, -+ vals, N_WCIDS * 2); -+ kfree(vals); -+ -+ return ret; -+} -+ -+static int mt7601u_init_key_mem(struct mt7601u_dev *dev) -+{ -+ u32 vals[4] = {}; -+ -+ return mt7601u_burst_write_regs(dev, MT_SKEY_MODE_BASE_0, -+ vals, ARRAY_SIZE(vals)); -+} -+ -+static int mt7601u_init_wcid_attr_mem(struct mt7601u_dev *dev) -+{ -+ u32 *vals; -+ int i, ret; -+ -+ vals = kmalloc(sizeof(*vals) * N_WCIDS * 2, GFP_KERNEL); -+ if (!vals) -+ return -ENOMEM; -+ -+ for (i = 0; i < N_WCIDS * 2; i++) -+ vals[i] = 1; -+ -+ ret = mt7601u_burst_write_regs(dev, MT_WCID_ATTR_BASE, -+ vals, N_WCIDS * 2); -+ kfree(vals); -+ -+ return ret; -+} -+ -+static void mt7601u_reset_counters(struct mt7601u_dev *dev) -+{ -+ mt7601u_rr(dev, MT_RX_STA_CNT0); -+ mt7601u_rr(dev, MT_RX_STA_CNT1); -+ mt7601u_rr(dev, MT_RX_STA_CNT2); -+ mt7601u_rr(dev, MT_TX_STA_CNT0); -+ mt7601u_rr(dev, MT_TX_STA_CNT1); -+ mt7601u_rr(dev, MT_TX_STA_CNT2); -+} -+ -+int mt7601u_mac_start(struct mt7601u_dev *dev) -+{ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX); -+ -+ if (!mt76_poll(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY | -+ MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 200000)) -+ return -ETIMEDOUT; -+ -+ dev->rxfilter = MT_RX_FILTR_CFG_CRC_ERR | -+ MT_RX_FILTR_CFG_PHY_ERR | MT_RX_FILTR_CFG_PROMISC | -+ MT_RX_FILTR_CFG_VER_ERR | MT_RX_FILTR_CFG_DUP | -+ MT_RX_FILTR_CFG_CFACK | MT_RX_FILTR_CFG_CFEND | -+ MT_RX_FILTR_CFG_ACK | MT_RX_FILTR_CFG_CTS | -+ MT_RX_FILTR_CFG_RTS | MT_RX_FILTR_CFG_PSPOLL | -+ MT_RX_FILTR_CFG_BA | MT_RX_FILTR_CFG_CTRL_RSV; -+ mt7601u_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); -+ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, -+ MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX); -+ -+ if (!mt76_poll(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY | -+ MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 50)) -+ return -ETIMEDOUT; -+ -+ return 0; -+} -+ -+static void mt7601u_mac_stop_hw(struct mt7601u_dev *dev) -+{ -+ int i, ok; -+ -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return; -+ -+ mt76_clear(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_TIMER_EN | -+ MT_BEACON_TIME_CFG_SYNC_MODE | MT_BEACON_TIME_CFG_TBTT_EN | -+ MT_BEACON_TIME_CFG_BEACON_TX); -+ -+ if (!mt76_poll(dev, MT_USB_DMA_CFG, MT_USB_DMA_CFG_TX_BUSY, 0, 1000)) -+ dev_warn(dev->dev, "Warning: TX DMA did not stop!\n"); -+ -+ /* Page count on TxQ */ -+ i = 200; -+ while (i-- && ((mt76_rr(dev, 0x0438) & 0xffffffff) || -+ (mt76_rr(dev, 0x0a30) & 0x000000ff) || -+ (mt76_rr(dev, 0x0a34) & 0x00ff00ff))) -+ msleep(10); -+ -+ if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_TX, 0, 1000)) -+ dev_warn(dev->dev, "Warning: MAC TX did not stop!\n"); -+ -+ mt76_clear(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_RX | -+ MT_MAC_SYS_CTRL_ENABLE_TX); -+ -+ /* Page count on RxQ */ -+ ok = 0; -+ i = 200; -+ while (i--) { -+ if ((mt76_rr(dev, 0x0430) & 0x00ff0000) || -+ (mt76_rr(dev, 0x0a30) & 0xffffffff) || -+ (mt76_rr(dev, 0x0a34) & 0xffffffff)) -+ ok++; -+ if (ok > 6) -+ break; -+ -+ msleep(1); -+ } -+ -+ if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_RX, 0, 1000)) -+ dev_warn(dev->dev, "Warning: MAC RX did not stop!\n"); -+ -+ if (!mt76_poll(dev, MT_USB_DMA_CFG, MT_USB_DMA_CFG_RX_BUSY, 0, 1000)) -+ dev_warn(dev->dev, "Warning: RX DMA did not stop!\n"); -+} -+ -+void mt7601u_mac_stop(struct mt7601u_dev *dev) -+{ -+ mt7601u_mac_stop_hw(dev); -+ flush_delayed_work(&dev->stat_work); -+ cancel_delayed_work_sync(&dev->stat_work); -+} -+ -+static void mt7601u_stop_hardware(struct mt7601u_dev *dev) -+{ -+ mt7601u_chip_onoff(dev, false, false); -+} -+ -+int mt7601u_init_hardware(struct mt7601u_dev *dev) -+{ -+ static const u16 beacon_offsets[16] = { -+ /* 512 byte per beacon */ -+ 0xc000, 0xc200, 0xc400, 0xc600, -+ 0xc800, 0xca00, 0xcc00, 0xce00, -+ 0xd000, 0xd200, 0xd400, 0xd600, -+ 0xd800, 0xda00, 0xdc00, 0xde00 -+ }; -+ int ret; -+ -+ dev->beacon_offsets = beacon_offsets; -+ -+ mt7601u_chip_onoff(dev, true, false); -+ -+ ret = mt7601u_wait_asic_ready(dev); -+ if (ret) -+ goto err; -+ ret = mt7601u_mcu_init(dev); -+ if (ret) -+ goto err; -+ -+ if (!mt76_poll_msec(dev, MT_WPDMA_GLO_CFG, -+ MT_WPDMA_GLO_CFG_TX_DMA_BUSY | -+ MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 100)) { -+ ret = -EIO; -+ goto err; -+ } -+ -+ /* Wait for ASIC ready after FW load. */ -+ ret = mt7601u_wait_asic_ready(dev); -+ if (ret) -+ goto err; -+ -+ mt7601u_reset_csr_bbp(dev); -+ mt7601u_init_usb_dma(dev); -+ -+ ret = mt7601u_mcu_cmd_init(dev); -+ if (ret) -+ goto err; -+ ret = mt7601u_dma_init(dev); -+ if (ret) -+ goto err_mcu; -+ ret = mt7601u_write_mac_initvals(dev); -+ if (ret) -+ goto err_rx; -+ -+ if (!mt76_poll_msec(dev, MT_MAC_STATUS, -+ MT_MAC_STATUS_TX | MT_MAC_STATUS_RX, 0, 100)) { -+ ret = -EIO; -+ goto err_rx; -+ } -+ -+ ret = mt7601u_init_bbp(dev); -+ if (ret) -+ goto err_rx; -+ ret = mt7601u_init_wcid_mem(dev); -+ if (ret) -+ goto err_rx; -+ ret = mt7601u_init_key_mem(dev); -+ if (ret) -+ goto err_rx; -+ ret = mt7601u_init_wcid_attr_mem(dev); -+ if (ret) -+ goto err_rx; -+ -+ mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN | -+ MT_BEACON_TIME_CFG_SYNC_MODE | -+ MT_BEACON_TIME_CFG_TBTT_EN | -+ MT_BEACON_TIME_CFG_BEACON_TX)); -+ -+ mt7601u_reset_counters(dev); -+ -+ mt7601u_rmw(dev, MT_US_CYC_CFG, MT_US_CYC_CNT, 0x1e); -+ -+ mt7601u_wr(dev, MT_TXOP_CTRL_CFG, MT76_SET(MT_TXOP_TRUN_EN, 0x3f) | -+ MT76_SET(MT_TXOP_EXT_CCA_DLY, 0x58)); -+ -+ ret = mt7601u_eeprom_init(dev); -+ if (ret) -+ goto err_rx; -+ -+ ret = mt7601u_phy_init(dev); -+ if (ret) -+ goto err_rx; -+ -+ mt7601u_set_rx_path(dev, 0); -+ mt7601u_set_tx_dac(dev, 0); -+ -+ mt7601u_mac_set_ctrlch(dev, false); -+ mt7601u_bbp_set_ctrlch(dev, false); -+ mt7601u_bbp_set_bw(dev, MT_BW_20); -+ -+ return 0; -+ -+err_rx: -+ mt7601u_dma_cleanup(dev); -+err_mcu: -+ mt7601u_mcu_cmd_deinit(dev); -+err: -+ mt7601u_chip_onoff(dev, false, false); -+ return ret; -+} -+ -+void mt7601u_cleanup(struct mt7601u_dev *dev) -+{ -+ if (!test_and_clear_bit(MT7601U_STATE_INITIALIZED, &dev->state)) -+ return; -+ -+ mt7601u_stop_hardware(dev); -+ mt7601u_dma_cleanup(dev); -+ mt7601u_mcu_cmd_deinit(dev); -+} -+ -+struct mt7601u_dev *mt7601u_alloc_device(struct device *pdev) -+{ -+ struct ieee80211_hw *hw; -+ struct mt7601u_dev *dev; -+ -+ hw = ieee80211_alloc_hw(sizeof(*dev), &mt7601u_ops); -+ if (!hw) -+ return NULL; -+ -+ dev = hw->priv; -+ dev->dev = pdev; -+ dev->hw = hw; -+ mutex_init(&dev->vendor_req_mutex); -+ mutex_init(&dev->reg_atomic_mutex); -+ mutex_init(&dev->hw_atomic_mutex); -+ mutex_init(&dev->mutex); -+ spin_lock_init(&dev->tx_lock); -+ spin_lock_init(&dev->rx_lock); -+ spin_lock_init(&dev->lock); -+ spin_lock_init(&dev->con_mon_lock); -+ atomic_set(&dev->avg_ampdu_len, 1); -+ -+ dev->stat_wq = alloc_workqueue("mt7601u", WQ_UNBOUND, 0); -+ if (!dev->stat_wq) { -+ ieee80211_free_hw(hw); -+ return NULL; -+ } -+ -+ return dev; -+} -+ -+#define CHAN2G(_idx, _freq) { \ -+ .band = IEEE80211_BAND_2GHZ, \ -+ .center_freq = (_freq), \ -+ .hw_value = (_idx), \ -+ .max_power = 30, \ -+} -+ -+static const struct ieee80211_channel mt76_channels_2ghz[] = { -+ CHAN2G(1, 2412), -+ CHAN2G(2, 2417), -+ CHAN2G(3, 2422), -+ CHAN2G(4, 2427), -+ CHAN2G(5, 2432), -+ CHAN2G(6, 2437), -+ CHAN2G(7, 2442), -+ CHAN2G(8, 2447), -+ CHAN2G(9, 2452), -+ CHAN2G(10, 2457), -+ CHAN2G(11, 2462), -+ CHAN2G(12, 2467), -+ CHAN2G(13, 2472), -+ CHAN2G(14, 2484), -+}; -+ -+#define CCK_RATE(_idx, _rate) { \ -+ .bitrate = _rate, \ -+ .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ -+ .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ -+ .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ -+} -+ -+#define OFDM_RATE(_idx, _rate) { \ -+ .bitrate = _rate, \ -+ .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ -+ .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ -+} -+ -+static struct ieee80211_rate mt76_rates[] = { -+ CCK_RATE(0, 10), -+ CCK_RATE(1, 20), -+ CCK_RATE(2, 55), -+ CCK_RATE(3, 110), -+ OFDM_RATE(0, 60), -+ OFDM_RATE(1, 90), -+ OFDM_RATE(2, 120), -+ OFDM_RATE(3, 180), -+ OFDM_RATE(4, 240), -+ OFDM_RATE(5, 360), -+ OFDM_RATE(6, 480), -+ OFDM_RATE(7, 540), -+}; -+ -+static int -+mt76_init_sband(struct mt7601u_dev *dev, struct ieee80211_supported_band *sband, -+ const struct ieee80211_channel *chan, int n_chan, -+ struct ieee80211_rate *rates, int n_rates) -+{ -+ struct ieee80211_sta_ht_cap *ht_cap; -+ void *chanlist; -+ int size; -+ -+ size = n_chan * sizeof(*chan); -+ chanlist = devm_kmemdup(dev->dev, chan, size, GFP_KERNEL); -+ if (!chanlist) -+ return -ENOMEM; -+ -+ sband->channels = chanlist; -+ sband->n_channels = n_chan; -+ sband->bitrates = rates; -+ sband->n_bitrates = n_rates; -+ -+ ht_cap = &sband->ht_cap; -+ ht_cap->ht_supported = true; -+ ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | -+ IEEE80211_HT_CAP_GRN_FLD | -+ IEEE80211_HT_CAP_SGI_20 | -+ IEEE80211_HT_CAP_SGI_40 | -+ (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); -+ -+ ht_cap->mcs.rx_mask[0] = 0xff; -+ ht_cap->mcs.rx_mask[4] = 0x1; -+ ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; -+ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; -+ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_2; -+ -+ dev->chandef.chan = &sband->channels[0]; -+ -+ return 0; -+} -+ -+static int -+mt76_init_sband_2g(struct mt7601u_dev *dev) -+{ -+ dev->sband_2g = devm_kzalloc(dev->dev, sizeof(*dev->sband_2g), -+ GFP_KERNEL); -+ dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = dev->sband_2g; -+ -+ WARN_ON(dev->ee->reg.start - 1 + dev->ee->reg.num > -+ ARRAY_SIZE(mt76_channels_2ghz)); -+ -+ return mt76_init_sband(dev, dev->sband_2g, -+ &mt76_channels_2ghz[dev->ee->reg.start - 1], -+ dev->ee->reg.num, -+ mt76_rates, ARRAY_SIZE(mt76_rates)); -+} -+ -+int mt7601u_register_device(struct mt7601u_dev *dev) -+{ -+ struct ieee80211_hw *hw = dev->hw; -+ struct wiphy *wiphy = hw->wiphy; -+ int ret; -+ -+ /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to -+ * entry no. 1 like it does in the vendor driver. -+ */ -+ dev->wcid_mask[0] |= 1; -+ -+ /* init fake wcid for monitor interfaces */ -+ dev->mon_wcid = devm_kmalloc(dev->dev, sizeof(*dev->mon_wcid), -+ GFP_KERNEL); -+ if (!dev->mon_wcid) -+ return -ENOMEM; -+ dev->mon_wcid->idx = 0xff; -+ dev->mon_wcid->hw_key_idx = -1; -+ -+ SET_IEEE80211_DEV(hw, dev->dev); -+ -+ hw->queues = 4; -+ hw->flags = IEEE80211_HW_SIGNAL_DBM | -+ IEEE80211_HW_PS_NULLFUNC_STACK | -+ IEEE80211_HW_SUPPORTS_HT_CCK_RATES | -+ IEEE80211_HW_AMPDU_AGGREGATION | -+ IEEE80211_HW_SUPPORTS_RC_TABLE; -+ hw->max_rates = 1; -+ hw->max_report_rates = 7; -+ hw->max_rate_tries = 1; -+ -+ hw->sta_data_size = sizeof(struct mt76_sta); -+ hw->vif_data_size = sizeof(struct mt76_vif); -+ -+ SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); -+ -+ wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; -+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); -+ -+ ret = mt76_init_sband_2g(dev); -+ if (ret) -+ return ret; -+ -+ INIT_DELAYED_WORK(&dev->mac_work, mt7601u_mac_work); -+ INIT_DELAYED_WORK(&dev->stat_work, mt7601u_tx_stat); -+ -+ ret = ieee80211_register_hw(hw); -+ if (ret) -+ return ret; -+ -+ mt7601u_init_debugfs(dev); -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/initvals.h b/drivers/net/wireless/mediatek/mt7601u/initvals.h -new file mode 100644 -index 0000000..ec11ff6 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/initvals.h -@@ -0,0 +1,164 @@ -+/* -+ * (c) Copyright 2002-2010, Ralink Technology, Inc. -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT7601U_INITVALS_H -+#define __MT7601U_INITVALS_H -+ -+static const struct mt76_reg_pair bbp_common_vals[] = { -+ { 65, 0x2c }, -+ { 66, 0x38 }, -+ { 68, 0x0b }, -+ { 69, 0x12 }, -+ { 70, 0x0a }, -+ { 73, 0x10 }, -+ { 81, 0x37 }, -+ { 82, 0x62 }, -+ { 83, 0x6a }, -+ { 84, 0x99 }, -+ { 86, 0x00 }, -+ { 91, 0x04 }, -+ { 92, 0x00 }, -+ { 103, 0x00 }, -+ { 105, 0x05 }, -+ { 106, 0x35 }, -+}; -+ -+static const struct mt76_reg_pair bbp_chip_vals[] = { -+ { 1, 0x04 }, { 4, 0x40 }, { 20, 0x06 }, { 31, 0x08 }, -+ /* CCK Tx Control */ -+ { 178, 0xff }, -+ /* AGC/Sync controls */ -+ { 66, 0x14 }, { 68, 0x8b }, { 69, 0x12 }, { 70, 0x09 }, -+ { 73, 0x11 }, { 75, 0x60 }, { 76, 0x44 }, { 84, 0x9a }, -+ { 86, 0x38 }, { 91, 0x07 }, { 92, 0x02 }, -+ /* Rx Path Controls */ -+ { 99, 0x50 }, { 101, 0x00 }, { 103, 0xc0 }, { 104, 0x92 }, -+ { 105, 0x3c }, { 106, 0x03 }, { 128, 0x12 }, -+ /* Change RXWI content: Gain Report */ -+ { 142, 0x04 }, { 143, 0x37 }, -+ /* Change RXWI content: Antenna Report */ -+ { 142, 0x03 }, { 143, 0x99 }, -+ /* Calibration Index Register */ -+ /* CCK Receiver Control */ -+ { 160, 0xeb }, { 161, 0xc4 }, { 162, 0x77 }, { 163, 0xf9 }, -+ { 164, 0x88 }, { 165, 0x80 }, { 166, 0xff }, { 167, 0xe4 }, -+ /* Added AGC controls - these AGC/GLRT registers are accessed -+ * through R195 and R196. -+ */ -+ { 195, 0x00 }, { 196, 0x00 }, -+ { 195, 0x01 }, { 196, 0x04 }, -+ { 195, 0x02 }, { 196, 0x20 }, -+ { 195, 0x03 }, { 196, 0x0a }, -+ { 195, 0x06 }, { 196, 0x16 }, -+ { 195, 0x07 }, { 196, 0x05 }, -+ { 195, 0x08 }, { 196, 0x37 }, -+ { 195, 0x0a }, { 196, 0x15 }, -+ { 195, 0x0b }, { 196, 0x17 }, -+ { 195, 0x0c }, { 196, 0x06 }, -+ { 195, 0x0d }, { 196, 0x09 }, -+ { 195, 0x0e }, { 196, 0x05 }, -+ { 195, 0x0f }, { 196, 0x09 }, -+ { 195, 0x10 }, { 196, 0x20 }, -+ { 195, 0x20 }, { 196, 0x17 }, -+ { 195, 0x21 }, { 196, 0x06 }, -+ { 195, 0x22 }, { 196, 0x09 }, -+ { 195, 0x23 }, { 196, 0x17 }, -+ { 195, 0x24 }, { 196, 0x06 }, -+ { 195, 0x25 }, { 196, 0x09 }, -+ { 195, 0x26 }, { 196, 0x17 }, -+ { 195, 0x27 }, { 196, 0x06 }, -+ { 195, 0x28 }, { 196, 0x09 }, -+ { 195, 0x29 }, { 196, 0x05 }, -+ { 195, 0x2a }, { 196, 0x09 }, -+ { 195, 0x80 }, { 196, 0x8b }, -+ { 195, 0x81 }, { 196, 0x12 }, -+ { 195, 0x82 }, { 196, 0x09 }, -+ { 195, 0x83 }, { 196, 0x17 }, -+ { 195, 0x84 }, { 196, 0x11 }, -+ { 195, 0x85 }, { 196, 0x00 }, -+ { 195, 0x86 }, { 196, 0x00 }, -+ { 195, 0x87 }, { 196, 0x18 }, -+ { 195, 0x88 }, { 196, 0x60 }, -+ { 195, 0x89 }, { 196, 0x44 }, -+ { 195, 0x8a }, { 196, 0x8b }, -+ { 195, 0x8b }, { 196, 0x8b }, -+ { 195, 0x8c }, { 196, 0x8b }, -+ { 195, 0x8d }, { 196, 0x8b }, -+ { 195, 0x8e }, { 196, 0x09 }, -+ { 195, 0x8f }, { 196, 0x09 }, -+ { 195, 0x90 }, { 196, 0x09 }, -+ { 195, 0x91 }, { 196, 0x09 }, -+ { 195, 0x92 }, { 196, 0x11 }, -+ { 195, 0x93 }, { 196, 0x11 }, -+ { 195, 0x94 }, { 196, 0x11 }, -+ { 195, 0x95 }, { 196, 0x11 }, -+ /* PPAD */ -+ { 47, 0x80 }, { 60, 0x80 }, { 150, 0xd2 }, { 151, 0x32 }, -+ { 152, 0x23 }, { 153, 0x41 }, { 154, 0x00 }, { 155, 0x4f }, -+ { 253, 0x7e }, { 195, 0x30 }, { 196, 0x32 }, { 195, 0x31 }, -+ { 196, 0x23 }, { 195, 0x32 }, { 196, 0x45 }, { 195, 0x35 }, -+ { 196, 0x4a }, { 195, 0x36 }, { 196, 0x5a }, { 195, 0x37 }, -+ { 196, 0x5a }, -+}; -+ -+static const struct mt76_reg_pair mac_common_vals[] = { -+ { MT_LEGACY_BASIC_RATE, 0x0000013f }, -+ { MT_HT_BASIC_RATE, 0x00008003 }, -+ { MT_MAC_SYS_CTRL, 0x00000000 }, -+ { MT_RX_FILTR_CFG, 0x00017f97 }, -+ { MT_BKOFF_SLOT_CFG, 0x00000209 }, -+ { MT_TX_SW_CFG0, 0x00000000 }, -+ { MT_TX_SW_CFG1, 0x00080606 }, -+ { MT_TX_LINK_CFG, 0x00001020 }, -+ { MT_TX_TIMEOUT_CFG, 0x000a2090 }, -+ { MT_MAX_LEN_CFG, 0x00003fff }, -+ { MT_PBF_TX_MAX_PCNT, 0x1fbf1f1f }, -+ { MT_PBF_RX_MAX_PCNT, 0x0000009f }, -+ { MT_TX_RETRY_CFG, 0x47d01f0f }, -+ { MT_AUTO_RSP_CFG, 0x00000013 }, -+ { MT_CCK_PROT_CFG, 0x05740003 }, -+ { MT_OFDM_PROT_CFG, 0x05740003 }, -+ { MT_MM40_PROT_CFG, 0x03f44084 }, -+ { MT_GF20_PROT_CFG, 0x01744004 }, -+ { MT_GF40_PROT_CFG, 0x03f44084 }, -+ { MT_MM20_PROT_CFG, 0x01744004 }, -+ { MT_TXOP_CTRL_CFG, 0x0000583f }, -+ { MT_TX_RTS_CFG, 0x01092b20 }, -+ { MT_EXP_ACK_TIME, 0x002400ca }, -+ { MT_TXOP_HLDR_ET, 0x00000002 }, -+ { MT_XIFS_TIME_CFG, 0x33a41010 }, -+ { MT_PWR_PIN_CFG, 0x00000000 }, -+}; -+ -+static const struct mt76_reg_pair mac_chip_vals[] = { -+ { MT_TSO_CTRL, 0x00006050 }, -+ { MT_BCN_OFFSET(0), 0x18100800 }, -+ { MT_BCN_OFFSET(1), 0x38302820 }, -+ { MT_PBF_SYS_CTRL, 0x00080c00 }, -+ { MT_PBF_CFG, 0x7f723c1f }, -+ { MT_FCE_PSE_CTRL, 0x00000001 }, -+ { MT_PAUSE_ENABLE_CONTROL1, 0x00000000 }, -+ { MT_TX0_RF_GAIN_CORR, 0x003b0005 }, -+ { MT_TX0_RF_GAIN_ATTEN, 0x00006900 }, -+ { MT_TX0_BB_GAIN_ATTEN, 0x00000400 }, -+ { MT_TX_ALC_VGA3, 0x00060006 }, -+ { MT_TX_SW_CFG0, 0x00000402 }, -+ { MT_TX_SW_CFG1, 0x00000000 }, -+ { MT_TX_SW_CFG2, 0x00000000 }, -+ { MT_HEADER_TRANS_CTRL_REG, 0x00000000 }, -+ { MT_FCE_CSO, 0x0000030f }, -+ { MT_FCE_PARAMETERS, 0x00256f0f }, -+}; -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/initvals_phy.h b/drivers/net/wireless/mediatek/mt7601u/initvals_phy.h -new file mode 100644 -index 0000000..a2bdc3e ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/initvals_phy.h -@@ -0,0 +1,291 @@ -+/* -+ * (c) Copyright 2002-2010, Ralink Technology, Inc. -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT7601U_PHY_INITVALS_H -+#define __MT7601U_PHY_INITVALS_H -+ -+#define RF_REG_PAIR(bank, reg, value) \ -+ { MT_MCU_MEMMAP_RF | (bank) << 16 | (reg), value } -+ -+static const struct mt76_reg_pair rf_central[] = { -+ /* Bank 0 - for central blocks: BG, PLL, XTAL, LO, ADC/DAC */ -+ RF_REG_PAIR(0, 0, 0x02), -+ RF_REG_PAIR(0, 1, 0x01), -+ RF_REG_PAIR(0, 2, 0x11), -+ RF_REG_PAIR(0, 3, 0xff), -+ RF_REG_PAIR(0, 4, 0x0a), -+ RF_REG_PAIR(0, 5, 0x20), -+ RF_REG_PAIR(0, 6, 0x00), -+ /* B/G */ -+ RF_REG_PAIR(0, 7, 0x00), -+ RF_REG_PAIR(0, 8, 0x00), -+ RF_REG_PAIR(0, 9, 0x00), -+ RF_REG_PAIR(0, 10, 0x00), -+ RF_REG_PAIR(0, 11, 0x21), -+ /* XO */ -+ RF_REG_PAIR(0, 13, 0x00), /* 40mhz xtal */ -+ /* RF_REG_PAIR(0, 13, 0x13), */ /* 20mhz xtal */ -+ RF_REG_PAIR(0, 14, 0x7c), -+ RF_REG_PAIR(0, 15, 0x22), -+ RF_REG_PAIR(0, 16, 0x80), -+ /* PLL */ -+ RF_REG_PAIR(0, 17, 0x99), -+ RF_REG_PAIR(0, 18, 0x99), -+ RF_REG_PAIR(0, 19, 0x09), -+ RF_REG_PAIR(0, 20, 0x50), -+ RF_REG_PAIR(0, 21, 0xb0), -+ RF_REG_PAIR(0, 22, 0x00), -+ RF_REG_PAIR(0, 23, 0xc5), -+ RF_REG_PAIR(0, 24, 0xfc), -+ RF_REG_PAIR(0, 25, 0x40), -+ RF_REG_PAIR(0, 26, 0x4d), -+ RF_REG_PAIR(0, 27, 0x02), -+ RF_REG_PAIR(0, 28, 0x72), -+ RF_REG_PAIR(0, 29, 0x01), -+ RF_REG_PAIR(0, 30, 0x00), -+ RF_REG_PAIR(0, 31, 0x00), -+ /* test ports */ -+ RF_REG_PAIR(0, 32, 0x00), -+ RF_REG_PAIR(0, 33, 0x00), -+ RF_REG_PAIR(0, 34, 0x23), -+ RF_REG_PAIR(0, 35, 0x01), /* change setting to reduce spurs */ -+ RF_REG_PAIR(0, 36, 0x00), -+ RF_REG_PAIR(0, 37, 0x00), -+ /* ADC/DAC */ -+ RF_REG_PAIR(0, 38, 0x00), -+ RF_REG_PAIR(0, 39, 0x20), -+ RF_REG_PAIR(0, 40, 0x00), -+ RF_REG_PAIR(0, 41, 0xd0), -+ RF_REG_PAIR(0, 42, 0x1b), -+ RF_REG_PAIR(0, 43, 0x02), -+ RF_REG_PAIR(0, 44, 0x00), -+}; -+ -+static const struct mt76_reg_pair rf_channel[] = { -+ RF_REG_PAIR(4, 0, 0x01), -+ RF_REG_PAIR(4, 1, 0x00), -+ RF_REG_PAIR(4, 2, 0x00), -+ RF_REG_PAIR(4, 3, 0x00), -+ /* LDO */ -+ RF_REG_PAIR(4, 4, 0x00), -+ RF_REG_PAIR(4, 5, 0x08), -+ RF_REG_PAIR(4, 6, 0x00), -+ /* RX */ -+ RF_REG_PAIR(4, 7, 0x5b), -+ RF_REG_PAIR(4, 8, 0x52), -+ RF_REG_PAIR(4, 9, 0xb6), -+ RF_REG_PAIR(4, 10, 0x57), -+ RF_REG_PAIR(4, 11, 0x33), -+ RF_REG_PAIR(4, 12, 0x22), -+ RF_REG_PAIR(4, 13, 0x3d), -+ RF_REG_PAIR(4, 14, 0x3e), -+ RF_REG_PAIR(4, 15, 0x13), -+ RF_REG_PAIR(4, 16, 0x22), -+ RF_REG_PAIR(4, 17, 0x23), -+ RF_REG_PAIR(4, 18, 0x02), -+ RF_REG_PAIR(4, 19, 0xa4), -+ RF_REG_PAIR(4, 20, 0x01), -+ RF_REG_PAIR(4, 21, 0x12), -+ RF_REG_PAIR(4, 22, 0x80), -+ RF_REG_PAIR(4, 23, 0xb3), -+ RF_REG_PAIR(4, 24, 0x00), /* reserved */ -+ RF_REG_PAIR(4, 25, 0x00), /* reserved */ -+ RF_REG_PAIR(4, 26, 0x00), /* reserved */ -+ RF_REG_PAIR(4, 27, 0x00), /* reserved */ -+ /* LOGEN */ -+ RF_REG_PAIR(4, 28, 0x18), -+ RF_REG_PAIR(4, 29, 0xee), -+ RF_REG_PAIR(4, 30, 0x6b), -+ RF_REG_PAIR(4, 31, 0x31), -+ RF_REG_PAIR(4, 32, 0x5d), -+ RF_REG_PAIR(4, 33, 0x00), /* reserved */ -+ /* TX */ -+ RF_REG_PAIR(4, 34, 0x96), -+ RF_REG_PAIR(4, 35, 0x55), -+ RF_REG_PAIR(4, 36, 0x08), -+ RF_REG_PAIR(4, 37, 0xbb), -+ RF_REG_PAIR(4, 38, 0xb3), -+ RF_REG_PAIR(4, 39, 0xb3), -+ RF_REG_PAIR(4, 40, 0x03), -+ RF_REG_PAIR(4, 41, 0x00), /* reserved */ -+ RF_REG_PAIR(4, 42, 0x00), /* reserved */ -+ RF_REG_PAIR(4, 43, 0xc5), -+ RF_REG_PAIR(4, 44, 0xc5), -+ RF_REG_PAIR(4, 45, 0xc5), -+ RF_REG_PAIR(4, 46, 0x07), -+ RF_REG_PAIR(4, 47, 0xa8), -+ RF_REG_PAIR(4, 48, 0xef), -+ RF_REG_PAIR(4, 49, 0x1a), -+ /* PA */ -+ RF_REG_PAIR(4, 54, 0x07), -+ RF_REG_PAIR(4, 55, 0xa7), -+ RF_REG_PAIR(4, 56, 0xcc), -+ RF_REG_PAIR(4, 57, 0x14), -+ RF_REG_PAIR(4, 58, 0x07), -+ RF_REG_PAIR(4, 59, 0xa8), -+ RF_REG_PAIR(4, 60, 0xd7), -+ RF_REG_PAIR(4, 61, 0x10), -+ RF_REG_PAIR(4, 62, 0x1c), -+ RF_REG_PAIR(4, 63, 0x00), /* reserved */ -+}; -+ -+static const struct mt76_reg_pair rf_vga[] = { -+ RF_REG_PAIR(5, 0, 0x47), -+ RF_REG_PAIR(5, 1, 0x00), -+ RF_REG_PAIR(5, 2, 0x00), -+ RF_REG_PAIR(5, 3, 0x08), -+ RF_REG_PAIR(5, 4, 0x04), -+ RF_REG_PAIR(5, 5, 0x20), -+ RF_REG_PAIR(5, 6, 0x3a), -+ RF_REG_PAIR(5, 7, 0x3a), -+ RF_REG_PAIR(5, 8, 0x00), -+ RF_REG_PAIR(5, 9, 0x00), -+ RF_REG_PAIR(5, 10, 0x10), -+ RF_REG_PAIR(5, 11, 0x10), -+ RF_REG_PAIR(5, 12, 0x10), -+ RF_REG_PAIR(5, 13, 0x10), -+ RF_REG_PAIR(5, 14, 0x10), -+ RF_REG_PAIR(5, 15, 0x20), -+ RF_REG_PAIR(5, 16, 0x22), -+ RF_REG_PAIR(5, 17, 0x7c), -+ RF_REG_PAIR(5, 18, 0x00), -+ RF_REG_PAIR(5, 19, 0x00), -+ RF_REG_PAIR(5, 20, 0x00), -+ RF_REG_PAIR(5, 21, 0xf1), -+ RF_REG_PAIR(5, 22, 0x11), -+ RF_REG_PAIR(5, 23, 0x02), -+ RF_REG_PAIR(5, 24, 0x41), -+ RF_REG_PAIR(5, 25, 0x20), -+ RF_REG_PAIR(5, 26, 0x00), -+ RF_REG_PAIR(5, 27, 0xd7), -+ RF_REG_PAIR(5, 28, 0xa2), -+ RF_REG_PAIR(5, 29, 0x20), -+ RF_REG_PAIR(5, 30, 0x49), -+ RF_REG_PAIR(5, 31, 0x20), -+ RF_REG_PAIR(5, 32, 0x04), -+ RF_REG_PAIR(5, 33, 0xf1), -+ RF_REG_PAIR(5, 34, 0xa1), -+ RF_REG_PAIR(5, 35, 0x01), -+ RF_REG_PAIR(5, 41, 0x00), -+ RF_REG_PAIR(5, 42, 0x00), -+ RF_REG_PAIR(5, 43, 0x00), -+ RF_REG_PAIR(5, 44, 0x00), -+ RF_REG_PAIR(5, 45, 0x00), -+ RF_REG_PAIR(5, 46, 0x00), -+ RF_REG_PAIR(5, 47, 0x00), -+ RF_REG_PAIR(5, 48, 0x00), -+ RF_REG_PAIR(5, 49, 0x00), -+ RF_REG_PAIR(5, 50, 0x00), -+ RF_REG_PAIR(5, 51, 0x00), -+ RF_REG_PAIR(5, 52, 0x00), -+ RF_REG_PAIR(5, 53, 0x00), -+ RF_REG_PAIR(5, 54, 0x00), -+ RF_REG_PAIR(5, 55, 0x00), -+ RF_REG_PAIR(5, 56, 0x00), -+ RF_REG_PAIR(5, 57, 0x00), -+ RF_REG_PAIR(5, 58, 0x31), -+ RF_REG_PAIR(5, 59, 0x31), -+ RF_REG_PAIR(5, 60, 0x0a), -+ RF_REG_PAIR(5, 61, 0x02), -+ RF_REG_PAIR(5, 62, 0x00), -+ RF_REG_PAIR(5, 63, 0x00), -+}; -+ -+/* TODO: BBP178 is set to 0xff for "CCK CH14 OBW" which overrides the settings -+ * from channel switching. Seems stupid at best. -+ */ -+static const struct mt76_reg_pair bbp_high_temp[] = { -+ { 75, 0x60 }, -+ { 92, 0x02 }, -+ { 178, 0xff }, /* For CCK CH14 OBW */ -+ { 195, 0x88 }, { 196, 0x60 }, -+}, bbp_high_temp_bw20[] = { -+ { 69, 0x12 }, -+ { 91, 0x07 }, -+ { 195, 0x23 }, { 196, 0x17 }, -+ { 195, 0x24 }, { 196, 0x06 }, -+ { 195, 0x81 }, { 196, 0x12 }, -+ { 195, 0x83 }, { 196, 0x17 }, -+}, bbp_high_temp_bw40[] = { -+ { 69, 0x15 }, -+ { 91, 0x04 }, -+ { 195, 0x23 }, { 196, 0x12 }, -+ { 195, 0x24 }, { 196, 0x08 }, -+ { 195, 0x81 }, { 196, 0x15 }, -+ { 195, 0x83 }, { 196, 0x16 }, -+}, bbp_low_temp[] = { -+ { 178, 0xff }, /* For CCK CH14 OBW */ -+}, bbp_low_temp_bw20[] = { -+ { 69, 0x12 }, -+ { 75, 0x5e }, -+ { 91, 0x07 }, -+ { 92, 0x02 }, -+ { 195, 0x23 }, { 196, 0x17 }, -+ { 195, 0x24 }, { 196, 0x06 }, -+ { 195, 0x81 }, { 196, 0x12 }, -+ { 195, 0x83 }, { 196, 0x17 }, -+ { 195, 0x88 }, { 196, 0x5e }, -+}, bbp_low_temp_bw40[] = { -+ { 69, 0x15 }, -+ { 75, 0x5c }, -+ { 91, 0x04 }, -+ { 92, 0x03 }, -+ { 195, 0x23 }, { 196, 0x10 }, -+ { 195, 0x24 }, { 196, 0x08 }, -+ { 195, 0x81 }, { 196, 0x15 }, -+ { 195, 0x83 }, { 196, 0x16 }, -+ { 195, 0x88 }, { 196, 0x5b }, -+}, bbp_normal_temp[] = { -+ { 75, 0x60 }, -+ { 92, 0x02 }, -+ { 178, 0xff }, /* For CCK CH14 OBW */ -+ { 195, 0x88 }, { 196, 0x60 }, -+}, bbp_normal_temp_bw20[] = { -+ { 69, 0x12 }, -+ { 91, 0x07 }, -+ { 195, 0x23 }, { 196, 0x17 }, -+ { 195, 0x24 }, { 196, 0x06 }, -+ { 195, 0x81 }, { 196, 0x12 }, -+ { 195, 0x83 }, { 196, 0x17 }, -+}, bbp_normal_temp_bw40[] = { -+ { 69, 0x15 }, -+ { 91, 0x04 }, -+ { 195, 0x23 }, { 196, 0x12 }, -+ { 195, 0x24 }, { 196, 0x08 }, -+ { 195, 0x81 }, { 196, 0x15 }, -+ { 195, 0x83 }, { 196, 0x16 }, -+}; -+ -+#define BBP_TABLE(arr) { arr, ARRAY_SIZE(arr), } -+ -+static const struct reg_table { -+ const struct mt76_reg_pair *regs; -+ size_t n; -+} bbp_mode_table[3][3] = { -+ { -+ BBP_TABLE(bbp_normal_temp_bw20), -+ BBP_TABLE(bbp_normal_temp_bw40), -+ BBP_TABLE(bbp_normal_temp), -+ }, { -+ BBP_TABLE(bbp_high_temp_bw20), -+ BBP_TABLE(bbp_high_temp_bw40), -+ BBP_TABLE(bbp_high_temp), -+ }, { -+ BBP_TABLE(bbp_low_temp_bw20), -+ BBP_TABLE(bbp_low_temp_bw40), -+ BBP_TABLE(bbp_low_temp), -+ } -+}; -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/mac.c b/drivers/net/wireless/mediatek/mt7601u/mac.c -new file mode 100644 -index 0000000..7514bce ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/mac.c -@@ -0,0 +1,573 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+#include "trace.h" -+#include -+ -+static void -+mt76_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate) -+{ -+ u8 idx = MT76_GET(MT_TXWI_RATE_MCS, rate); -+ -+ txrate->idx = 0; -+ txrate->flags = 0; -+ txrate->count = 1; -+ -+ switch (MT76_GET(MT_TXWI_RATE_PHY_MODE, rate)) { -+ case MT_PHY_TYPE_OFDM: -+ txrate->idx = idx + 4; -+ return; -+ case MT_PHY_TYPE_CCK: -+ if (idx >= 8) -+ idx -= 8; -+ -+ txrate->idx = idx; -+ return; -+ case MT_PHY_TYPE_HT_GF: -+ txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD; -+ /* fall through */ -+ case MT_PHY_TYPE_HT: -+ txrate->flags |= IEEE80211_TX_RC_MCS; -+ txrate->idx = idx; -+ break; -+ default: -+ WARN_ON(1); -+ return; -+ } -+ -+ if (MT76_GET(MT_TXWI_RATE_BW, rate) == MT_PHY_BW_40) -+ txrate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; -+ -+ if (rate & MT_TXWI_RATE_SGI) -+ txrate->flags |= IEEE80211_TX_RC_SHORT_GI; -+} -+ -+static void -+mt76_mac_fill_tx_status(struct mt7601u_dev *dev, struct ieee80211_tx_info *info, -+ struct mt76_tx_status *st) -+{ -+ struct ieee80211_tx_rate *rate = info->status.rates; -+ int cur_idx, last_rate; -+ int i; -+ -+ last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); -+ mt76_mac_process_tx_rate(&rate[last_rate], st->rate); -+ if (last_rate < IEEE80211_TX_MAX_RATES - 1) -+ rate[last_rate + 1].idx = -1; -+ -+ cur_idx = rate[last_rate].idx + st->retry; -+ for (i = 0; i <= last_rate; i++) { -+ rate[i].flags = rate[last_rate].flags; -+ rate[i].idx = max_t(int, 0, cur_idx - i); -+ rate[i].count = 1; -+ } -+ -+ if (last_rate > 0) -+ rate[last_rate - 1].count = st->retry + 1 - last_rate; -+ -+ info->status.ampdu_len = 1; -+ info->status.ampdu_ack_len = st->success; -+ -+ if (st->is_probe) -+ info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; -+ -+ if (st->aggr) -+ info->flags |= IEEE80211_TX_CTL_AMPDU | -+ IEEE80211_TX_STAT_AMPDU; -+ -+ if (!st->ack_req) -+ info->flags |= IEEE80211_TX_CTL_NO_ACK; -+ else if (st->success) -+ info->flags |= IEEE80211_TX_STAT_ACK; -+} -+ -+u16 mt76_mac_tx_rate_val(struct mt7601u_dev *dev, -+ const struct ieee80211_tx_rate *rate, u8 *nss_val) -+{ -+ u16 rateval; -+ u8 phy, rate_idx; -+ u8 nss = 1; -+ u8 bw = 0; -+ -+ if (rate->flags & IEEE80211_TX_RC_MCS) { -+ rate_idx = rate->idx; -+ nss = 1 + (rate->idx >> 3); -+ phy = MT_PHY_TYPE_HT; -+ if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD) -+ phy = MT_PHY_TYPE_HT_GF; -+ if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) -+ bw = 1; -+ } else { -+ const struct ieee80211_rate *r; -+ int band = dev->chandef.chan->band; -+ u16 val; -+ -+ r = &dev->hw->wiphy->bands[band]->bitrates[rate->idx]; -+ if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) -+ val = r->hw_value_short; -+ else -+ val = r->hw_value; -+ -+ phy = val >> 8; -+ rate_idx = val & 0xff; -+ bw = 0; -+ } -+ -+ rateval = MT76_SET(MT_RXWI_RATE_MCS, rate_idx); -+ rateval |= MT76_SET(MT_RXWI_RATE_PHY, phy); -+ rateval |= MT76_SET(MT_RXWI_RATE_BW, bw); -+ if (rate->flags & IEEE80211_TX_RC_SHORT_GI) -+ rateval |= MT_RXWI_RATE_SGI; -+ -+ *nss_val = nss; -+ return rateval; -+} -+ -+void mt76_mac_wcid_set_rate(struct mt7601u_dev *dev, struct mt76_wcid *wcid, -+ const struct ieee80211_tx_rate *rate) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ wcid->tx_rate = mt76_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); -+ wcid->tx_rate_set = true; -+ spin_unlock_irqrestore(&dev->lock, flags); -+} -+ -+struct mt76_tx_status mt7601u_mac_fetch_tx_status(struct mt7601u_dev *dev) -+{ -+ struct mt76_tx_status stat = {}; -+ u32 val; -+ -+ val = mt7601u_rr(dev, MT_TX_STAT_FIFO); -+ stat.valid = !!(val & MT_TX_STAT_FIFO_VALID); -+ stat.success = !!(val & MT_TX_STAT_FIFO_SUCCESS); -+ stat.aggr = !!(val & MT_TX_STAT_FIFO_AGGR); -+ stat.ack_req = !!(val & MT_TX_STAT_FIFO_ACKREQ); -+ stat.pktid = MT76_GET(MT_TX_STAT_FIFO_PID_TYPE, val); -+ stat.wcid = MT76_GET(MT_TX_STAT_FIFO_WCID, val); -+ stat.rate = MT76_GET(MT_TX_STAT_FIFO_RATE, val); -+ -+ return stat; -+} -+ -+void mt76_send_tx_status(struct mt7601u_dev *dev, struct mt76_tx_status *stat) -+{ -+ struct ieee80211_tx_info info = {}; -+ struct ieee80211_sta *sta = NULL; -+ struct mt76_wcid *wcid = NULL; -+ void *msta; -+ -+ rcu_read_lock(); -+ if (stat->wcid < ARRAY_SIZE(dev->wcid)) -+ wcid = rcu_dereference(dev->wcid[stat->wcid]); -+ -+ if (wcid) { -+ msta = container_of(wcid, struct mt76_sta, wcid); -+ sta = container_of(msta, struct ieee80211_sta, -+ drv_priv); -+ } -+ -+ mt76_mac_fill_tx_status(dev, &info, stat); -+ ieee80211_tx_status_noskb(dev->hw, sta, &info); -+ rcu_read_unlock(); -+} -+ -+void mt7601u_mac_set_protection(struct mt7601u_dev *dev, bool legacy_prot, -+ int ht_mode) -+{ -+ int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION; -+ bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); -+ u32 prot[6]; -+ bool ht_rts[4] = {}; -+ int i; -+ -+ prot[0] = MT_PROT_NAV_SHORT | -+ MT_PROT_TXOP_ALLOW_ALL | -+ MT_PROT_RTS_THR_EN; -+ prot[1] = prot[0]; -+ if (legacy_prot) -+ prot[1] |= MT_PROT_CTRL_CTS2SELF; -+ -+ prot[2] = prot[4] = MT_PROT_NAV_SHORT | MT_PROT_TXOP_ALLOW_BW20; -+ prot[3] = prot[5] = MT_PROT_NAV_SHORT | MT_PROT_TXOP_ALLOW_ALL; -+ -+ if (legacy_prot) { -+ prot[2] |= MT_PROT_RATE_CCK_11; -+ prot[3] |= MT_PROT_RATE_CCK_11; -+ prot[4] |= MT_PROT_RATE_CCK_11; -+ prot[5] |= MT_PROT_RATE_CCK_11; -+ } else { -+ prot[2] |= MT_PROT_RATE_OFDM_24; -+ prot[3] |= MT_PROT_RATE_DUP_OFDM_24; -+ prot[4] |= MT_PROT_RATE_OFDM_24; -+ prot[5] |= MT_PROT_RATE_DUP_OFDM_24; -+ } -+ -+ switch (mode) { -+ case IEEE80211_HT_OP_MODE_PROTECTION_NONE: -+ break; -+ -+ case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: -+ ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true; -+ break; -+ -+ case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: -+ ht_rts[1] = ht_rts[3] = true; -+ break; -+ -+ case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: -+ ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true; -+ break; -+ } -+ -+ if (non_gf) -+ ht_rts[2] = ht_rts[3] = true; -+ -+ for (i = 0; i < 4; i++) -+ if (ht_rts[i]) -+ prot[i + 2] |= MT_PROT_CTRL_RTS_CTS; -+ -+ for (i = 0; i < 6; i++) -+ mt7601u_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]); -+} -+ -+void mt7601u_mac_set_short_preamble(struct mt7601u_dev *dev, bool short_preamb) -+{ -+ if (short_preamb) -+ mt76_set(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT); -+ else -+ mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT); -+} -+ -+void mt7601u_mac_config_tsf(struct mt7601u_dev *dev, bool enable, int interval) -+{ -+ u32 val = mt7601u_rr(dev, MT_BEACON_TIME_CFG); -+ -+ val &= ~(MT_BEACON_TIME_CFG_TIMER_EN | -+ MT_BEACON_TIME_CFG_SYNC_MODE | -+ MT_BEACON_TIME_CFG_TBTT_EN); -+ -+ if (!enable) { -+ mt7601u_wr(dev, MT_BEACON_TIME_CFG, val); -+ return; -+ } -+ -+ val &= ~MT_BEACON_TIME_CFG_INTVAL; -+ val |= MT76_SET(MT_BEACON_TIME_CFG_INTVAL, interval << 4) | -+ MT_BEACON_TIME_CFG_TIMER_EN | -+ MT_BEACON_TIME_CFG_SYNC_MODE | -+ MT_BEACON_TIME_CFG_TBTT_EN; -+} -+ -+static void mt7601u_check_mac_err(struct mt7601u_dev *dev) -+{ -+ u32 val = mt7601u_rr(dev, 0x10f4); -+ -+ if (!(val & BIT(29)) || !(val & (BIT(7) | BIT(5)))) -+ return; -+ -+ dev_err(dev->dev, "Error: MAC specific condition occurred\n"); -+ -+ mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR); -+ udelay(10); -+ mt76_clear(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR); -+} -+ -+void mt7601u_mac_work(struct work_struct *work) -+{ -+ struct mt7601u_dev *dev = container_of(work, struct mt7601u_dev, -+ mac_work.work); -+ struct { -+ u32 addr_base; -+ u32 span; -+ u64 *stat_base; -+ } spans[] = { -+ { MT_RX_STA_CNT0, 3, dev->stats.rx_stat }, -+ { MT_TX_STA_CNT0, 3, dev->stats.tx_stat }, -+ { MT_TX_AGG_STAT, 1, dev->stats.aggr_stat }, -+ { MT_MPDU_DENSITY_CNT, 1, dev->stats.zero_len_del }, -+ { MT_TX_AGG_CNT_BASE0, 8, &dev->stats.aggr_n[0] }, -+ { MT_TX_AGG_CNT_BASE1, 8, &dev->stats.aggr_n[16] }, -+ }; -+ u32 sum, n; -+ int i, j, k; -+ -+ /* Note: using MCU_RANDOM_READ is actually slower then reading all the -+ * registers by hand. MCU takes ca. 20ms to complete read of 24 -+ * registers while reading them one by one will takes roughly -+ * 24*200us =~ 5ms. -+ */ -+ -+ k = 0; -+ n = 0; -+ sum = 0; -+ for (i = 0; i < ARRAY_SIZE(spans); i++) -+ for (j = 0; j < spans[i].span; j++) { -+ u32 val = mt7601u_rr(dev, spans[i].addr_base + j * 4); -+ -+ spans[i].stat_base[j * 2] += val & 0xffff; -+ spans[i].stat_base[j * 2 + 1] += val >> 16; -+ -+ /* Calculate average AMPDU length */ -+ if (spans[i].addr_base != MT_TX_AGG_CNT_BASE0 && -+ spans[i].addr_base != MT_TX_AGG_CNT_BASE1) -+ continue; -+ -+ n += (val >> 16) + (val & 0xffff); -+ sum += (val & 0xffff) * (1 + k * 2) + -+ (val >> 16) * (2 + k * 2); -+ k++; -+ } -+ -+ atomic_set(&dev->avg_ampdu_len, n ? DIV_ROUND_CLOSEST(sum, n) : 1); -+ -+ mt7601u_check_mac_err(dev); -+ -+ ieee80211_queue_delayed_work(dev->hw, &dev->mac_work, 10 * HZ); -+} -+ -+void -+mt7601u_mac_wcid_setup(struct mt7601u_dev *dev, u8 idx, u8 vif_idx, u8 *mac) -+{ -+ u8 zmac[ETH_ALEN] = {}; -+ u32 attr; -+ -+ attr = MT76_SET(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | -+ MT76_SET(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); -+ -+ mt76_wr(dev, MT_WCID_ATTR(idx), attr); -+ -+ if (mac) -+ memcpy(zmac, mac, sizeof(zmac)); -+ -+ mt7601u_addr_wr(dev, MT_WCID_ADDR(idx), zmac); -+} -+ -+void mt7601u_mac_set_ampdu_factor(struct mt7601u_dev *dev) -+{ -+ struct ieee80211_sta *sta; -+ struct mt76_wcid *wcid; -+ void *msta; -+ u8 min_factor = 3; -+ int i; -+ -+ rcu_read_lock(); -+ for (i = 0; i < ARRAY_SIZE(dev->wcid); i++) { -+ wcid = rcu_dereference(dev->wcid[i]); -+ if (!wcid) -+ continue; -+ -+ msta = container_of(wcid, struct mt76_sta, wcid); -+ sta = container_of(msta, struct ieee80211_sta, drv_priv); -+ -+ min_factor = min(min_factor, sta->ht_cap.ampdu_factor); -+ } -+ rcu_read_unlock(); -+ -+ mt7601u_wr(dev, MT_MAX_LEN_CFG, 0xa0fff | -+ MT76_SET(MT_MAX_LEN_CFG_AMPDU, min_factor)); -+} -+ -+static void -+mt76_mac_process_rate(struct ieee80211_rx_status *status, u16 rate) -+{ -+ u8 idx = MT76_GET(MT_RXWI_RATE_MCS, rate); -+ -+ switch (MT76_GET(MT_RXWI_RATE_PHY, rate)) { -+ case MT_PHY_TYPE_OFDM: -+ if (WARN_ON(idx >= 8)) -+ idx = 0; -+ idx += 4; -+ -+ status->rate_idx = idx; -+ return; -+ case MT_PHY_TYPE_CCK: -+ if (idx >= 8) { -+ idx -= 8; -+ status->flag |= RX_FLAG_SHORTPRE; -+ } -+ -+ if (WARN_ON(idx >= 4)) -+ idx = 0; -+ -+ status->rate_idx = idx; -+ return; -+ case MT_PHY_TYPE_HT_GF: -+ status->flag |= RX_FLAG_HT_GF; -+ /* fall through */ -+ case MT_PHY_TYPE_HT: -+ status->flag |= RX_FLAG_HT; -+ status->rate_idx = idx; -+ break; -+ default: -+ WARN_ON(1); -+ return; -+ } -+ -+ if (rate & MT_RXWI_RATE_SGI) -+ status->flag |= RX_FLAG_SHORT_GI; -+ -+ if (rate & MT_RXWI_RATE_STBC) -+ status->flag |= 1 << RX_FLAG_STBC_SHIFT; -+ -+ if (rate & MT_RXWI_RATE_BW) -+ status->flag |= RX_FLAG_40MHZ; -+} -+ -+static void -+mt7601u_rx_monitor_beacon(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi, -+ u16 rate, int rssi) -+{ -+ dev->bcn_freq_off = rxwi->freq_off; -+ dev->bcn_phy_mode = MT76_GET(MT_RXWI_RATE_PHY, rate); -+ dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8); -+} -+ -+static int -+mt7601u_rx_is_our_beacon(struct mt7601u_dev *dev, u8 *data) -+{ -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data; -+ -+ return ieee80211_is_beacon(hdr->frame_control) && -+ ether_addr_equal(hdr->addr2, dev->ap_bssid); -+} -+ -+u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb, -+ u8 *data, void *rxi) -+{ -+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -+ struct mt7601u_rxwi *rxwi = rxi; -+ u32 len, ctl = le32_to_cpu(rxwi->ctl); -+ u16 rate = le16_to_cpu(rxwi->rate); -+ int rssi; -+ -+ len = MT76_GET(MT_RXWI_CTL_MPDU_LEN, ctl); -+ if (len < 10) -+ return 0; -+ -+ if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_DECRYPT)) { -+ status->flag |= RX_FLAG_DECRYPTED; -+ status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; -+ } -+ -+ status->chains = BIT(0); -+ rssi = mt7601u_phy_get_rssi(dev, rxwi, rate); -+ status->chain_signal[0] = status->signal = rssi; -+ status->freq = dev->chandef.chan->center_freq; -+ status->band = dev->chandef.chan->band; -+ -+ mt76_mac_process_rate(status, rate); -+ -+ spin_lock_bh(&dev->con_mon_lock); -+ if (mt7601u_rx_is_our_beacon(dev, data)) -+ mt7601u_rx_monitor_beacon(dev, rxwi, rate, rssi); -+ else if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_U2M)) -+ dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8); -+ spin_unlock_bh(&dev->con_mon_lock); -+ -+ return len; -+} -+ -+static enum mt76_cipher_type -+mt76_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) -+{ -+ memset(key_data, 0, 32); -+ if (!key) -+ return MT_CIPHER_NONE; -+ -+ if (key->keylen > 32) -+ return MT_CIPHER_NONE; -+ -+ memcpy(key_data, key->key, key->keylen); -+ -+ switch (key->cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ return MT_CIPHER_WEP40; -+ case WLAN_CIPHER_SUITE_WEP104: -+ return MT_CIPHER_WEP104; -+ case WLAN_CIPHER_SUITE_TKIP: -+ return MT_CIPHER_TKIP; -+ case WLAN_CIPHER_SUITE_CCMP: -+ return MT_CIPHER_AES_CCMP; -+ default: -+ return MT_CIPHER_NONE; -+ } -+} -+ -+int mt76_mac_wcid_set_key(struct mt7601u_dev *dev, u8 idx, -+ struct ieee80211_key_conf *key) -+{ -+ enum mt76_cipher_type cipher; -+ u8 key_data[32]; -+ u8 iv_data[8]; -+ u32 val; -+ -+ cipher = mt76_mac_get_key_info(key, key_data); -+ if (cipher == MT_CIPHER_NONE && key) -+ return -EINVAL; -+ -+ trace_set_key(dev, idx); -+ -+ mt7601u_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); -+ -+ memset(iv_data, 0, sizeof(iv_data)); -+ if (key) { -+ iv_data[3] = key->keyidx << 6; -+ if (cipher >= MT_CIPHER_TKIP) { -+ /* Note: start with 1 to comply with spec, -+ * (see comment on common/cmm_wpa.c:4291). -+ */ -+ iv_data[0] |= 1; -+ iv_data[3] |= 0x20; -+ } -+ } -+ mt7601u_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); -+ -+ val = mt7601u_rr(dev, MT_WCID_ATTR(idx)); -+ val &= ~MT_WCID_ATTR_PKEY_MODE & ~MT_WCID_ATTR_PKEY_MODE_EXT; -+ val |= MT76_SET(MT_WCID_ATTR_PKEY_MODE, cipher & 7) | -+ MT76_SET(MT_WCID_ATTR_PKEY_MODE_EXT, cipher >> 3); -+ val &= ~MT_WCID_ATTR_PAIRWISE; -+ val |= MT_WCID_ATTR_PAIRWISE * -+ !!(key && key->flags & IEEE80211_KEY_FLAG_PAIRWISE); -+ mt7601u_wr(dev, MT_WCID_ATTR(idx), val); -+ -+ return 0; -+} -+ -+int mt76_mac_shared_key_setup(struct mt7601u_dev *dev, u8 vif_idx, u8 key_idx, -+ struct ieee80211_key_conf *key) -+{ -+ enum mt76_cipher_type cipher; -+ u8 key_data[32]; -+ u32 val; -+ -+ cipher = mt76_mac_get_key_info(key, key_data); -+ if (cipher == MT_CIPHER_NONE && key) -+ return -EINVAL; -+ -+ trace_set_shared_key(dev, vif_idx, key_idx); -+ -+ mt7601u_wr_copy(dev, MT_SKEY(vif_idx, key_idx), -+ key_data, sizeof(key_data)); -+ -+ val = mt76_rr(dev, MT_SKEY_MODE(vif_idx)); -+ val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); -+ val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); -+ mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/mac.h b/drivers/net/wireless/mediatek/mt7601u/mac.h -new file mode 100644 -index 0000000..2c22d63 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/mac.h -@@ -0,0 +1,178 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT76_MAC_H -+#define __MT76_MAC_H -+ -+struct mt76_tx_status { -+ u8 valid:1; -+ u8 success:1; -+ u8 aggr:1; -+ u8 ack_req:1; -+ u8 is_probe:1; -+ u8 wcid; -+ u8 pktid; -+ u8 retry; -+ u16 rate; -+} __packed __aligned(2); -+ -+/* Note: values in original "RSSI" and "SNR" fields are not actually what they -+ * are called for MT7601U, names used by this driver are educated guesses -+ * (see vendor mac/ral_omac.c). -+ */ -+struct mt7601u_rxwi { -+ __le32 rxinfo; -+ -+ __le32 ctl; -+ -+ __le16 frag_sn; -+ __le16 rate; -+ -+ u8 unknown; -+ u8 zero[3]; -+ -+ u8 snr; -+ u8 ant; -+ u8 gain; -+ u8 freq_off; -+ -+ __le32 resv2; -+ __le32 expert_ant; -+} __packed __aligned(4); -+ -+#define MT_RXINFO_BA BIT(0) -+#define MT_RXINFO_DATA BIT(1) -+#define MT_RXINFO_NULL BIT(2) -+#define MT_RXINFO_FRAG BIT(3) -+#define MT_RXINFO_U2M BIT(4) -+#define MT_RXINFO_MULTICAST BIT(5) -+#define MT_RXINFO_BROADCAST BIT(6) -+#define MT_RXINFO_MYBSS BIT(7) -+#define MT_RXINFO_CRCERR BIT(8) -+#define MT_RXINFO_ICVERR BIT(9) -+#define MT_RXINFO_MICERR BIT(10) -+#define MT_RXINFO_AMSDU BIT(11) -+#define MT_RXINFO_HTC BIT(12) -+#define MT_RXINFO_RSSI BIT(13) -+#define MT_RXINFO_L2PAD BIT(14) -+#define MT_RXINFO_AMPDU BIT(15) -+#define MT_RXINFO_DECRYPT BIT(16) -+#define MT_RXINFO_BSSIDX3 BIT(17) -+#define MT_RXINFO_WAPI_KEY BIT(18) -+#define MT_RXINFO_PN_LEN GENMASK(21, 19) -+#define MT_RXINFO_SW_PKT_80211 BIT(22) -+#define MT_RXINFO_TCP_SUM_BYPASS BIT(28) -+#define MT_RXINFO_IP_SUM_BYPASS BIT(29) -+#define MT_RXINFO_TCP_SUM_ERR BIT(30) -+#define MT_RXINFO_IP_SUM_ERR BIT(31) -+ -+#define MT_RXWI_CTL_WCID GENMASK(7, 0) -+#define MT_RXWI_CTL_KEY_IDX GENMASK(9, 8) -+#define MT_RXWI_CTL_BSS_IDX GENMASK(12, 10) -+#define MT_RXWI_CTL_UDF GENMASK(15, 13) -+#define MT_RXWI_CTL_MPDU_LEN GENMASK(27, 16) -+#define MT_RXWI_CTL_TID GENMASK(31, 28) -+ -+#define MT_RXWI_FRAG GENMASK(3, 0) -+#define MT_RXWI_SN GENMASK(15, 4) -+ -+#define MT_RXWI_RATE_MCS GENMASK(6, 0) -+#define MT_RXWI_RATE_BW BIT(7) -+#define MT_RXWI_RATE_SGI BIT(8) -+#define MT_RXWI_RATE_STBC GENMASK(10, 9) -+#define MT_RXWI_RATE_ETXBF BIT(11) -+#define MT_RXWI_RATE_SND BIT(12) -+#define MT_RXWI_RATE_ITXBF BIT(13) -+#define MT_RXWI_RATE_PHY GENMASK(15, 14) -+ -+#define MT_RXWI_GAIN_RSSI_VAL GENMASK(5, 0) -+#define MT_RXWI_GAIN_RSSI_LNA_ID GENMASK(7, 6) -+#define MT_RXWI_ANT_AUX_LNA BIT(7) -+ -+#define MT_RXWI_EANT_ENC_ANT_ID GENMASK(7, 0) -+ -+enum mt76_phy_type { -+ MT_PHY_TYPE_CCK, -+ MT_PHY_TYPE_OFDM, -+ MT_PHY_TYPE_HT, -+ MT_PHY_TYPE_HT_GF, -+}; -+ -+enum mt76_phy_bandwidth { -+ MT_PHY_BW_20, -+ MT_PHY_BW_40, -+}; -+ -+struct mt76_txwi { -+ __le16 flags; -+ __le16 rate_ctl; -+ -+ u8 ack_ctl; -+ u8 wcid; -+ __le16 len_ctl; -+ -+ __le32 iv; -+ -+ __le32 eiv; -+ -+ u8 aid; -+ u8 txstream; -+ __le16 ctl; -+} __packed __aligned(4); -+ -+#define MT_TXWI_FLAGS_FRAG BIT(0) -+#define MT_TXWI_FLAGS_MMPS BIT(1) -+#define MT_TXWI_FLAGS_CFACK BIT(2) -+#define MT_TXWI_FLAGS_TS BIT(3) -+#define MT_TXWI_FLAGS_AMPDU BIT(4) -+#define MT_TXWI_FLAGS_MPDU_DENSITY GENMASK(7, 5) -+#define MT_TXWI_FLAGS_TXOP GENMASK(9, 8) -+#define MT_TXWI_FLAGS_CWMIN GENMASK(12, 10) -+#define MT_TXWI_FLAGS_NO_RATE_FALLBACK BIT(13) -+#define MT_TXWI_FLAGS_TX_RPT BIT(14) -+#define MT_TXWI_FLAGS_TX_RATE_LUT BIT(15) -+ -+#define MT_TXWI_RATE_MCS GENMASK(6, 0) -+#define MT_TXWI_RATE_BW BIT(7) -+#define MT_TXWI_RATE_SGI BIT(8) -+#define MT_TXWI_RATE_STBC GENMASK(10, 9) -+#define MT_TXWI_RATE_PHY_MODE GENMASK(15, 14) -+ -+#define MT_TXWI_ACK_CTL_REQ BIT(0) -+#define MT_TXWI_ACK_CTL_NSEQ BIT(1) -+#define MT_TXWI_ACK_CTL_BA_WINDOW GENMASK(7, 2) -+ -+#define MT_TXWI_LEN_BYTE_CNT GENMASK(11, 0) -+#define MT_TXWI_LEN_PKTID GENMASK(15, 12) -+ -+#define MT_TXWI_CTL_TX_POWER_ADJ GENMASK(3, 0) -+#define MT_TXWI_CTL_CHAN_CHECK_PKT BIT(4) -+#define MT_TXWI_CTL_PIFS_REV BIT(6) -+ -+u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb, -+ u8 *data, void *rxi); -+int mt76_mac_wcid_set_key(struct mt7601u_dev *dev, u8 idx, -+ struct ieee80211_key_conf *key); -+void mt76_mac_wcid_set_rate(struct mt7601u_dev *dev, struct mt76_wcid *wcid, -+ const struct ieee80211_tx_rate *rate); -+ -+int mt76_mac_shared_key_setup(struct mt7601u_dev *dev, u8 vif_idx, u8 key_idx, -+ struct ieee80211_key_conf *key); -+u16 mt76_mac_tx_rate_val(struct mt7601u_dev *dev, -+ const struct ieee80211_tx_rate *rate, u8 *nss_val); -+struct mt76_tx_status -+mt7601u_mac_fetch_tx_status(struct mt7601u_dev *dev); -+void mt76_send_tx_status(struct mt7601u_dev *dev, struct mt76_tx_status *stat); -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/main.c b/drivers/net/wireless/mediatek/mt7601u/main.c -new file mode 100644 -index 0000000..169384b ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/main.c -@@ -0,0 +1,413 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+#include "mac.h" -+#include -+#include -+ -+static int mt7601u_start(struct ieee80211_hw *hw) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ int ret; -+ -+ mutex_lock(&dev->mutex); -+ -+ ret = mt7601u_mac_start(dev); -+ if (ret) -+ goto out; -+ -+ ieee80211_queue_delayed_work(dev->hw, &dev->mac_work, -+ MT_CALIBRATE_INTERVAL); -+ ieee80211_queue_delayed_work(dev->hw, &dev->cal_work, -+ MT_CALIBRATE_INTERVAL); -+out: -+ mutex_unlock(&dev->mutex); -+ return ret; -+} -+ -+static void mt7601u_stop(struct ieee80211_hw *hw) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ -+ mutex_lock(&dev->mutex); -+ -+ cancel_delayed_work_sync(&dev->cal_work); -+ cancel_delayed_work_sync(&dev->mac_work); -+ mt7601u_mac_stop(dev); -+ -+ mutex_unlock(&dev->mutex); -+} -+ -+static int mt7601u_add_interface(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; -+ unsigned int idx = 0; -+ unsigned int wcid = GROUP_WCID(idx); -+ -+ /* Note: for AP do the AP-STA things mt76 does: -+ * - beacon offsets -+ * - do mac address tricks -+ * - shift vif idx -+ */ -+ mvif->idx = idx; -+ -+ if (dev->wcid_mask[wcid / BITS_PER_LONG] & BIT(wcid % BITS_PER_LONG)) -+ return -ENOSPC; -+ dev->wcid_mask[wcid / BITS_PER_LONG] |= BIT(wcid % BITS_PER_LONG); -+ mvif->group_wcid.idx = wcid; -+ mvif->group_wcid.hw_key_idx = -1; -+ -+ return 0; -+} -+ -+static void mt7601u_remove_interface(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; -+ unsigned int wcid = mvif->group_wcid.idx; -+ -+ dev->wcid_mask[wcid / BITS_PER_LONG] &= ~BIT(wcid % BITS_PER_LONG); -+} -+ -+static int mt7601u_config(struct ieee80211_hw *hw, u32 changed) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ int ret = 0; -+ -+ mutex_lock(&dev->mutex); -+ -+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { -+ ieee80211_stop_queues(hw); -+ ret = mt7601u_phy_set_channel(dev, &hw->conf.chandef); -+ ieee80211_wake_queues(hw); -+ } -+ -+ mutex_unlock(&dev->mutex); -+ -+ return ret; -+} -+ -+static void -+mt76_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, -+ unsigned int *total_flags, u64 multicast) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ u32 flags = 0; -+ -+#define MT76_FILTER(_flag, _hw) do { \ -+ flags |= *total_flags & FIF_##_flag; \ -+ dev->rxfilter &= ~(_hw); \ -+ dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \ -+ } while (0) -+ -+ mutex_lock(&dev->mutex); -+ -+ dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; -+ -+ MT76_FILTER(OTHER_BSS, MT_RX_FILTR_CFG_PROMISC); -+ MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); -+ MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); -+ MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | -+ MT_RX_FILTR_CFG_CTS | -+ MT_RX_FILTR_CFG_CFEND | -+ MT_RX_FILTR_CFG_CFACK | -+ MT_RX_FILTR_CFG_BA | -+ MT_RX_FILTR_CFG_CTRL_RSV); -+ MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); -+ -+ *total_flags = flags; -+ mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); -+ -+ mutex_unlock(&dev->mutex); -+} -+ -+static void -+mt7601u_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ struct ieee80211_bss_conf *info, u32 changed) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ -+ mutex_lock(&dev->mutex); -+ -+ if (changed & BSS_CHANGED_ASSOC) -+ mt7601u_phy_con_cal_onoff(dev, info); -+ -+ if (changed & BSS_CHANGED_BSSID) { -+ mt7601u_addr_wr(dev, MT_MAC_BSSID_DW0, info->bssid); -+ -+ /* Note: this is a hack because beacon_int is not changed -+ * on leave nor is any more appropriate event generated. -+ * rt2x00 doesn't seem to be bothered though. -+ */ -+ if (is_zero_ether_addr(info->bssid)) -+ mt7601u_mac_config_tsf(dev, false, 0); -+ } -+ -+ if (changed & BSS_CHANGED_BASIC_RATES) { -+ mt7601u_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates); -+ mt7601u_wr(dev, MT_HT_FBK_CFG0, 0x65432100); -+ mt7601u_wr(dev, MT_HT_FBK_CFG1, 0xedcba980); -+ mt7601u_wr(dev, MT_LG_FBK_CFG0, 0xedcba988); -+ mt7601u_wr(dev, MT_LG_FBK_CFG1, 0x00002100); -+ } -+ -+ if (changed & BSS_CHANGED_BEACON_INT) -+ mt7601u_mac_config_tsf(dev, true, info->beacon_int); -+ -+ if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT) -+ mt7601u_mac_set_protection(dev, info->use_cts_prot, -+ info->ht_operation_mode); -+ -+ if (changed & BSS_CHANGED_ERP_PREAMBLE) -+ mt7601u_mac_set_short_preamble(dev, info->use_short_preamble); -+ -+ if (changed & BSS_CHANGED_ERP_SLOT) { -+ int slottime = info->use_short_slot ? 9 : 20; -+ -+ mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG, -+ MT_BKOFF_SLOT_CFG_SLOTTIME, slottime); -+ } -+ -+ if (changed & BSS_CHANGED_ASSOC) -+ mt7601u_phy_recalibrate_after_assoc(dev); -+ -+ mutex_unlock(&dev->mutex); -+} -+ -+static int -+mt76_wcid_alloc(struct mt7601u_dev *dev) -+{ -+ int i, idx = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) { -+ idx = ffs(~dev->wcid_mask[i]); -+ if (!idx) -+ continue; -+ -+ idx--; -+ dev->wcid_mask[i] |= BIT(idx); -+ break; -+ } -+ -+ idx = i * BITS_PER_LONG + idx; -+ if (idx > 119) -+ return -1; -+ -+ return idx; -+} -+ -+static int -+mt7601u_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; -+ struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; -+ int ret = 0; -+ int idx = 0; -+ -+ mutex_lock(&dev->mutex); -+ -+ idx = mt76_wcid_alloc(dev); -+ if (idx < 0) { -+ ret = -ENOSPC; -+ goto out; -+ } -+ -+ msta->wcid.idx = idx; -+ msta->wcid.hw_key_idx = -1; -+ mt7601u_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); -+ mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); -+ rcu_assign_pointer(dev->wcid[idx], &msta->wcid); -+ mt7601u_mac_set_ampdu_factor(dev); -+ -+out: -+ mutex_unlock(&dev->mutex); -+ -+ return ret; -+} -+ -+static int -+mt7601u_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; -+ int idx = msta->wcid.idx; -+ -+ mutex_lock(&dev->mutex); -+ rcu_assign_pointer(dev->wcid[idx], NULL); -+ mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); -+ dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); -+ mt7601u_mac_wcid_setup(dev, idx, 0, NULL); -+ mt7601u_mac_set_ampdu_factor(dev); -+ mutex_unlock(&dev->mutex); -+ -+ return 0; -+} -+ -+static void -+mt7601u_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ enum sta_notify_cmd cmd, struct ieee80211_sta *sta) -+{ -+} -+ -+static void -+mt7601u_sw_scan(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ const u8 *mac_addr) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ -+ mt7601u_agc_save(dev); -+ set_bit(MT7601U_STATE_SCANNING, &dev->state); -+} -+ -+static void -+mt7601u_sw_scan_complete(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ -+ mt7601u_agc_restore(dev); -+ clear_bit(MT7601U_STATE_SCANNING, &dev->state); -+} -+ -+static int -+mt7601u_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, -+ struct ieee80211_vif *vif, struct ieee80211_sta *sta, -+ struct ieee80211_key_conf *key) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; -+ struct mt76_sta *msta = sta ? (struct mt76_sta *) sta->drv_priv : NULL; -+ struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->group_wcid; -+ int idx = key->keyidx; -+ int ret; -+ -+ if (cmd == SET_KEY) { -+ key->hw_key_idx = wcid->idx; -+ wcid->hw_key_idx = idx; -+ } else { -+ if (idx == wcid->hw_key_idx) -+ wcid->hw_key_idx = -1; -+ -+ key = NULL; -+ } -+ -+ if (!msta) { -+ if (key || wcid->hw_key_idx == idx) { -+ ret = mt76_mac_wcid_set_key(dev, wcid->idx, key); -+ if (ret) -+ return ret; -+ } -+ -+ return mt76_mac_shared_key_setup(dev, mvif->idx, idx, key); -+ } -+ -+ return mt76_mac_wcid_set_key(dev, msta->wcid.idx, key); -+} -+ -+static int mt7601u_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ -+ mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, value); -+ -+ return 0; -+} -+ -+static int -+mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ enum ieee80211_ampdu_mlme_action action, -+ struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; -+ -+ WARN_ON(msta->wcid.idx > GROUP_WCID(0)); -+ -+ switch (action) { -+ case IEEE80211_AMPDU_RX_START: -+ mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); -+ break; -+ case IEEE80211_AMPDU_RX_STOP: -+ mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, -+ BIT(16 + tid)); -+ break; -+ case IEEE80211_AMPDU_TX_OPERATIONAL: -+ ieee80211_send_bar(vif, sta->addr, tid, msta->agg_ssn[tid]); -+ break; -+ case IEEE80211_AMPDU_TX_STOP_FLUSH: -+ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: -+ break; -+ case IEEE80211_AMPDU_TX_START: -+ msta->agg_ssn[tid] = *ssn << 4; -+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); -+ break; -+ case IEEE80211_AMPDU_TX_STOP_CONT: -+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); -+ break; -+ } -+ -+ return 0; -+} -+ -+static void -+mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; -+ struct ieee80211_sta_rates *rates; -+ struct ieee80211_tx_rate rate = {}; -+ -+ rcu_read_lock(); -+ rates = rcu_dereference(sta->rates); -+ -+ if (!rates) -+ goto out; -+ -+ rate.idx = rates->rate[0].idx; -+ rate.flags = rates->rate[0].flags; -+ mt76_mac_wcid_set_rate(dev, &msta->wcid, &rate); -+ -+out: -+ rcu_read_unlock(); -+} -+ -+const struct ieee80211_ops mt7601u_ops = { -+ .tx = mt7601u_tx, -+ .start = mt7601u_start, -+ .stop = mt7601u_stop, -+ .add_interface = mt7601u_add_interface, -+ .remove_interface = mt7601u_remove_interface, -+ .config = mt7601u_config, -+ .configure_filter = mt76_configure_filter, -+ .bss_info_changed = mt7601u_bss_info_changed, -+ .sta_add = mt7601u_sta_add, -+ .sta_remove = mt7601u_sta_remove, -+ .sta_notify = mt7601u_sta_notify, -+ .set_key = mt7601u_set_key, -+ .conf_tx = mt7601u_conf_tx, -+ .sw_scan_start = mt7601u_sw_scan, -+ .sw_scan_complete = mt7601u_sw_scan_complete, -+ .ampdu_action = mt76_ampdu_action, -+ .sta_rate_tbl_update = mt76_sta_rate_tbl_update, -+ .set_rts_threshold = mt7601u_set_rts_threshold, -+}; -diff --git a/drivers/net/wireless/mediatek/mt7601u/mcu.c b/drivers/net/wireless/mediatek/mt7601u/mcu.c -new file mode 100644 -index 0000000..fbb1986 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/mcu.c -@@ -0,0 +1,534 @@ -+/* -+ * (c) Copyright 2002-2010, Ralink Technology, Inc. -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "mt7601u.h" -+#include "dma.h" -+#include "mcu.h" -+#include "usb.h" -+#include "trace.h" -+ -+#define MCU_FW_URB_MAX_PAYLOAD 0x3800 -+#define MCU_FW_URB_SIZE (MCU_FW_URB_MAX_PAYLOAD + 12) -+#define MCU_RESP_URB_SIZE 1024 -+ -+static inline int firmware_running(struct mt7601u_dev *dev) -+{ -+ return mt7601u_rr(dev, MT_MCU_COM_REG0) == 1; -+} -+ -+static inline void skb_put_le32(struct sk_buff *skb, u32 val) -+{ -+ put_unaligned_le32(val, skb_put(skb, 4)); -+} -+ -+static inline void mt7601u_dma_skb_wrap_cmd(struct sk_buff *skb, -+ u8 seq, enum mcu_cmd cmd) -+{ -+ WARN_ON(mt7601u_dma_skb_wrap(skb, CPU_TX_PORT, DMA_COMMAND, -+ MT76_SET(MT_TXD_CMD_INFO_SEQ, seq) | -+ MT76_SET(MT_TXD_CMD_INFO_TYPE, cmd))); -+} -+ -+static inline void trace_mt_mcu_msg_send_cs(struct mt7601u_dev *dev, -+ struct sk_buff *skb, bool need_resp) -+{ -+ u32 i, csum = 0; -+ -+ for (i = 0; i < skb->len / 4; i++) -+ csum ^= get_unaligned_le32(skb->data + i * 4); -+ -+ trace_mt_mcu_msg_send(dev, skb, csum, need_resp); -+} -+ -+static struct sk_buff * -+mt7601u_mcu_msg_alloc(struct mt7601u_dev *dev, const void *data, int len) -+{ -+ struct sk_buff *skb; -+ -+ WARN_ON(len % 4); /* if length is not divisible by 4 we need to pad */ -+ -+ skb = alloc_skb(len + MT_DMA_HDR_LEN + 4, GFP_KERNEL); -+ skb_reserve(skb, MT_DMA_HDR_LEN); -+ memcpy(skb_put(skb, len), data, len); -+ -+ return skb; -+} -+ -+static int mt7601u_mcu_wait_resp(struct mt7601u_dev *dev, u8 seq) -+{ -+ struct urb *urb = dev->mcu.resp.urb; -+ u32 rxfce; -+ int urb_status, ret, i = 5; -+ -+ while (i--) { -+ if (!wait_for_completion_timeout(&dev->mcu.resp_cmpl, -+ msecs_to_jiffies(300))) { -+ dev_warn(dev->dev, "Warning: %s retrying\n", __func__); -+ continue; -+ } -+ -+ /* Make copies of important data before reusing the urb */ -+ rxfce = get_unaligned_le32(dev->mcu.resp.buf); -+ urb_status = urb->status * mt7601u_urb_has_error(urb); -+ -+ ret = mt7601u_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, -+ &dev->mcu.resp, GFP_KERNEL, -+ mt7601u_complete_urb, -+ &dev->mcu.resp_cmpl); -+ if (ret) -+ return ret; -+ -+ if (urb_status) -+ dev_err(dev->dev, "Error: MCU resp urb failed:%d\n", -+ urb_status); -+ -+ if (MT76_GET(MT_RXD_CMD_INFO_CMD_SEQ, rxfce) == seq && -+ MT76_GET(MT_RXD_CMD_INFO_EVT_TYPE, rxfce) == CMD_DONE) -+ return 0; -+ -+ dev_err(dev->dev, "Error: MCU resp evt:%hhx seq:%hhx-%hhx!\n", -+ MT76_GET(MT_RXD_CMD_INFO_EVT_TYPE, rxfce), -+ seq, MT76_GET(MT_RXD_CMD_INFO_CMD_SEQ, rxfce)); -+ } -+ -+ dev_err(dev->dev, "Error: %s timed out\n", __func__); -+ return -ETIMEDOUT; -+} -+ -+static int -+mt7601u_mcu_msg_send(struct mt7601u_dev *dev, struct sk_buff *skb, -+ enum mcu_cmd cmd, bool wait_resp) -+{ -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ unsigned cmd_pipe = usb_sndbulkpipe(usb_dev, -+ dev->out_eps[MT_EP_OUT_INBAND_CMD]); -+ int sent, ret; -+ u8 seq = 0; -+ -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return 0; -+ -+ mutex_lock(&dev->mcu.mutex); -+ -+ if (wait_resp) -+ while (!seq) -+ seq = ++dev->mcu.msg_seq & 0xf; -+ -+ mt7601u_dma_skb_wrap_cmd(skb, seq, cmd); -+ -+ if (dev->mcu.resp_cmpl.done) -+ dev_err(dev->dev, "Error: MCU response pre-completed!\n"); -+ -+ trace_mt_mcu_msg_send_cs(dev, skb, wait_resp); -+ trace_mt_submit_urb_sync(dev, cmd_pipe, skb->len); -+ ret = usb_bulk_msg(usb_dev, cmd_pipe, skb->data, skb->len, &sent, 500); -+ if (ret) { -+ dev_err(dev->dev, "Error: send MCU cmd failed:%d\n", ret); -+ goto out; -+ } -+ if (sent != skb->len) -+ dev_err(dev->dev, "Error: %s sent != skb->len\n", __func__); -+ -+ if (wait_resp) -+ ret = mt7601u_mcu_wait_resp(dev, seq); -+out: -+ mutex_unlock(&dev->mcu.mutex); -+ -+ consume_skb(skb); -+ -+ return ret; -+} -+ -+static int mt7601u_mcu_function_select(struct mt7601u_dev *dev, -+ enum mcu_function func, u32 val) -+{ -+ struct sk_buff *skb; -+ struct { -+ __le32 id; -+ __le32 value; -+ } __packed __aligned(4) msg = { -+ .id = cpu_to_le32(func), -+ .value = cpu_to_le32(val), -+ }; -+ -+ skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg)); -+ return mt7601u_mcu_msg_send(dev, skb, CMD_FUN_SET_OP, func == 5); -+} -+ -+int mt7601u_mcu_tssi_read_kick(struct mt7601u_dev *dev, int use_hvga) -+{ -+ int ret; -+ -+ if (!test_bit(MT7601U_STATE_MCU_RUNNING, &dev->state)) -+ return 0; -+ -+ ret = mt7601u_mcu_function_select(dev, ATOMIC_TSSI_SETTING, -+ use_hvga); -+ if (ret) { -+ dev_warn(dev->dev, "Warning: MCU TSSI read kick failed\n"); -+ return ret; -+ } -+ -+ dev->tssi_read_trig = true; -+ -+ return 0; -+} -+ -+int -+mt7601u_mcu_calibrate(struct mt7601u_dev *dev, enum mcu_calibrate cal, u32 val) -+{ -+ struct sk_buff *skb; -+ struct { -+ __le32 id; -+ __le32 value; -+ } __packed __aligned(4) msg = { -+ .id = cpu_to_le32(cal), -+ .value = cpu_to_le32(val), -+ }; -+ -+ skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg)); -+ return mt7601u_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP, true); -+} -+ -+int mt7601u_write_reg_pairs(struct mt7601u_dev *dev, u32 base, -+ const struct mt76_reg_pair *data, int n) -+{ -+ const int max_vals_per_cmd = INBAND_PACKET_MAX_LEN / 8; -+ struct sk_buff *skb; -+ int cnt, i, ret; -+ -+ if (!n) -+ return 0; -+ -+ cnt = min(max_vals_per_cmd, n); -+ -+ skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ skb_reserve(skb, MT_DMA_HDR_LEN); -+ -+ for (i = 0; i < cnt; i++) { -+ skb_put_le32(skb, base + data[i].reg); -+ skb_put_le32(skb, data[i].value); -+ } -+ -+ ret = mt7601u_mcu_msg_send(dev, skb, CMD_RANDOM_WRITE, cnt == n); -+ if (ret) -+ return ret; -+ -+ return mt7601u_write_reg_pairs(dev, base, data + cnt, n - cnt); -+} -+ -+int mt7601u_burst_write_regs(struct mt7601u_dev *dev, u32 offset, -+ const u32 *data, int n) -+{ -+ const int max_regs_per_cmd = INBAND_PACKET_MAX_LEN / 4 - 1; -+ struct sk_buff *skb; -+ int cnt, i, ret; -+ -+ if (!n) -+ return 0; -+ -+ cnt = min(max_regs_per_cmd, n); -+ -+ skb = alloc_skb(cnt * 4 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ skb_reserve(skb, MT_DMA_HDR_LEN); -+ -+ skb_put_le32(skb, MT_MCU_MEMMAP_WLAN + offset); -+ for (i = 0; i < cnt; i++) -+ skb_put_le32(skb, data[i]); -+ -+ ret = mt7601u_mcu_msg_send(dev, skb, CMD_BURST_WRITE, cnt == n); -+ if (ret) -+ return ret; -+ -+ return mt7601u_burst_write_regs(dev, offset + cnt * 4, -+ data + cnt, n - cnt); -+} -+ -+struct mt76_fw_header { -+ __le32 ilm_len; -+ __le32 dlm_len; -+ __le16 build_ver; -+ __le16 fw_ver; -+ u8 pad[4]; -+ char build_time[16]; -+}; -+ -+struct mt76_fw { -+ struct mt76_fw_header hdr; -+ u8 ivb[MT_MCU_IVB_SIZE]; -+ u8 ilm[]; -+}; -+ -+static int __mt7601u_dma_fw(struct mt7601u_dev *dev, -+ const struct mt7601u_dma_buf *dma_buf, -+ const void *data, u32 len, u32 dst_addr) -+{ -+ DECLARE_COMPLETION_ONSTACK(cmpl); -+ struct mt7601u_dma_buf buf = *dma_buf; /* we need to fake length */ -+ __le32 reg; -+ u32 val; -+ int ret; -+ -+ reg = cpu_to_le32(MT76_SET(MT_TXD_INFO_TYPE, DMA_PACKET) | -+ MT76_SET(MT_TXD_INFO_D_PORT, CPU_TX_PORT) | -+ MT76_SET(MT_TXD_INFO_LEN, len)); -+ memcpy(buf.buf, ®, sizeof(reg)); -+ memcpy(buf.buf + sizeof(reg), data, len); -+ memset(buf.buf + sizeof(reg) + len, 0, 8); -+ -+ ret = mt7601u_vendor_single_wr(dev, MT_VEND_WRITE_FCE, -+ MT_FCE_DMA_ADDR, dst_addr); -+ if (ret) -+ return ret; -+ len = roundup(len, 4); -+ ret = mt7601u_vendor_single_wr(dev, MT_VEND_WRITE_FCE, -+ MT_FCE_DMA_LEN, len << 16); -+ if (ret) -+ return ret; -+ -+ buf.len = MT_DMA_HDR_LEN + len + 4; -+ ret = mt7601u_usb_submit_buf(dev, USB_DIR_OUT, MT_EP_OUT_INBAND_CMD, -+ &buf, GFP_KERNEL, -+ mt7601u_complete_urb, &cmpl); -+ if (ret) -+ return ret; -+ -+ if (!wait_for_completion_timeout(&cmpl, msecs_to_jiffies(1000))) { -+ dev_err(dev->dev, "Error: firmware upload timed out\n"); -+ usb_kill_urb(buf.urb); -+ return -ETIMEDOUT; -+ } -+ if (mt7601u_urb_has_error(buf.urb)) { -+ dev_err(dev->dev, "Error: firmware upload urb failed:%d\n", -+ buf.urb->status); -+ return buf.urb->status; -+ } -+ -+ val = mt7601u_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); -+ val++; -+ mt7601u_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); -+ -+ return 0; -+} -+ -+static int -+mt7601u_dma_fw(struct mt7601u_dev *dev, struct mt7601u_dma_buf *dma_buf, -+ const void *data, int len, u32 dst_addr) -+{ -+ int n, ret; -+ -+ if (len == 0) -+ return 0; -+ -+ n = min(MCU_FW_URB_MAX_PAYLOAD, len); -+ ret = __mt7601u_dma_fw(dev, dma_buf, data, n, dst_addr); -+ if (ret) -+ return ret; -+ -+ if (!mt76_poll_msec(dev, MT_MCU_COM_REG1, BIT(31), BIT(31), 500)) -+ return -ETIMEDOUT; -+ -+ return mt7601u_dma_fw(dev, dma_buf, data + n, len - n, dst_addr + n); -+} -+ -+static int -+mt7601u_upload_firmware(struct mt7601u_dev *dev, const struct mt76_fw *fw) -+{ -+ struct mt7601u_dma_buf dma_buf; -+ void *ivb; -+ u32 ilm_len, dlm_len; -+ int i, ret; -+ -+ ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL); -+ if (!ivb || mt7601u_usb_alloc_buf(dev, MCU_FW_URB_SIZE, &dma_buf)) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ ilm_len = le32_to_cpu(fw->hdr.ilm_len) - sizeof(fw->ivb); -+ dev_dbg(dev->dev, "loading FW - ILM %u + IVB %zu\n", -+ ilm_len, sizeof(fw->ivb)); -+ ret = mt7601u_dma_fw(dev, &dma_buf, fw->ilm, ilm_len, sizeof(fw->ivb)); -+ if (ret) -+ goto error; -+ -+ dlm_len = le32_to_cpu(fw->hdr.dlm_len); -+ dev_dbg(dev->dev, "loading FW - DLM %u\n", dlm_len); -+ ret = mt7601u_dma_fw(dev, &dma_buf, fw->ilm + ilm_len, -+ dlm_len, MT_MCU_DLM_OFFSET); -+ if (ret) -+ goto error; -+ -+ ret = mt7601u_vendor_request(dev, MT_VEND_DEV_MODE, USB_DIR_OUT, -+ 0x12, 0, ivb, sizeof(fw->ivb)); -+ if (ret < 0) -+ goto error; -+ ret = 0; -+ -+ for (i = 100; i && !firmware_running(dev); i--) -+ msleep(10); -+ if (!i) { -+ ret = -ETIMEDOUT; -+ goto error; -+ } -+ -+ dev_dbg(dev->dev, "Firmware running!\n"); -+error: -+ kfree(ivb); -+ mt7601u_usb_free_buf(dev, &dma_buf); -+ -+ return ret; -+} -+ -+static int mt7601u_load_firmware(struct mt7601u_dev *dev) -+{ -+ const struct firmware *fw; -+ const struct mt76_fw_header *hdr; -+ int len, ret; -+ u32 val; -+ -+ mt7601u_wr(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | -+ MT_USB_DMA_CFG_TX_BULK_EN)); -+ -+ if (firmware_running(dev)) -+ return 0; -+ -+ ret = request_firmware(&fw, MT7601U_FIRMWARE, dev->dev); -+ if (ret) -+ return ret; -+ -+ if (!fw || !fw->data || fw->size < sizeof(*hdr)) -+ goto err_inv_fw; -+ -+ hdr = (const struct mt76_fw_header *) fw->data; -+ -+ if (le32_to_cpu(hdr->ilm_len) <= MT_MCU_IVB_SIZE) -+ goto err_inv_fw; -+ -+ len = sizeof(*hdr); -+ len += le32_to_cpu(hdr->ilm_len); -+ len += le32_to_cpu(hdr->dlm_len); -+ -+ if (fw->size != len) -+ goto err_inv_fw; -+ -+ val = le16_to_cpu(hdr->fw_ver); -+ dev_info(dev->dev, -+ "Firmware Version: %d.%d.%02d Build: %x Build time: %.16s\n", -+ (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf, -+ le16_to_cpu(hdr->build_ver), hdr->build_time); -+ -+ len = le32_to_cpu(hdr->ilm_len); -+ -+ mt7601u_wr(dev, 0x94c, 0); -+ mt7601u_wr(dev, MT_FCE_PSE_CTRL, 0); -+ -+ mt7601u_vendor_reset(dev); -+ msleep(5); -+ -+ mt7601u_wr(dev, 0xa44, 0); -+ mt7601u_wr(dev, 0x230, 0x84210); -+ mt7601u_wr(dev, 0x400, 0x80c00); -+ mt7601u_wr(dev, 0x800, 1); -+ -+ mt7601u_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | -+ MT_PBF_CFG_TX1Q_EN | -+ MT_PBF_CFG_TX2Q_EN | -+ MT_PBF_CFG_TX3Q_EN)); -+ -+ mt7601u_wr(dev, MT_FCE_PSE_CTRL, 1); -+ -+ mt7601u_wr(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | -+ MT_USB_DMA_CFG_TX_BULK_EN)); -+ val = mt76_set(dev, MT_USB_DMA_CFG, MT_USB_DMA_CFG_TX_CLR); -+ val &= ~MT_USB_DMA_CFG_TX_CLR; -+ mt7601u_wr(dev, MT_USB_DMA_CFG, val); -+ -+ /* FCE tx_fs_base_ptr */ -+ mt7601u_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230); -+ /* FCE tx_fs_max_cnt */ -+ mt7601u_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 1); -+ /* FCE pdma enable */ -+ mt7601u_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44); -+ /* FCE skip_fs_en */ -+ mt7601u_wr(dev, MT_FCE_SKIP_FS, 3); -+ -+ ret = mt7601u_upload_firmware(dev, (const struct mt76_fw *)fw->data); -+ -+ release_firmware(fw); -+ -+ return ret; -+ -+err_inv_fw: -+ dev_err(dev->dev, "Invalid firmware image\n"); -+ release_firmware(fw); -+ return -ENOENT; -+} -+ -+int mt7601u_mcu_init(struct mt7601u_dev *dev) -+{ -+ int ret; -+ -+ mutex_init(&dev->mcu.mutex); -+ -+ ret = mt7601u_load_firmware(dev); -+ if (ret) -+ return ret; -+ -+ set_bit(MT7601U_STATE_MCU_RUNNING, &dev->state); -+ -+ return 0; -+} -+ -+int mt7601u_mcu_cmd_init(struct mt7601u_dev *dev) -+{ -+ int ret; -+ -+ ret = mt7601u_mcu_function_select(dev, Q_SELECT, 1); -+ if (ret) -+ return ret; -+ -+ init_completion(&dev->mcu.resp_cmpl); -+ if (mt7601u_usb_alloc_buf(dev, MCU_RESP_URB_SIZE, &dev->mcu.resp)) { -+ mt7601u_usb_free_buf(dev, &dev->mcu.resp); -+ return -ENOMEM; -+ } -+ -+ ret = mt7601u_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, -+ &dev->mcu.resp, GFP_KERNEL, -+ mt7601u_complete_urb, &dev->mcu.resp_cmpl); -+ if (ret) { -+ mt7601u_usb_free_buf(dev, &dev->mcu.resp); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+void mt7601u_mcu_cmd_deinit(struct mt7601u_dev *dev) -+{ -+ usb_kill_urb(dev->mcu.resp.urb); -+ mt7601u_usb_free_buf(dev, &dev->mcu.resp); -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/mcu.h b/drivers/net/wireless/mediatek/mt7601u/mcu.h -new file mode 100644 -index 0000000..4a66d10 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/mcu.h -@@ -0,0 +1,94 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT7601U_MCU_H -+#define __MT7601U_MCU_H -+ -+struct mt7601u_dev; -+ -+/* Register definitions */ -+#define MT_MCU_RESET_CTL 0x070C -+#define MT_MCU_INT_LEVEL 0x0718 -+#define MT_MCU_COM_REG0 0x0730 -+#define MT_MCU_COM_REG1 0x0734 -+#define MT_MCU_COM_REG2 0x0738 -+#define MT_MCU_COM_REG3 0x073C -+ -+#define MT_MCU_IVB_SIZE 0x40 -+#define MT_MCU_DLM_OFFSET 0x80000 -+ -+#define MT_MCU_MEMMAP_WLAN 0x00410000 -+#define MT_MCU_MEMMAP_BBP 0x40000000 -+#define MT_MCU_MEMMAP_RF 0x80000000 -+ -+#define INBAND_PACKET_MAX_LEN 192 -+ -+enum mcu_cmd { -+ CMD_FUN_SET_OP = 1, -+ CMD_LOAD_CR = 2, -+ CMD_INIT_GAIN_OP = 3, -+ CMD_DYNC_VGA_OP = 6, -+ CMD_TDLS_CH_SW = 7, -+ CMD_BURST_WRITE = 8, -+ CMD_READ_MODIFY_WRITE = 9, -+ CMD_RANDOM_READ = 10, -+ CMD_BURST_READ = 11, -+ CMD_RANDOM_WRITE = 12, -+ CMD_LED_MODE_OP = 16, -+ CMD_POWER_SAVING_OP = 20, -+ CMD_WOW_CONFIG = 21, -+ CMD_WOW_QUERY = 22, -+ CMD_WOW_FEATURE = 24, -+ CMD_CARRIER_DETECT_OP = 28, -+ CMD_RADOR_DETECT_OP = 29, -+ CMD_SWITCH_CHANNEL_OP = 30, -+ CMD_CALIBRATION_OP = 31, -+ CMD_BEACON_OP = 32, -+ CMD_ANTENNA_OP = 33, -+}; -+ -+enum mcu_function { -+ Q_SELECT = 1, -+ ATOMIC_TSSI_SETTING = 5, -+}; -+ -+enum mcu_power_mode { -+ RADIO_OFF = 0x30, -+ RADIO_ON = 0x31, -+ RADIO_OFF_AUTO_WAKEUP = 0x32, -+ RADIO_OFF_ADVANCE = 0x33, -+ RADIO_ON_ADVANCE = 0x34, -+}; -+ -+enum mcu_calibrate { -+ MCU_CAL_R = 1, -+ MCU_CAL_DCOC, -+ MCU_CAL_LC, -+ MCU_CAL_LOFT, -+ MCU_CAL_TXIQ, -+ MCU_CAL_BW, -+ MCU_CAL_DPD, -+ MCU_CAL_RXIQ, -+ MCU_CAL_TXDCOC, -+}; -+ -+int mt7601u_mcu_init(struct mt7601u_dev *dev); -+int mt7601u_mcu_cmd_init(struct mt7601u_dev *dev); -+void mt7601u_mcu_cmd_deinit(struct mt7601u_dev *dev); -+ -+int -+mt7601u_mcu_calibrate(struct mt7601u_dev *dev, enum mcu_calibrate cal, u32 val); -+int mt7601u_mcu_tssi_read_kick(struct mt7601u_dev *dev, int use_hvga); -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/mt7601u.h b/drivers/net/wireless/mediatek/mt7601u/mt7601u.h -new file mode 100644 -index 0000000..9102be6b ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/mt7601u.h -@@ -0,0 +1,390 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef MT7601U_H -+#define MT7601U_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "regs.h" -+#include "util.h" -+ -+#define MT_CALIBRATE_INTERVAL (4 * HZ) -+ -+#define MT_FREQ_CAL_INIT_DELAY (30 * HZ) -+#define MT_FREQ_CAL_CHECK_INTERVAL (10 * HZ) -+#define MT_FREQ_CAL_ADJ_INTERVAL (HZ / 2) -+ -+#define MT_BBP_REG_VERSION 0x00 -+ -+#define MT_USB_AGGR_SIZE_LIMIT 28 /* * 1024B */ -+#define MT_USB_AGGR_TIMEOUT 0x80 /* * 33ns */ -+#define MT_RX_ORDER 3 -+#define MT_RX_URB_SIZE (PAGE_SIZE << MT_RX_ORDER) -+ -+struct mt7601u_dma_buf { -+ struct urb *urb; -+ void *buf; -+ dma_addr_t dma; -+ size_t len; -+}; -+ -+struct mt7601u_mcu { -+ struct mutex mutex; -+ -+ u8 msg_seq; -+ -+ struct mt7601u_dma_buf resp; -+ struct completion resp_cmpl; -+}; -+ -+struct mt7601u_freq_cal { -+ struct delayed_work work; -+ u8 freq; -+ bool enabled; -+ bool adjusting; -+}; -+ -+struct mac_stats { -+ u64 rx_stat[6]; -+ u64 tx_stat[6]; -+ u64 aggr_stat[2]; -+ u64 aggr_n[32]; -+ u64 zero_len_del[2]; -+}; -+ -+#define N_RX_ENTRIES 16 -+struct mt7601u_rx_queue { -+ struct mt7601u_dev *dev; -+ -+ struct mt7601u_dma_buf_rx { -+ struct urb *urb; -+ struct page *p; -+ } e[N_RX_ENTRIES]; -+ -+ unsigned int start; -+ unsigned int end; -+ unsigned int entries; -+ unsigned int pending; -+}; -+ -+#define N_TX_ENTRIES 64 -+ -+struct mt7601u_tx_queue { -+ struct mt7601u_dev *dev; -+ -+ struct mt7601u_dma_buf_tx { -+ struct urb *urb; -+ struct sk_buff *skb; -+ } e[N_TX_ENTRIES]; -+ -+ unsigned int start; -+ unsigned int end; -+ unsigned int entries; -+ unsigned int used; -+ unsigned int fifo_seq; -+}; -+ -+/* WCID allocation: -+ * 0: mcast wcid -+ * 1: bssid wcid -+ * 1...: STAs -+ * ...7e: group wcids -+ * 7f: reserved -+ */ -+#define N_WCIDS 128 -+#define GROUP_WCID(idx) (N_WCIDS - 2 - idx) -+ -+struct mt7601u_eeprom_params; -+ -+#define MT_EE_TEMPERATURE_SLOPE 39 -+#define MT_FREQ_OFFSET_INVALID -128 -+ -+enum mt_temp_mode { -+ MT_TEMP_MODE_NORMAL, -+ MT_TEMP_MODE_HIGH, -+ MT_TEMP_MODE_LOW, -+}; -+ -+enum mt_bw { -+ MT_BW_20, -+ MT_BW_40, -+}; -+ -+enum { -+ MT7601U_STATE_INITIALIZED, -+ MT7601U_STATE_REMOVED, -+ MT7601U_STATE_WLAN_RUNNING, -+ MT7601U_STATE_MCU_RUNNING, -+ MT7601U_STATE_SCANNING, -+ MT7601U_STATE_READING_STATS, -+ MT7601U_STATE_MORE_STATS, -+}; -+ -+/** -+ * struct mt7601u_dev - adapter structure -+ * @lock: protects @wcid->tx_rate. -+ * @tx_lock: protects @tx_q and changes of MT7601U_STATE_*_STATS -+ flags in @state. -+ * @rx_lock: protects @rx_q. -+ * @con_mon_lock: protects @ap_bssid, @bcn_*, @avg_rssi. -+ * @mutex: ensures exclusive access from mac80211 callbacks. -+ * @vendor_req_mutex: ensures atomicity of vendor requests. -+ * @reg_atomic_mutex: ensures atomicity of indirect register accesses -+ * (accesses to RF and BBP). -+ * @hw_atomic_mutex: ensures exclusive access to HW during critical -+ * operations (power management, channel switch). -+ */ -+struct mt7601u_dev { -+ struct ieee80211_hw *hw; -+ struct device *dev; -+ -+ unsigned long state; -+ -+ struct mutex mutex; -+ -+ unsigned long wcid_mask[N_WCIDS / BITS_PER_LONG]; -+ -+ struct cfg80211_chan_def chandef; -+ struct ieee80211_supported_band *sband_2g; -+ -+ struct mt7601u_mcu mcu; -+ -+ struct delayed_work cal_work; -+ struct delayed_work mac_work; -+ -+ struct workqueue_struct *stat_wq; -+ struct delayed_work stat_work; -+ -+ struct mt76_wcid *mon_wcid; -+ struct mt76_wcid __rcu *wcid[N_WCIDS]; -+ -+ spinlock_t lock; -+ -+ const u16 *beacon_offsets; -+ -+ u8 macaddr[ETH_ALEN]; -+ struct mt7601u_eeprom_params *ee; -+ -+ struct mutex vendor_req_mutex; -+ struct mutex reg_atomic_mutex; -+ struct mutex hw_atomic_mutex; -+ -+ u32 rxfilter; -+ u32 debugfs_reg; -+ -+ u8 out_eps[8]; -+ u8 in_eps[8]; -+ u16 out_max_packet; -+ u16 in_max_packet; -+ -+ /* TX */ -+ spinlock_t tx_lock; -+ struct mt7601u_tx_queue *tx_q; -+ -+ atomic_t avg_ampdu_len; -+ -+ /* RX */ -+ spinlock_t rx_lock; -+ struct tasklet_struct rx_tasklet; -+ struct mt7601u_rx_queue rx_q; -+ -+ /* Connection monitoring things */ -+ spinlock_t con_mon_lock; -+ u8 ap_bssid[ETH_ALEN]; -+ -+ s8 bcn_freq_off; -+ u8 bcn_phy_mode; -+ -+ int avg_rssi; /* starts at 0 and converges */ -+ -+ u8 agc_save; -+ -+ struct mt7601u_freq_cal freq_cal; -+ -+ bool tssi_read_trig; -+ -+ s8 tssi_init; -+ s8 tssi_init_hvga; -+ s16 tssi_init_hvga_offset_db; -+ -+ int prev_pwr_diff; -+ -+ enum mt_temp_mode temp_mode; -+ int curr_temp; -+ int dpd_temp; -+ s8 raw_temp; -+ bool pll_lock_protect; -+ -+ u8 bw; -+ bool chan_ext_below; -+ -+ /* PA mode */ -+ u32 rf_pa_mode[2]; -+ -+ struct mac_stats stats; -+}; -+ -+struct mt7601u_tssi_params { -+ char tssi0; -+ int trgt_power; -+}; -+ -+struct mt76_wcid { -+ u8 idx; -+ u8 hw_key_idx; -+ -+ u16 tx_rate; -+ bool tx_rate_set; -+ u8 tx_rate_nss; -+}; -+ -+struct mt76_vif { -+ u8 idx; -+ -+ struct mt76_wcid group_wcid; -+}; -+ -+struct mt76_sta { -+ struct mt76_wcid wcid; -+ u16 agg_ssn[IEEE80211_NUM_TIDS]; -+}; -+ -+struct mt76_reg_pair { -+ u32 reg; -+ u32 value; -+}; -+ -+struct mt7601u_rxwi; -+ -+extern const struct ieee80211_ops mt7601u_ops; -+ -+void mt7601u_init_debugfs(struct mt7601u_dev *dev); -+ -+u32 mt7601u_rr(struct mt7601u_dev *dev, u32 offset); -+void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val); -+u32 mt7601u_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val); -+u32 mt7601u_rmc(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val); -+void mt7601u_wr_copy(struct mt7601u_dev *dev, u32 offset, -+ const void *data, int len); -+ -+int mt7601u_wait_asic_ready(struct mt7601u_dev *dev); -+bool mt76_poll(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, -+ int timeout); -+bool mt76_poll_msec(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, -+ int timeout); -+ -+/* Compatibility with mt76 */ -+#define mt76_rmw_field(_dev, _reg, _field, _val) \ -+ mt76_rmw(_dev, _reg, _field, MT76_SET(_field, _val)) -+ -+static inline u32 mt76_rr(struct mt7601u_dev *dev, u32 offset) -+{ -+ return mt7601u_rr(dev, offset); -+} -+ -+static inline void mt76_wr(struct mt7601u_dev *dev, u32 offset, u32 val) -+{ -+ return mt7601u_wr(dev, offset, val); -+} -+ -+static inline u32 -+mt76_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val) -+{ -+ return mt7601u_rmw(dev, offset, mask, val); -+} -+ -+static inline u32 mt76_set(struct mt7601u_dev *dev, u32 offset, u32 val) -+{ -+ return mt76_rmw(dev, offset, 0, val); -+} -+ -+static inline u32 mt76_clear(struct mt7601u_dev *dev, u32 offset, u32 val) -+{ -+ return mt76_rmw(dev, offset, val, 0); -+} -+ -+int mt7601u_write_reg_pairs(struct mt7601u_dev *dev, u32 base, -+ const struct mt76_reg_pair *data, int len); -+int mt7601u_burst_write_regs(struct mt7601u_dev *dev, u32 offset, -+ const u32 *data, int n); -+void mt7601u_addr_wr(struct mt7601u_dev *dev, const u32 offset, const u8 *addr); -+ -+/* Init */ -+struct mt7601u_dev *mt7601u_alloc_device(struct device *dev); -+int mt7601u_init_hardware(struct mt7601u_dev *dev); -+int mt7601u_register_device(struct mt7601u_dev *dev); -+void mt7601u_cleanup(struct mt7601u_dev *dev); -+ -+int mt7601u_mac_start(struct mt7601u_dev *dev); -+void mt7601u_mac_stop(struct mt7601u_dev *dev); -+ -+/* PHY */ -+int mt7601u_phy_init(struct mt7601u_dev *dev); -+int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev); -+void mt7601u_set_rx_path(struct mt7601u_dev *dev, u8 path); -+void mt7601u_set_tx_dac(struct mt7601u_dev *dev, u8 path); -+int mt7601u_bbp_set_bw(struct mt7601u_dev *dev, int bw); -+void mt7601u_agc_save(struct mt7601u_dev *dev); -+void mt7601u_agc_restore(struct mt7601u_dev *dev); -+int mt7601u_phy_set_channel(struct mt7601u_dev *dev, -+ struct cfg80211_chan_def *chandef); -+void mt7601u_phy_recalibrate_after_assoc(struct mt7601u_dev *dev); -+int mt7601u_phy_get_rssi(struct mt7601u_dev *dev, -+ struct mt7601u_rxwi *rxwi, u16 rate); -+void mt7601u_phy_con_cal_onoff(struct mt7601u_dev *dev, -+ struct ieee80211_bss_conf *info); -+ -+/* MAC */ -+void mt7601u_mac_work(struct work_struct *work); -+void mt7601u_mac_set_protection(struct mt7601u_dev *dev, bool legacy_prot, -+ int ht_mode); -+void mt7601u_mac_set_short_preamble(struct mt7601u_dev *dev, bool short_preamb); -+void mt7601u_mac_config_tsf(struct mt7601u_dev *dev, bool enable, int interval); -+void -+mt7601u_mac_wcid_setup(struct mt7601u_dev *dev, u8 idx, u8 vif_idx, u8 *mac); -+void mt7601u_mac_set_ampdu_factor(struct mt7601u_dev *dev); -+ -+/* TX */ -+void mt7601u_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, -+ struct sk_buff *skb); -+int mt7601u_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ u16 queue, const struct ieee80211_tx_queue_params *params); -+void mt7601u_tx_status(struct mt7601u_dev *dev, struct sk_buff *skb); -+void mt7601u_tx_stat(struct work_struct *work); -+ -+/* util */ -+void mt76_remove_hdr_pad(struct sk_buff *skb); -+int mt76_insert_hdr_pad(struct sk_buff *skb); -+ -+u32 mt7601u_bbp_set_ctrlch(struct mt7601u_dev *dev, bool below); -+ -+static inline u32 mt7601u_mac_set_ctrlch(struct mt7601u_dev *dev, bool below) -+{ -+ return mt7601u_rmc(dev, MT_TX_BAND_CFG, 1, below); -+} -+ -+int mt7601u_dma_init(struct mt7601u_dev *dev); -+void mt7601u_dma_cleanup(struct mt7601u_dev *dev); -+ -+int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb, -+ struct mt76_wcid *wcid, int hw_q); -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/phy.c b/drivers/net/wireless/mediatek/mt7601u/phy.c -new file mode 100644 -index 0000000..1908af6 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/phy.c -@@ -0,0 +1,1251 @@ -+/* -+ * (c) Copyright 2002-2010, Ralink Technology, Inc. -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+#include "mcu.h" -+#include "eeprom.h" -+#include "trace.h" -+#include "initvals_phy.h" -+ -+#include -+ -+static void mt7601u_agc_reset(struct mt7601u_dev *dev); -+ -+static int -+mt7601u_rf_wr(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 value) -+{ -+ int ret = 0; -+ -+ if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)) || -+ WARN_ON(offset > 63)) -+ return -EINVAL; -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return 0; -+ -+ mutex_lock(&dev->reg_atomic_mutex); -+ -+ if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100)) { -+ ret = -ETIMEDOUT; -+ goto out; -+ } -+ -+ mt7601u_wr(dev, MT_RF_CSR_CFG, MT76_SET(MT_RF_CSR_CFG_DATA, value) | -+ MT76_SET(MT_RF_CSR_CFG_REG_BANK, bank) | -+ MT76_SET(MT_RF_CSR_CFG_REG_ID, offset) | -+ MT_RF_CSR_CFG_WR | -+ MT_RF_CSR_CFG_KICK); -+ trace_rf_write(dev, bank, offset, value); -+out: -+ mutex_unlock(&dev->reg_atomic_mutex); -+ -+ if (ret < 0) -+ dev_err(dev->dev, "Error: RF write %02hhx:%02hhx failed:%d!!\n", -+ bank, offset, ret); -+ -+ return ret; -+} -+ -+static int -+mt7601u_rf_rr(struct mt7601u_dev *dev, u8 bank, u8 offset) -+{ -+ int ret = -ETIMEDOUT; -+ u32 val; -+ -+ if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)) || -+ WARN_ON(offset > 63)) -+ return -EINVAL; -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return 0xff; -+ -+ mutex_lock(&dev->reg_atomic_mutex); -+ -+ if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100)) -+ goto out; -+ -+ mt7601u_wr(dev, MT_RF_CSR_CFG, MT76_SET(MT_RF_CSR_CFG_REG_BANK, bank) | -+ MT76_SET(MT_RF_CSR_CFG_REG_ID, offset) | -+ MT_RF_CSR_CFG_KICK); -+ -+ if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100)) -+ goto out; -+ -+ val = mt7601u_rr(dev, MT_RF_CSR_CFG); -+ if (MT76_GET(MT_RF_CSR_CFG_REG_ID, val) == offset && -+ MT76_GET(MT_RF_CSR_CFG_REG_BANK, val) == bank) { -+ ret = MT76_GET(MT_RF_CSR_CFG_DATA, val); -+ trace_rf_read(dev, bank, offset, ret); -+ } -+out: -+ mutex_unlock(&dev->reg_atomic_mutex); -+ -+ if (ret < 0) -+ dev_err(dev->dev, "Error: RF read %02hhx:%02hhx failed:%d!!\n", -+ bank, offset, ret); -+ -+ return ret; -+} -+ -+static int -+mt7601u_rf_rmw(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 mask, u8 val) -+{ -+ int ret; -+ -+ ret = mt7601u_rf_rr(dev, bank, offset); -+ if (ret < 0) -+ return ret; -+ val |= ret & ~mask; -+ ret = mt7601u_rf_wr(dev, bank, offset, val); -+ if (ret) -+ return ret; -+ -+ return val; -+} -+ -+static int -+mt7601u_rf_set(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 val) -+{ -+ return mt7601u_rf_rmw(dev, bank, offset, 0, val); -+} -+ -+static int -+mt7601u_rf_clear(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 mask) -+{ -+ return mt7601u_rf_rmw(dev, bank, offset, mask, 0); -+} -+ -+static void mt7601u_bbp_wr(struct mt7601u_dev *dev, u8 offset, u8 val) -+{ -+ if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)) || -+ test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return; -+ -+ mutex_lock(&dev->reg_atomic_mutex); -+ -+ if (!mt76_poll(dev, MT_BBP_CSR_CFG, MT_BBP_CSR_CFG_BUSY, 0, 1000)) { -+ dev_err(dev->dev, "Error: BBP write %02hhx failed!!\n", offset); -+ goto out; -+ } -+ -+ mt7601u_wr(dev, MT_BBP_CSR_CFG, -+ MT76_SET(MT_BBP_CSR_CFG_VAL, val) | -+ MT76_SET(MT_BBP_CSR_CFG_REG_NUM, offset) | -+ MT_BBP_CSR_CFG_RW_MODE | MT_BBP_CSR_CFG_BUSY); -+ trace_bbp_write(dev, offset, val); -+out: -+ mutex_unlock(&dev->reg_atomic_mutex); -+} -+ -+static int mt7601u_bbp_rr(struct mt7601u_dev *dev, u8 offset) -+{ -+ u32 val; -+ int ret = -ETIMEDOUT; -+ -+ if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state))) -+ return -EINVAL; -+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) -+ return 0xff; -+ -+ mutex_lock(&dev->reg_atomic_mutex); -+ -+ if (!mt76_poll(dev, MT_BBP_CSR_CFG, MT_BBP_CSR_CFG_BUSY, 0, 1000)) -+ goto out; -+ -+ mt7601u_wr(dev, MT_BBP_CSR_CFG, -+ MT76_SET(MT_BBP_CSR_CFG_REG_NUM, offset) | -+ MT_BBP_CSR_CFG_RW_MODE | MT_BBP_CSR_CFG_BUSY | -+ MT_BBP_CSR_CFG_READ); -+ -+ if (!mt76_poll(dev, MT_BBP_CSR_CFG, MT_BBP_CSR_CFG_BUSY, 0, 1000)) -+ goto out; -+ -+ val = mt7601u_rr(dev, MT_BBP_CSR_CFG); -+ if (MT76_GET(MT_BBP_CSR_CFG_REG_NUM, val) == offset) { -+ ret = MT76_GET(MT_BBP_CSR_CFG_VAL, val); -+ trace_bbp_read(dev, offset, ret); -+ } -+out: -+ mutex_unlock(&dev->reg_atomic_mutex); -+ -+ if (ret < 0) -+ dev_err(dev->dev, "Error: BBP read %02hhx failed:%d!!\n", -+ offset, ret); -+ -+ return ret; -+} -+ -+static int mt7601u_bbp_rmw(struct mt7601u_dev *dev, u8 offset, u8 mask, u8 val) -+{ -+ int ret; -+ -+ ret = mt7601u_bbp_rr(dev, offset); -+ if (ret < 0) -+ return ret; -+ val |= ret & ~mask; -+ mt7601u_bbp_wr(dev, offset, val); -+ -+ return val; -+} -+ -+static u8 mt7601u_bbp_rmc(struct mt7601u_dev *dev, u8 offset, u8 mask, u8 val) -+{ -+ int ret; -+ -+ ret = mt7601u_bbp_rr(dev, offset); -+ if (ret < 0) -+ return ret; -+ val |= ret & ~mask; -+ if (ret != val) -+ mt7601u_bbp_wr(dev, offset, val); -+ -+ return val; -+} -+ -+int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev) -+{ -+ int i = 20; -+ u8 val; -+ -+ do { -+ val = mt7601u_bbp_rr(dev, MT_BBP_REG_VERSION); -+ if (val && ~val) -+ break; -+ } while (--i); -+ -+ if (!i) { -+ dev_err(dev->dev, "Error: BBP is not ready\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+u32 mt7601u_bbp_set_ctrlch(struct mt7601u_dev *dev, bool below) -+{ -+ return mt7601u_bbp_rmc(dev, 3, 0x20, below ? 0x20 : 0); -+} -+ -+int mt7601u_phy_get_rssi(struct mt7601u_dev *dev, -+ struct mt7601u_rxwi *rxwi, u16 rate) -+{ -+ static const s8 lna[2][2][3] = { -+ /* main LNA */ { -+ /* bw20 */ { -2, 15, 33 }, -+ /* bw40 */ { 0, 16, 34 } -+ }, -+ /* aux LNA */ { -+ /* bw20 */ { -2, 15, 33 }, -+ /* bw40 */ { -2, 16, 34 } -+ } -+ }; -+ int bw = MT76_GET(MT_RXWI_RATE_BW, rate); -+ int aux_lna = MT76_GET(MT_RXWI_ANT_AUX_LNA, rxwi->ant); -+ int lna_id = MT76_GET(MT_RXWI_GAIN_RSSI_LNA_ID, rxwi->gain); -+ int val; -+ -+ if (lna_id) /* LNA id can be 0, 2, 3. */ -+ lna_id--; -+ -+ val = 8; -+ val -= lna[aux_lna][bw][lna_id]; -+ val -= MT76_GET(MT_RXWI_GAIN_RSSI_VAL, rxwi->gain); -+ val -= dev->ee->lna_gain; -+ val -= dev->ee->rssi_offset[0]; -+ -+ return val; -+} -+ -+static void mt7601u_vco_cal(struct mt7601u_dev *dev) -+{ -+ mt7601u_rf_wr(dev, 0, 4, 0x0a); -+ mt7601u_rf_wr(dev, 0, 5, 0x20); -+ mt7601u_rf_set(dev, 0, 4, BIT(7)); -+ msleep(2); -+} -+ -+static int mt7601u_set_bw_filter(struct mt7601u_dev *dev, bool cal) -+{ -+ u32 filter = 0; -+ int ret; -+ -+ if (!cal) -+ filter |= 0x10000; -+ if (dev->bw != MT_BW_20) -+ filter |= 0x00100; -+ -+ /* TX */ -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_BW, filter | 1); -+ if (ret) -+ return ret; -+ /* RX */ -+ return mt7601u_mcu_calibrate(dev, MCU_CAL_BW, filter); -+} -+ -+static int mt7601u_load_bbp_temp_table_bw(struct mt7601u_dev *dev) -+{ -+ const struct reg_table *t; -+ -+ if (WARN_ON(dev->temp_mode > MT_TEMP_MODE_LOW)) -+ return -EINVAL; -+ -+ t = &bbp_mode_table[dev->temp_mode][dev->bw]; -+ -+ return mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, t->regs, t->n); -+} -+ -+static int mt7601u_bbp_temp(struct mt7601u_dev *dev, int mode, const char *name) -+{ -+ const struct reg_table *t; -+ int ret; -+ -+ if (dev->temp_mode == mode) -+ return 0; -+ -+ dev->temp_mode = mode; -+ trace_temp_mode(dev, mode); -+ -+ t = bbp_mode_table[dev->temp_mode]; -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, -+ t[2].regs, t[2].n); -+ if (ret) -+ return ret; -+ -+ return mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, -+ t[dev->bw].regs, t[dev->bw].n); -+} -+ -+static void mt7601u_apply_ch14_fixup(struct mt7601u_dev *dev, int hw_chan) -+{ -+ struct mt7601u_rate_power *t = &dev->ee->power_rate_table; -+ -+ if (hw_chan != 14 || dev->bw != MT_BW_20) { -+ mt7601u_bbp_rmw(dev, 4, 0x20, 0); -+ mt7601u_bbp_wr(dev, 178, 0xff); -+ -+ t->cck[0].bw20 = dev->ee->real_cck_bw20[0]; -+ t->cck[1].bw20 = dev->ee->real_cck_bw20[1]; -+ } else { /* Apply CH14 OBW fixup */ -+ mt7601u_bbp_wr(dev, 4, 0x60); -+ mt7601u_bbp_wr(dev, 178, 0); -+ -+ /* Note: vendor code is buggy here for negative values */ -+ t->cck[0].bw20 = dev->ee->real_cck_bw20[0] - 2; -+ t->cck[1].bw20 = dev->ee->real_cck_bw20[1] - 2; -+ } -+} -+ -+static int __mt7601u_phy_set_channel(struct mt7601u_dev *dev, -+ struct cfg80211_chan_def *chandef) -+{ -+#define FREQ_PLAN_REGS 4 -+ static const u8 freq_plan[14][FREQ_PLAN_REGS] = { -+ { 0x99, 0x99, 0x09, 0x50 }, -+ { 0x46, 0x44, 0x0a, 0x50 }, -+ { 0xec, 0xee, 0x0a, 0x50 }, -+ { 0x99, 0x99, 0x0b, 0x50 }, -+ { 0x46, 0x44, 0x08, 0x51 }, -+ { 0xec, 0xee, 0x08, 0x51 }, -+ { 0x99, 0x99, 0x09, 0x51 }, -+ { 0x46, 0x44, 0x0a, 0x51 }, -+ { 0xec, 0xee, 0x0a, 0x51 }, -+ { 0x99, 0x99, 0x0b, 0x51 }, -+ { 0x46, 0x44, 0x08, 0x52 }, -+ { 0xec, 0xee, 0x08, 0x52 }, -+ { 0x99, 0x99, 0x09, 0x52 }, -+ { 0x33, 0x33, 0x0b, 0x52 }, -+ }; -+ struct mt76_reg_pair channel_freq_plan[FREQ_PLAN_REGS] = { -+ { 17, 0 }, { 18, 0 }, { 19, 0 }, { 20, 0 }, -+ }; -+ struct mt76_reg_pair bbp_settings[3] = { -+ { 62, 0x37 - dev->ee->lna_gain }, -+ { 63, 0x37 - dev->ee->lna_gain }, -+ { 64, 0x37 - dev->ee->lna_gain }, -+ }; -+ -+ struct ieee80211_channel *chan = chandef->chan; -+ enum nl80211_channel_type chan_type = -+ cfg80211_get_chandef_type(chandef); -+ struct mt7601u_rate_power *t = &dev->ee->power_rate_table; -+ int chan_idx; -+ bool chan_ext_below; -+ u8 bw; -+ int i, ret; -+ -+ bw = MT_BW_20; -+ chan_ext_below = (chan_type == NL80211_CHAN_HT40MINUS); -+ chan_idx = chan->hw_value - 1; -+ -+ if (chandef->width == NL80211_CHAN_WIDTH_40) { -+ bw = MT_BW_40; -+ -+ if (chan_idx > 1 && chan_type == NL80211_CHAN_HT40MINUS) -+ chan_idx -= 2; -+ else if (chan_idx < 12 && chan_type == NL80211_CHAN_HT40PLUS) -+ chan_idx += 2; -+ else -+ dev_err(dev->dev, "Error: invalid 40MHz channel!!\n"); -+ } -+ -+ if (bw != dev->bw || chan_ext_below != dev->chan_ext_below) { -+ dev_dbg(dev->dev, "Info: switching HT mode bw:%d below:%d\n", -+ bw, chan_ext_below); -+ -+ mt7601u_bbp_set_bw(dev, bw); -+ -+ mt7601u_bbp_set_ctrlch(dev, chan_ext_below); -+ mt7601u_mac_set_ctrlch(dev, chan_ext_below); -+ dev->chan_ext_below = chan_ext_below; -+ } -+ -+ for (i = 0; i < FREQ_PLAN_REGS; i++) -+ channel_freq_plan[i].value = freq_plan[chan_idx][i]; -+ -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_RF, -+ channel_freq_plan, FREQ_PLAN_REGS); -+ if (ret) -+ return ret; -+ -+ mt7601u_rmw(dev, MT_TX_ALC_CFG_0, 0x3f3f, -+ dev->ee->chan_pwr[chan_idx] & 0x3f); -+ -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, -+ bbp_settings, ARRAY_SIZE(bbp_settings)); -+ if (ret) -+ return ret; -+ -+ mt7601u_vco_cal(dev); -+ mt7601u_bbp_set_bw(dev, bw); -+ ret = mt7601u_set_bw_filter(dev, false); -+ if (ret) -+ return ret; -+ -+ mt7601u_apply_ch14_fixup(dev, chan->hw_value); -+ mt7601u_wr(dev, MT_TX_PWR_CFG_0, int_to_s6(t->ofdm[1].bw20) << 24 | -+ int_to_s6(t->ofdm[0].bw20) << 16 | -+ int_to_s6(t->cck[1].bw20) << 8 | -+ int_to_s6(t->cck[0].bw20)); -+ -+ if (test_bit(MT7601U_STATE_SCANNING, &dev->state)) -+ mt7601u_agc_reset(dev); -+ -+ dev->chandef = *chandef; -+ -+ return 0; -+} -+ -+int mt7601u_phy_set_channel(struct mt7601u_dev *dev, -+ struct cfg80211_chan_def *chandef) -+{ -+ int ret; -+ -+ cancel_delayed_work_sync(&dev->cal_work); -+ cancel_delayed_work_sync(&dev->freq_cal.work); -+ -+ mutex_lock(&dev->hw_atomic_mutex); -+ ret = __mt7601u_phy_set_channel(dev, chandef); -+ mutex_unlock(&dev->hw_atomic_mutex); -+ if (ret) -+ return ret; -+ -+ if (test_bit(MT7601U_STATE_SCANNING, &dev->state)) -+ return 0; -+ -+ ieee80211_queue_delayed_work(dev->hw, &dev->cal_work, -+ MT_CALIBRATE_INTERVAL); -+ if (dev->freq_cal.enabled) -+ ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work, -+ MT_FREQ_CAL_INIT_DELAY); -+ return 0; -+} -+ -+#define BBP_R47_FLAG GENMASK(2, 0) -+#define BBP_R47_F_TSSI 0 -+#define BBP_R47_F_PKT_T 1 -+#define BBP_R47_F_TX_RATE 2 -+#define BBP_R47_F_TEMP 4 -+/** -+ * mt7601u_bbp_r47_get - read value through BBP R47/R49 pair -+ * @dev: pointer to adapter structure -+ * @reg: value of BBP R47 before the operation -+ * @flag: one of the BBP_R47_F_* flags -+ * -+ * Convenience helper for reading values through BBP R47/R49 pair. -+ * Takes old value of BBP R47 as @reg, because callers usually have it -+ * cached already. -+ * -+ * Return: value of BBP R49. -+ */ -+static u8 mt7601u_bbp_r47_get(struct mt7601u_dev *dev, u8 reg, u8 flag) -+{ -+ flag |= reg & ~BBP_R47_FLAG; -+ mt7601u_bbp_wr(dev, 47, flag); -+ usleep_range(500, 700); -+ return mt7601u_bbp_rr(dev, 49); -+} -+ -+static s8 mt7601u_read_bootup_temp(struct mt7601u_dev *dev) -+{ -+ u8 bbp_val, temp; -+ u32 rf_bp, rf_set; -+ int i; -+ -+ rf_set = mt7601u_rr(dev, MT_RF_SETTING_0); -+ rf_bp = mt7601u_rr(dev, MT_RF_BYPASS_0); -+ -+ mt7601u_wr(dev, MT_RF_BYPASS_0, 0); -+ mt7601u_wr(dev, MT_RF_SETTING_0, 0x00000010); -+ mt7601u_wr(dev, MT_RF_BYPASS_0, 0x00000010); -+ -+ bbp_val = mt7601u_bbp_rmw(dev, 47, 0, 0x10); -+ -+ mt7601u_bbp_wr(dev, 22, 0x40); -+ -+ for (i = 100; i && (bbp_val & 0x10); i--) -+ bbp_val = mt7601u_bbp_rr(dev, 47); -+ -+ temp = mt7601u_bbp_r47_get(dev, bbp_val, BBP_R47_F_TEMP); -+ -+ mt7601u_bbp_wr(dev, 22, 0); -+ -+ bbp_val = mt7601u_bbp_rr(dev, 21); -+ bbp_val |= 0x02; -+ mt7601u_bbp_wr(dev, 21, bbp_val); -+ bbp_val &= ~0x02; -+ mt7601u_bbp_wr(dev, 21, bbp_val); -+ -+ mt7601u_wr(dev, MT_RF_BYPASS_0, 0); -+ mt7601u_wr(dev, MT_RF_SETTING_0, rf_set); -+ mt7601u_wr(dev, MT_RF_BYPASS_0, rf_bp); -+ -+ trace_read_temp(dev, temp); -+ return temp; -+} -+ -+static s8 mt7601u_read_temp(struct mt7601u_dev *dev) -+{ -+ int i; -+ u8 val; -+ s8 temp; -+ -+ val = mt7601u_bbp_rmw(dev, 47, 0x7f, 0x10); -+ -+ /* Note: this rarely succeeds, temp can change even if it fails. */ -+ for (i = 100; i && (val & 0x10); i--) -+ val = mt7601u_bbp_rr(dev, 47); -+ -+ temp = mt7601u_bbp_r47_get(dev, val, BBP_R47_F_TEMP); -+ -+ trace_read_temp(dev, temp); -+ return temp; -+} -+ -+static void mt7601u_rxdc_cal(struct mt7601u_dev *dev) -+{ -+ static const struct mt76_reg_pair intro[] = { -+ { 158, 0x8d }, { 159, 0xfc }, -+ { 158, 0x8c }, { 159, 0x4c }, -+ }, outro[] = { -+ { 158, 0x8d }, { 159, 0xe0 }, -+ }; -+ u32 mac_ctrl; -+ int i, ret; -+ -+ mac_ctrl = mt7601u_rr(dev, MT_MAC_SYS_CTRL); -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_RX); -+ -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, -+ intro, ARRAY_SIZE(intro)); -+ if (ret) -+ dev_err(dev->dev, "%s intro failed:%d\n", __func__, ret); -+ -+ for (i = 20; i; i--) { -+ usleep_range(300, 500); -+ -+ mt7601u_bbp_wr(dev, 158, 0x8c); -+ if (mt7601u_bbp_rr(dev, 159) == 0x0c) -+ break; -+ } -+ if (!i) -+ dev_err(dev->dev, "%s timed out\n", __func__); -+ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, 0); -+ -+ ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, -+ outro, ARRAY_SIZE(outro)); -+ if (ret) -+ dev_err(dev->dev, "%s outro failed:%d\n", __func__, ret); -+ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, mac_ctrl); -+} -+ -+void mt7601u_phy_recalibrate_after_assoc(struct mt7601u_dev *dev) -+{ -+ mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->curr_temp); -+ -+ mt7601u_rxdc_cal(dev); -+} -+ -+/* Note: function copied from vendor driver */ -+static s16 lin2dBd(u16 linear) -+{ -+ short exp = 0; -+ unsigned int mantisa; -+ int app, dBd; -+ -+ if (WARN_ON(!linear)) -+ return -10000; -+ -+ mantisa = linear; -+ -+ exp = fls(mantisa) - 16; -+ if (exp > 0) -+ mantisa >>= exp; -+ else -+ mantisa <<= abs(exp); -+ -+ if (mantisa <= 0xb800) -+ app = (mantisa + (mantisa >> 3) + (mantisa >> 4) - 0x9600); -+ else -+ app = (mantisa - (mantisa >> 3) - (mantisa >> 6) - 0x5a00); -+ if (app < 0) -+ app = 0; -+ -+ dBd = ((15 + exp) << 15) + app; -+ dBd = (dBd << 2) + (dBd << 1) + (dBd >> 6) + (dBd >> 7); -+ dBd = (dBd >> 10); -+ -+ return dBd; -+} -+ -+static void -+mt7601u_set_initial_tssi(struct mt7601u_dev *dev, s16 tssi_db, s16 tssi_hvga_db) -+{ -+ struct tssi_data *d = &dev->ee->tssi_data; -+ int init_offset; -+ -+ init_offset = -((tssi_db * d->slope + d->offset[1]) / 4096) + 10; -+ -+ mt76_rmw(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, -+ int_to_s6(init_offset) & MT_TX_ALC_CFG_1_TEMP_COMP); -+} -+ -+static void mt7601u_tssi_dc_gain_cal(struct mt7601u_dev *dev) -+{ -+ u8 rf_vga, rf_mixer, bbp_r47; -+ int i, j; -+ s8 res[4]; -+ s16 tssi_init_db, tssi_init_hvga_db; -+ -+ mt7601u_wr(dev, MT_RF_SETTING_0, 0x00000030); -+ mt7601u_wr(dev, MT_RF_BYPASS_0, 0x000c0030); -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, 0); -+ -+ mt7601u_bbp_wr(dev, 58, 0); -+ mt7601u_bbp_wr(dev, 241, 0x2); -+ mt7601u_bbp_wr(dev, 23, 0x8); -+ bbp_r47 = mt7601u_bbp_rr(dev, 47); -+ -+ /* Set VGA gain */ -+ rf_vga = mt7601u_rf_rr(dev, 5, 3); -+ mt7601u_rf_wr(dev, 5, 3, 8); -+ -+ /* Mixer disable */ -+ rf_mixer = mt7601u_rf_rr(dev, 4, 39); -+ mt7601u_rf_wr(dev, 4, 39, 0); -+ -+ for (i = 0; i < 4; i++) { -+ mt7601u_rf_wr(dev, 4, 39, (i & 1) ? rf_mixer : 0); -+ -+ mt7601u_bbp_wr(dev, 23, (i < 2) ? 0x08 : 0x02); -+ mt7601u_rf_wr(dev, 5, 3, (i < 2) ? 0x08 : 0x11); -+ -+ /* BBP TSSI initial and soft reset */ -+ mt7601u_bbp_wr(dev, 22, 0); -+ mt7601u_bbp_wr(dev, 244, 0); -+ -+ mt7601u_bbp_wr(dev, 21, 1); -+ udelay(1); -+ mt7601u_bbp_wr(dev, 21, 0); -+ -+ /* TSSI measurement */ -+ mt7601u_bbp_wr(dev, 47, 0x50); -+ mt7601u_bbp_wr(dev, (i & 1) ? 244 : 22, (i & 1) ? 0x31 : 0x40); -+ -+ for (j = 20; j; j--) -+ if (!(mt7601u_bbp_rr(dev, 47) & 0x10)) -+ break; -+ if (!j) -+ dev_err(dev->dev, "%s timed out\n", __func__); -+ -+ /* TSSI read */ -+ mt7601u_bbp_wr(dev, 47, 0x40); -+ res[i] = mt7601u_bbp_rr(dev, 49); -+ } -+ -+ tssi_init_db = lin2dBd((short)res[1] - res[0]); -+ tssi_init_hvga_db = lin2dBd(((short)res[3] - res[2]) * 4); -+ dev->tssi_init = res[0]; -+ dev->tssi_init_hvga = res[2]; -+ dev->tssi_init_hvga_offset_db = tssi_init_hvga_db - tssi_init_db; -+ -+ dev_dbg(dev->dev, -+ "TSSI_init:%hhx db:%hx hvga:%hhx hvga_db:%hx off_db:%hx\n", -+ dev->tssi_init, tssi_init_db, dev->tssi_init_hvga, -+ tssi_init_hvga_db, dev->tssi_init_hvga_offset_db); -+ -+ mt7601u_bbp_wr(dev, 22, 0); -+ mt7601u_bbp_wr(dev, 244, 0); -+ -+ mt7601u_bbp_wr(dev, 21, 1); -+ udelay(1); -+ mt7601u_bbp_wr(dev, 21, 0); -+ -+ mt7601u_wr(dev, MT_RF_BYPASS_0, 0); -+ mt7601u_wr(dev, MT_RF_SETTING_0, 0); -+ -+ mt7601u_rf_wr(dev, 5, 3, rf_vga); -+ mt7601u_rf_wr(dev, 4, 39, rf_mixer); -+ mt7601u_bbp_wr(dev, 47, bbp_r47); -+ -+ mt7601u_set_initial_tssi(dev, tssi_init_db, tssi_init_hvga_db); -+} -+ -+static int mt7601u_temp_comp(struct mt7601u_dev *dev, bool on) -+{ -+ int ret, temp, hi_temp = 400, lo_temp = -200; -+ -+ temp = (dev->raw_temp - dev->ee->ref_temp) * MT_EE_TEMPERATURE_SLOPE; -+ dev->curr_temp = temp; -+ -+ /* DPD Calibration */ -+ if (temp - dev->dpd_temp > 450 || temp - dev->dpd_temp < -450) { -+ dev->dpd_temp = temp; -+ -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->dpd_temp); -+ if (ret) -+ return ret; -+ -+ mt7601u_vco_cal(dev); -+ -+ dev_dbg(dev->dev, "Recalibrate DPD\n"); -+ } -+ -+ /* PLL Lock Protect */ -+ if (temp < -50 && !dev->pll_lock_protect) { /* < 20C */ -+ dev->pll_lock_protect = true; -+ -+ mt7601u_rf_wr(dev, 4, 4, 6); -+ mt7601u_rf_clear(dev, 4, 10, 0x30); -+ -+ dev_dbg(dev->dev, "PLL lock protect on - too cold\n"); -+ } else if (temp > 50 && dev->pll_lock_protect) { /* > 30C */ -+ dev->pll_lock_protect = false; -+ -+ mt7601u_rf_wr(dev, 4, 4, 0); -+ mt7601u_rf_rmw(dev, 4, 10, 0x30, 0x10); -+ -+ dev_dbg(dev->dev, "PLL lock protect off\n"); -+ } -+ -+ if (on) { -+ hi_temp -= 50; -+ lo_temp -= 50; -+ } -+ -+ /* BBP CR for H, L, N temperature */ -+ if (temp > hi_temp) -+ return mt7601u_bbp_temp(dev, MT_TEMP_MODE_HIGH, "high"); -+ else if (temp > lo_temp) -+ return mt7601u_bbp_temp(dev, MT_TEMP_MODE_NORMAL, "normal"); -+ else -+ return mt7601u_bbp_temp(dev, MT_TEMP_MODE_LOW, "low"); -+} -+ -+/* Note: this is used only with TSSI, we can just use trgt_pwr from eeprom. */ -+static int mt7601u_current_tx_power(struct mt7601u_dev *dev) -+{ -+ return dev->ee->chan_pwr[dev->chandef.chan->hw_value - 1]; -+} -+ -+static bool mt7601u_use_hvga(struct mt7601u_dev *dev) -+{ -+ return !(mt7601u_current_tx_power(dev) > 20); -+} -+ -+static s16 -+mt7601u_phy_rf_pa_mode_val(struct mt7601u_dev *dev, int phy_mode, int tx_rate) -+{ -+ static const s16 decode_tb[] = { 0, 8847, -5734, -5734 }; -+ u32 reg; -+ -+ switch (phy_mode) { -+ case MT_PHY_TYPE_OFDM: -+ tx_rate += 4; -+ case MT_PHY_TYPE_CCK: -+ reg = dev->rf_pa_mode[0]; -+ break; -+ default: -+ reg = dev->rf_pa_mode[1]; -+ break; -+ } -+ -+ return decode_tb[(reg >> (tx_rate * 2)) & 0x3]; -+} -+ -+static struct mt7601u_tssi_params -+mt7601u_tssi_params_get(struct mt7601u_dev *dev) -+{ -+ static const u8 ofdm_pkt2rate[8] = { 6, 4, 2, 0, 7, 5, 3, 1 }; -+ static const int static_power[4] = { 0, -49152, -98304, 49152 }; -+ struct mt7601u_tssi_params p; -+ u8 bbp_r47, pkt_type, tx_rate; -+ struct power_per_rate *rate_table; -+ -+ bbp_r47 = mt7601u_bbp_rr(dev, 47); -+ -+ p.tssi0 = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_TSSI); -+ dev->raw_temp = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_TEMP); -+ pkt_type = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_PKT_T); -+ -+ p.trgt_power = mt7601u_current_tx_power(dev); -+ -+ switch (pkt_type & 0x03) { -+ case MT_PHY_TYPE_CCK: -+ tx_rate = (pkt_type >> 4) & 0x03; -+ rate_table = dev->ee->power_rate_table.cck; -+ break; -+ -+ case MT_PHY_TYPE_OFDM: -+ tx_rate = ofdm_pkt2rate[(pkt_type >> 4) & 0x07]; -+ rate_table = dev->ee->power_rate_table.ofdm; -+ break; -+ -+ default: -+ tx_rate = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_TX_RATE); -+ tx_rate &= 0x7f; -+ rate_table = dev->ee->power_rate_table.ht; -+ break; -+ } -+ -+ if (dev->bw == MT_BW_20) -+ p.trgt_power += rate_table[tx_rate / 2].bw20; -+ else -+ p.trgt_power += rate_table[tx_rate / 2].bw40; -+ -+ p.trgt_power <<= 12; -+ -+ dev_dbg(dev->dev, "tx_rate:%02hhx pwr:%08x\n", tx_rate, p.trgt_power); -+ -+ p.trgt_power += mt7601u_phy_rf_pa_mode_val(dev, pkt_type & 0x03, -+ tx_rate); -+ -+ /* Channel 14, cck, bw20 */ -+ if ((pkt_type & 0x03) == MT_PHY_TYPE_CCK) { -+ if (mt7601u_bbp_rr(dev, 4) & 0x20) -+ p.trgt_power += mt7601u_bbp_rr(dev, 178) ? 18022 : 9830; -+ else -+ p.trgt_power += mt7601u_bbp_rr(dev, 178) ? 819 : 24576; -+ } -+ -+ p.trgt_power += static_power[mt7601u_bbp_rr(dev, 1) & 0x03]; -+ -+ p.trgt_power += dev->ee->tssi_data.tx0_delta_offset; -+ -+ dev_dbg(dev->dev, -+ "tssi:%02hhx t_power:%08x temp:%02hhx pkt_type:%02hhx\n", -+ p.tssi0, p.trgt_power, dev->raw_temp, pkt_type); -+ -+ return p; -+} -+ -+static bool mt7601u_tssi_read_ready(struct mt7601u_dev *dev) -+{ -+ return !(mt7601u_bbp_rr(dev, 47) & 0x10); -+} -+ -+static int mt7601u_tssi_cal(struct mt7601u_dev *dev) -+{ -+ struct mt7601u_tssi_params params; -+ int curr_pwr, diff_pwr; -+ char tssi_offset; -+ s8 tssi_init; -+ s16 tssi_m_dc, tssi_db; -+ bool hvga; -+ u32 val; -+ -+ if (!dev->ee->tssi_enabled) -+ return 0; -+ -+ hvga = mt7601u_use_hvga(dev); -+ if (!dev->tssi_read_trig) -+ return mt7601u_mcu_tssi_read_kick(dev, hvga); -+ -+ if (!mt7601u_tssi_read_ready(dev)) -+ return 0; -+ -+ params = mt7601u_tssi_params_get(dev); -+ -+ tssi_init = (hvga ? dev->tssi_init_hvga : dev->tssi_init); -+ tssi_m_dc = params.tssi0 - tssi_init; -+ tssi_db = lin2dBd(tssi_m_dc); -+ dev_dbg(dev->dev, "tssi dc:%04hx db:%04hx hvga:%d\n", -+ tssi_m_dc, tssi_db, hvga); -+ -+ if (dev->chandef.chan->hw_value < 5) -+ tssi_offset = dev->ee->tssi_data.offset[0]; -+ else if (dev->chandef.chan->hw_value < 9) -+ tssi_offset = dev->ee->tssi_data.offset[1]; -+ else -+ tssi_offset = dev->ee->tssi_data.offset[2]; -+ -+ if (hvga) -+ tssi_db -= dev->tssi_init_hvga_offset_db; -+ -+ curr_pwr = tssi_db * dev->ee->tssi_data.slope + (tssi_offset << 9); -+ diff_pwr = params.trgt_power - curr_pwr; -+ dev_dbg(dev->dev, "Power curr:%08x diff:%08x\n", curr_pwr, diff_pwr); -+ -+ if (params.tssi0 > 126 && diff_pwr > 0) { -+ dev_err(dev->dev, "Error: TSSI upper saturation\n"); -+ diff_pwr = 0; -+ } -+ if (params.tssi0 - tssi_init < 1 && diff_pwr < 0) { -+ dev_err(dev->dev, "Error: TSSI lower saturation\n"); -+ diff_pwr = 0; -+ } -+ -+ if ((dev->prev_pwr_diff ^ diff_pwr) < 0 && abs(diff_pwr) < 4096 && -+ (abs(diff_pwr) > abs(dev->prev_pwr_diff) || -+ (diff_pwr > 0 && diff_pwr == -dev->prev_pwr_diff))) -+ diff_pwr = 0; -+ else -+ dev->prev_pwr_diff = diff_pwr; -+ -+ diff_pwr += (diff_pwr > 0) ? 2048 : -2048; -+ diff_pwr /= 4096; -+ -+ dev_dbg(dev->dev, "final diff: %08x\n", diff_pwr); -+ -+ val = mt7601u_rr(dev, MT_TX_ALC_CFG_1); -+ curr_pwr = s6_to_int(MT76_GET(MT_TX_ALC_CFG_1_TEMP_COMP, val)); -+ diff_pwr += curr_pwr; -+ val = (val & ~MT_TX_ALC_CFG_1_TEMP_COMP) | int_to_s6(diff_pwr); -+ mt7601u_wr(dev, MT_TX_ALC_CFG_1, val); -+ -+ return mt7601u_mcu_tssi_read_kick(dev, hvga); -+} -+ -+static u8 mt7601u_agc_default(struct mt7601u_dev *dev) -+{ -+ return (dev->ee->lna_gain - 8) * 2 + 0x34; -+} -+ -+static void mt7601u_agc_reset(struct mt7601u_dev *dev) -+{ -+ u8 agc = mt7601u_agc_default(dev); -+ -+ mt7601u_bbp_wr(dev, 66, agc); -+} -+ -+void mt7601u_agc_save(struct mt7601u_dev *dev) -+{ -+ dev->agc_save = mt7601u_bbp_rr(dev, 66); -+} -+ -+void mt7601u_agc_restore(struct mt7601u_dev *dev) -+{ -+ mt7601u_bbp_wr(dev, 66, dev->agc_save); -+} -+ -+static void mt7601u_agc_tune(struct mt7601u_dev *dev) -+{ -+ u8 val = mt7601u_agc_default(dev); -+ -+ if (test_bit(MT7601U_STATE_SCANNING, &dev->state)) -+ return; -+ -+ /* Note: only in STA mode and not dozing; perhaps do this only if -+ * there is enough rssi updates since last run? -+ * Rssi updates are only on beacons and U2M so should work... -+ */ -+ spin_lock_bh(&dev->con_mon_lock); -+ if (dev->avg_rssi <= -70) -+ val -= 0x20; -+ else if (dev->avg_rssi <= -60) -+ val -= 0x10; -+ spin_unlock_bh(&dev->con_mon_lock); -+ -+ if (val != mt7601u_bbp_rr(dev, 66)) -+ mt7601u_bbp_wr(dev, 66, val); -+ -+ /* TODO: also if lost a lot of beacons try resetting -+ * (see RTMPSetAGCInitValue() call in mlme.c). -+ */ -+} -+ -+static void mt7601u_phy_calibrate(struct work_struct *work) -+{ -+ struct mt7601u_dev *dev = container_of(work, struct mt7601u_dev, -+ cal_work.work); -+ -+ mt7601u_agc_tune(dev); -+ mt7601u_tssi_cal(dev); -+ /* If TSSI calibration was run it already updated temperature. */ -+ if (!dev->ee->tssi_enabled) -+ dev->raw_temp = mt7601u_read_temp(dev); -+ mt7601u_temp_comp(dev, true); /* TODO: find right value for @on */ -+ -+ ieee80211_queue_delayed_work(dev->hw, &dev->cal_work, -+ MT_CALIBRATE_INTERVAL); -+} -+ -+static unsigned long -+__mt7601u_phy_freq_cal(struct mt7601u_dev *dev, s8 last_offset, u8 phy_mode) -+{ -+ u8 activate_threshold, deactivate_threshold; -+ -+ trace_freq_cal_offset(dev, phy_mode, last_offset); -+ -+ /* No beacons received - reschedule soon */ -+ if (last_offset == MT_FREQ_OFFSET_INVALID) -+ return MT_FREQ_CAL_ADJ_INTERVAL; -+ -+ switch (phy_mode) { -+ case MT_PHY_TYPE_CCK: -+ activate_threshold = 19; -+ deactivate_threshold = 5; -+ break; -+ case MT_PHY_TYPE_OFDM: -+ activate_threshold = 102; -+ deactivate_threshold = 32; -+ break; -+ case MT_PHY_TYPE_HT: -+ case MT_PHY_TYPE_HT_GF: -+ activate_threshold = 82; -+ deactivate_threshold = 20; -+ break; -+ default: -+ WARN_ON(1); -+ return MT_FREQ_CAL_CHECK_INTERVAL; -+ } -+ -+ if (abs(last_offset) >= activate_threshold) -+ dev->freq_cal.adjusting = true; -+ else if (abs(last_offset) <= deactivate_threshold) -+ dev->freq_cal.adjusting = false; -+ -+ if (!dev->freq_cal.adjusting) -+ return MT_FREQ_CAL_CHECK_INTERVAL; -+ -+ if (last_offset > deactivate_threshold) { -+ if (dev->freq_cal.freq > 0) -+ dev->freq_cal.freq--; -+ else -+ dev->freq_cal.adjusting = false; -+ } else if (last_offset < -deactivate_threshold) { -+ if (dev->freq_cal.freq < 0xbf) -+ dev->freq_cal.freq++; -+ else -+ dev->freq_cal.adjusting = false; -+ } -+ -+ trace_freq_cal_adjust(dev, dev->freq_cal.freq); -+ mt7601u_rf_wr(dev, 0, 12, dev->freq_cal.freq); -+ mt7601u_vco_cal(dev); -+ -+ return dev->freq_cal.adjusting ? MT_FREQ_CAL_ADJ_INTERVAL : -+ MT_FREQ_CAL_CHECK_INTERVAL; -+} -+ -+static void mt7601u_phy_freq_cal(struct work_struct *work) -+{ -+ struct mt7601u_dev *dev = container_of(work, struct mt7601u_dev, -+ freq_cal.work.work); -+ s8 last_offset; -+ u8 phy_mode; -+ unsigned long delay; -+ -+ spin_lock_bh(&dev->con_mon_lock); -+ last_offset = dev->bcn_freq_off; -+ phy_mode = dev->bcn_phy_mode; -+ spin_unlock_bh(&dev->con_mon_lock); -+ -+ delay = __mt7601u_phy_freq_cal(dev, last_offset, phy_mode); -+ ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work, delay); -+ -+ spin_lock_bh(&dev->con_mon_lock); -+ dev->bcn_freq_off = MT_FREQ_OFFSET_INVALID; -+ spin_unlock_bh(&dev->con_mon_lock); -+} -+ -+void mt7601u_phy_con_cal_onoff(struct mt7601u_dev *dev, -+ struct ieee80211_bss_conf *info) -+{ -+ if (!info->assoc) -+ cancel_delayed_work_sync(&dev->freq_cal.work); -+ -+ /* Start/stop collecting beacon data */ -+ spin_lock_bh(&dev->con_mon_lock); -+ ether_addr_copy(dev->ap_bssid, info->bssid); -+ dev->avg_rssi = 0; -+ dev->bcn_freq_off = MT_FREQ_OFFSET_INVALID; -+ spin_unlock_bh(&dev->con_mon_lock); -+ -+ dev->freq_cal.freq = dev->ee->rf_freq_off; -+ dev->freq_cal.enabled = info->assoc; -+ dev->freq_cal.adjusting = false; -+ -+ if (info->assoc) -+ ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work, -+ MT_FREQ_CAL_INIT_DELAY); -+} -+ -+static int mt7601u_init_cal(struct mt7601u_dev *dev) -+{ -+ u32 mac_ctrl; -+ int ret; -+ -+ dev->raw_temp = mt7601u_read_bootup_temp(dev); -+ dev->curr_temp = (dev->raw_temp - dev->ee->ref_temp) * -+ MT_EE_TEMPERATURE_SLOPE; -+ dev->dpd_temp = dev->curr_temp; -+ -+ mac_ctrl = mt7601u_rr(dev, MT_MAC_SYS_CTRL); -+ -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_R, 0); -+ if (ret) -+ return ret; -+ -+ ret = mt7601u_rf_rr(dev, 0, 4); -+ if (ret < 0) -+ return ret; -+ ret |= 0x80; -+ ret = mt7601u_rf_wr(dev, 0, 4, ret); -+ if (ret) -+ return ret; -+ msleep(2); -+ -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_TXDCOC, 0); -+ if (ret) -+ return ret; -+ -+ mt7601u_rxdc_cal(dev); -+ -+ ret = mt7601u_set_bw_filter(dev, true); -+ if (ret) -+ return ret; -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_LOFT, 0); -+ if (ret) -+ return ret; -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_TXIQ, 0); -+ if (ret) -+ return ret; -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_RXIQ, 0); -+ if (ret) -+ return ret; -+ ret = mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->dpd_temp); -+ if (ret) -+ return ret; -+ -+ mt7601u_rxdc_cal(dev); -+ -+ mt7601u_tssi_dc_gain_cal(dev); -+ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, mac_ctrl); -+ -+ mt7601u_temp_comp(dev, true); -+ -+ return 0; -+} -+ -+int mt7601u_bbp_set_bw(struct mt7601u_dev *dev, int bw) -+{ -+ u32 val, old; -+ -+ if (bw == dev->bw) { -+ /* Vendor driver does the rmc even when no change is needed. */ -+ mt7601u_bbp_rmc(dev, 4, 0x18, bw == MT_BW_20 ? 0 : 0x10); -+ -+ return 0; -+ } -+ dev->bw = bw; -+ -+ /* Stop MAC for the time of bw change */ -+ old = mt7601u_rr(dev, MT_MAC_SYS_CTRL); -+ val = old & ~(MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX); -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, val); -+ mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_TX | MT_MAC_STATUS_RX, -+ 0, 500000); -+ -+ mt7601u_bbp_rmc(dev, 4, 0x18, bw == MT_BW_20 ? 0 : 0x10); -+ -+ mt7601u_wr(dev, MT_MAC_SYS_CTRL, old); -+ -+ return mt7601u_load_bbp_temp_table_bw(dev); -+} -+ -+/** -+ * mt7601u_set_rx_path - set rx path in BBP -+ * @dev: pointer to adapter structure -+ * @path: rx path to set values are 0-based -+ */ -+void mt7601u_set_rx_path(struct mt7601u_dev *dev, u8 path) -+{ -+ mt7601u_bbp_rmw(dev, 3, 0x18, path << 3); -+} -+ -+/** -+ * mt7601u_set_tx_dac - set which tx DAC to use -+ * @dev: pointer to adapter structure -+ * @path: DAC index, values are 0-based -+ */ -+void mt7601u_set_tx_dac(struct mt7601u_dev *dev, u8 dac) -+{ -+ mt7601u_bbp_rmc(dev, 1, 0x18, dac << 3); -+} -+ -+int mt7601u_phy_init(struct mt7601u_dev *dev) -+{ -+ int ret; -+ -+ dev->rf_pa_mode[0] = mt7601u_rr(dev, MT_RF_PA_MODE_CFG0); -+ dev->rf_pa_mode[1] = mt7601u_rr(dev, MT_RF_PA_MODE_CFG1); -+ -+ ret = mt7601u_rf_wr(dev, 0, 12, dev->ee->rf_freq_off); -+ if (ret) -+ return ret; -+ ret = mt7601u_write_reg_pairs(dev, 0, rf_central, -+ ARRAY_SIZE(rf_central)); -+ if (ret) -+ return ret; -+ ret = mt7601u_write_reg_pairs(dev, 0, rf_channel, -+ ARRAY_SIZE(rf_channel)); -+ if (ret) -+ return ret; -+ ret = mt7601u_write_reg_pairs(dev, 0, rf_vga, ARRAY_SIZE(rf_vga)); -+ if (ret) -+ return ret; -+ -+ ret = mt7601u_init_cal(dev); -+ if (ret) -+ return ret; -+ -+ dev->prev_pwr_diff = 100; -+ -+ INIT_DELAYED_WORK(&dev->cal_work, mt7601u_phy_calibrate); -+ INIT_DELAYED_WORK(&dev->freq_cal.work, mt7601u_phy_freq_cal); -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/regs.h b/drivers/net/wireless/mediatek/mt7601u/regs.h -new file mode 100644 -index 0000000..afd8978 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/regs.h -@@ -0,0 +1,636 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT76_REGS_H -+#define __MT76_REGS_H -+ -+#include -+ -+#ifndef GENMASK -+#define GENMASK(h, l) (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l)) -+#endif -+ -+#define MT_ASIC_VERSION 0x0000 -+ -+#define MT76XX_REV_E3 0x22 -+#define MT76XX_REV_E4 0x33 -+ -+#define MT_CMB_CTRL 0x0020 -+#define MT_CMB_CTRL_XTAL_RDY BIT(22) -+#define MT_CMB_CTRL_PLL_LD BIT(23) -+ -+#define MT_EFUSE_CTRL 0x0024 -+#define MT_EFUSE_CTRL_AOUT GENMASK(5, 0) -+#define MT_EFUSE_CTRL_MODE GENMASK(7, 6) -+#define MT_EFUSE_CTRL_LDO_OFF_TIME GENMASK(13, 8) -+#define MT_EFUSE_CTRL_LDO_ON_TIME GENMASK(15, 14) -+#define MT_EFUSE_CTRL_AIN GENMASK(25, 16) -+#define MT_EFUSE_CTRL_KICK BIT(30) -+#define MT_EFUSE_CTRL_SEL BIT(31) -+ -+#define MT_EFUSE_DATA_BASE 0x0028 -+#define MT_EFUSE_DATA(_n) (MT_EFUSE_DATA_BASE + ((_n) << 2)) -+ -+#define MT_COEXCFG0 0x0040 -+#define MT_COEXCFG0_COEX_EN BIT(0) -+ -+#define MT_WLAN_FUN_CTRL 0x0080 -+#define MT_WLAN_FUN_CTRL_WLAN_EN BIT(0) -+#define MT_WLAN_FUN_CTRL_WLAN_CLK_EN BIT(1) -+#define MT_WLAN_FUN_CTRL_WLAN_RESET_RF BIT(2) -+ -+#define MT_WLAN_FUN_CTRL_WLAN_RESET BIT(3) /* MT76x0 */ -+#define MT_WLAN_FUN_CTRL_CSR_F20M_CKEN BIT(3) /* MT76x2 */ -+ -+#define MT_WLAN_FUN_CTRL_PCIE_CLK_REQ BIT(4) -+#define MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL BIT(5) -+#define MT_WLAN_FUN_CTRL_INV_ANT_SEL BIT(6) -+#define MT_WLAN_FUN_CTRL_WAKE_HOST BIT(7) -+ -+#define MT_WLAN_FUN_CTRL_THERM_RST BIT(8) /* MT76x2 */ -+#define MT_WLAN_FUN_CTRL_THERM_CKEN BIT(9) /* MT76x2 */ -+ -+#define MT_WLAN_FUN_CTRL_GPIO_IN GENMASK(15, 8) /* MT76x0 */ -+#define MT_WLAN_FUN_CTRL_GPIO_OUT GENMASK(23, 16) /* MT76x0 */ -+#define MT_WLAN_FUN_CTRL_GPIO_OUT_EN GENMASK(31, 24) /* MT76x0 */ -+ -+#define MT_XO_CTRL0 0x0100 -+#define MT_XO_CTRL1 0x0104 -+#define MT_XO_CTRL2 0x0108 -+#define MT_XO_CTRL3 0x010c -+#define MT_XO_CTRL4 0x0110 -+ -+#define MT_XO_CTRL5 0x0114 -+#define MT_XO_CTRL5_C2_VAL GENMASK(14, 8) -+ -+#define MT_XO_CTRL6 0x0118 -+#define MT_XO_CTRL6_C2_CTRL GENMASK(14, 8) -+ -+#define MT_XO_CTRL7 0x011c -+ -+#define MT_WLAN_MTC_CTRL 0x10148 -+#define MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP BIT(0) -+#define MT_WLAN_MTC_CTRL_PWR_ACK BIT(12) -+#define MT_WLAN_MTC_CTRL_PWR_ACK_S BIT(13) -+#define MT_WLAN_MTC_CTRL_BBP_MEM_PD GENMASK(19, 16) -+#define MT_WLAN_MTC_CTRL_PBF_MEM_PD BIT(20) -+#define MT_WLAN_MTC_CTRL_FCE_MEM_PD BIT(21) -+#define MT_WLAN_MTC_CTRL_TSO_MEM_PD BIT(22) -+#define MT_WLAN_MTC_CTRL_BBP_MEM_RB BIT(24) -+#define MT_WLAN_MTC_CTRL_PBF_MEM_RB BIT(25) -+#define MT_WLAN_MTC_CTRL_FCE_MEM_RB BIT(26) -+#define MT_WLAN_MTC_CTRL_TSO_MEM_RB BIT(27) -+#define MT_WLAN_MTC_CTRL_STATE_UP BIT(28) -+ -+#define MT_INT_SOURCE_CSR 0x0200 -+#define MT_INT_MASK_CSR 0x0204 -+ -+#define MT_INT_RX_DONE(_n) BIT(_n) -+#define MT_INT_RX_DONE_ALL GENMASK(1, 0) -+#define MT_INT_TX_DONE_ALL GENMASK(13, 4) -+#define MT_INT_TX_DONE(_n) BIT(_n + 4) -+#define MT_INT_RX_COHERENT BIT(16) -+#define MT_INT_TX_COHERENT BIT(17) -+#define MT_INT_ANY_COHERENT BIT(18) -+#define MT_INT_MCU_CMD BIT(19) -+#define MT_INT_TBTT BIT(20) -+#define MT_INT_PRE_TBTT BIT(21) -+#define MT_INT_TX_STAT BIT(22) -+#define MT_INT_AUTO_WAKEUP BIT(23) -+#define MT_INT_GPTIMER BIT(24) -+#define MT_INT_RXDELAYINT BIT(26) -+#define MT_INT_TXDELAYINT BIT(27) -+ -+#define MT_WPDMA_GLO_CFG 0x0208 -+#define MT_WPDMA_GLO_CFG_TX_DMA_EN BIT(0) -+#define MT_WPDMA_GLO_CFG_TX_DMA_BUSY BIT(1) -+#define MT_WPDMA_GLO_CFG_RX_DMA_EN BIT(2) -+#define MT_WPDMA_GLO_CFG_RX_DMA_BUSY BIT(3) -+#define MT_WPDMA_GLO_CFG_DMA_BURST_SIZE GENMASK(5, 4) -+#define MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE BIT(6) -+#define MT_WPDMA_GLO_CFG_BIG_ENDIAN BIT(7) -+#define MT_WPDMA_GLO_CFG_HDR_SEG_LEN GENMASK(15, 8) -+#define MT_WPDMA_GLO_CFG_CLK_GATE_DIS BIT(30) -+#define MT_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) -+ -+#define MT_WPDMA_RST_IDX 0x020c -+ -+#define MT_WPDMA_DELAY_INT_CFG 0x0210 -+ -+#define MT_WMM_AIFSN 0x0214 -+#define MT_WMM_AIFSN_MASK GENMASK(3, 0) -+#define MT_WMM_AIFSN_SHIFT(_n) ((_n) * 4) -+ -+#define MT_WMM_CWMIN 0x0218 -+#define MT_WMM_CWMIN_MASK GENMASK(3, 0) -+#define MT_WMM_CWMIN_SHIFT(_n) ((_n) * 4) -+ -+#define MT_WMM_CWMAX 0x021c -+#define MT_WMM_CWMAX_MASK GENMASK(3, 0) -+#define MT_WMM_CWMAX_SHIFT(_n) ((_n) * 4) -+ -+#define MT_WMM_TXOP_BASE 0x0220 -+#define MT_WMM_TXOP(_n) (MT_WMM_TXOP_BASE + (((_n) / 2) << 2)) -+#define MT_WMM_TXOP_SHIFT(_n) ((_n & 1) * 16) -+#define MT_WMM_TXOP_MASK GENMASK(15, 0) -+ -+#define MT_FCE_DMA_ADDR 0x0230 -+#define MT_FCE_DMA_LEN 0x0234 -+ -+#define MT_USB_DMA_CFG 0x238 -+#define MT_USB_DMA_CFG_RX_BULK_AGG_TOUT GENMASK(7, 0) -+#define MT_USB_DMA_CFG_RX_BULK_AGG_LMT GENMASK(15, 8) -+#define MT_USB_DMA_CFG_PHY_CLR BIT(16) -+#define MT_USB_DMA_CFG_TX_CLR BIT(19) -+#define MT_USB_DMA_CFG_TXOP_HALT BIT(20) -+#define MT_USB_DMA_CFG_RX_BULK_AGG_EN BIT(21) -+#define MT_USB_DMA_CFG_RX_BULK_EN BIT(22) -+#define MT_USB_DMA_CFG_TX_BULK_EN BIT(23) -+#define MT_USB_DMA_CFG_UDMA_RX_WL_DROP BIT(25) -+#define MT_USB_DMA_CFG_EP_OUT_VALID GENMASK(29, 27) -+#define MT_USB_DMA_CFG_RX_BUSY BIT(30) -+#define MT_USB_DMA_CFG_TX_BUSY BIT(31) -+ -+#define MT_TSO_CTRL 0x0250 -+#define MT_HEADER_TRANS_CTRL_REG 0x0260 -+ -+#define MT_US_CYC_CFG 0x02a4 -+#define MT_US_CYC_CNT GENMASK(7, 0) -+ -+#define MT_TX_RING_BASE 0x0300 -+#define MT_RX_RING_BASE 0x03c0 -+#define MT_RING_SIZE 0x10 -+ -+#define MT_TX_HW_QUEUE_MCU 8 -+#define MT_TX_HW_QUEUE_MGMT 9 -+ -+#define MT_PBF_SYS_CTRL 0x0400 -+#define MT_PBF_SYS_CTRL_MCU_RESET BIT(0) -+#define MT_PBF_SYS_CTRL_DMA_RESET BIT(1) -+#define MT_PBF_SYS_CTRL_MAC_RESET BIT(2) -+#define MT_PBF_SYS_CTRL_PBF_RESET BIT(3) -+#define MT_PBF_SYS_CTRL_ASY_RESET BIT(4) -+ -+#define MT_PBF_CFG 0x0404 -+#define MT_PBF_CFG_TX0Q_EN BIT(0) -+#define MT_PBF_CFG_TX1Q_EN BIT(1) -+#define MT_PBF_CFG_TX2Q_EN BIT(2) -+#define MT_PBF_CFG_TX3Q_EN BIT(3) -+#define MT_PBF_CFG_RX0Q_EN BIT(4) -+#define MT_PBF_CFG_RX_DROP_EN BIT(8) -+ -+#define MT_PBF_TX_MAX_PCNT 0x0408 -+#define MT_PBF_RX_MAX_PCNT 0x040c -+ -+#define MT_BCN_OFFSET_BASE 0x041c -+#define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2)) -+ -+#define MT_RF_CSR_CFG 0x0500 -+#define MT_RF_CSR_CFG_DATA GENMASK(7, 0) -+#define MT_RF_CSR_CFG_REG_ID GENMASK(13, 8) -+#define MT_RF_CSR_CFG_REG_BANK GENMASK(17, 14) -+#define MT_RF_CSR_CFG_WR BIT(30) -+#define MT_RF_CSR_CFG_KICK BIT(31) -+ -+#define MT_RF_BYPASS_0 0x0504 -+#define MT_RF_BYPASS_1 0x0508 -+#define MT_RF_SETTING_0 0x050c -+ -+#define MT_RF_DATA_WRITE 0x0524 -+ -+#define MT_RF_CTRL 0x0528 -+#define MT_RF_CTRL_ADDR GENMASK(11, 0) -+#define MT_RF_CTRL_WRITE BIT(12) -+#define MT_RF_CTRL_BUSY BIT(13) -+#define MT_RF_CTRL_IDX BIT(16) -+ -+#define MT_RF_DATA_READ 0x052c -+ -+#define MT_FCE_PSE_CTRL 0x0800 -+#define MT_FCE_PARAMETERS 0x0804 -+#define MT_FCE_CSO 0x0808 -+ -+#define MT_FCE_L2_STUFF 0x080c -+#define MT_FCE_L2_STUFF_HT_L2_EN BIT(0) -+#define MT_FCE_L2_STUFF_QOS_L2_EN BIT(1) -+#define MT_FCE_L2_STUFF_RX_STUFF_EN BIT(2) -+#define MT_FCE_L2_STUFF_TX_STUFF_EN BIT(3) -+#define MT_FCE_L2_STUFF_WR_MPDU_LEN_EN BIT(4) -+#define MT_FCE_L2_STUFF_MVINV_BSWAP BIT(5) -+#define MT_FCE_L2_STUFF_TS_CMD_QSEL_EN GENMASK(15, 8) -+#define MT_FCE_L2_STUFF_TS_LEN_EN GENMASK(23, 16) -+#define MT_FCE_L2_STUFF_OTHER_PORT GENMASK(25, 24) -+ -+#define MT_FCE_WLAN_FLOW_CONTROL1 0x0824 -+ -+#define MT_TX_CPU_FROM_FCE_BASE_PTR 0x09a0 -+#define MT_TX_CPU_FROM_FCE_MAX_COUNT 0x09a4 -+#define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8 -+ -+#define MT_FCE_PDMA_GLOBAL_CONF 0x09c4 -+ -+#define MT_PAUSE_ENABLE_CONTROL1 0x0a38 -+ -+#define MT_FCE_SKIP_FS 0x0a6c -+ -+#define MT_MAC_CSR0 0x1000 -+ -+#define MT_MAC_SYS_CTRL 0x1004 -+#define MT_MAC_SYS_CTRL_RESET_CSR BIT(0) -+#define MT_MAC_SYS_CTRL_RESET_BBP BIT(1) -+#define MT_MAC_SYS_CTRL_ENABLE_TX BIT(2) -+#define MT_MAC_SYS_CTRL_ENABLE_RX BIT(3) -+ -+#define MT_MAC_ADDR_DW0 0x1008 -+#define MT_MAC_ADDR_DW1 0x100c -+#define MT_MAC_ADDR_DW1_U2ME_MASK GENMASK(23, 16) -+ -+#define MT_MAC_BSSID_DW0 0x1010 -+#define MT_MAC_BSSID_DW1 0x1014 -+#define MT_MAC_BSSID_DW1_ADDR GENMASK(15, 0) -+#define MT_MAC_BSSID_DW1_MBSS_MODE GENMASK(17, 16) -+#define MT_MAC_BSSID_DW1_MBEACON_N GENMASK(20, 18) -+#define MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT BIT(21) -+#define MT_MAC_BSSID_DW1_MBSS_MODE_B2 BIT(22) -+#define MT_MAC_BSSID_DW1_MBEACON_N_B3 BIT(23) -+#define MT_MAC_BSSID_DW1_MBSS_IDX_BYTE GENMASK(26, 24) -+ -+#define MT_MAX_LEN_CFG 0x1018 -+#define MT_MAX_LEN_CFG_AMPDU GENMASK(13, 12) -+ -+#define MT_BBP_CSR_CFG 0x101c -+#define MT_BBP_CSR_CFG_VAL GENMASK(7, 0) -+#define MT_BBP_CSR_CFG_REG_NUM GENMASK(15, 8) -+#define MT_BBP_CSR_CFG_READ BIT(16) -+#define MT_BBP_CSR_CFG_BUSY BIT(17) -+#define MT_BBP_CSR_CFG_PAR_DUR BIT(18) -+#define MT_BBP_CSR_CFG_RW_MODE BIT(19) -+ -+#define MT_AMPDU_MAX_LEN_20M1S 0x1030 -+#define MT_AMPDU_MAX_LEN_20M2S 0x1034 -+#define MT_AMPDU_MAX_LEN_40M1S 0x1038 -+#define MT_AMPDU_MAX_LEN_40M2S 0x103c -+#define MT_AMPDU_MAX_LEN 0x1040 -+ -+#define MT_WCID_DROP_BASE 0x106c -+#define MT_WCID_DROP(_n) (MT_WCID_DROP_BASE + ((_n) >> 5) * 4) -+#define MT_WCID_DROP_MASK(_n) BIT((_n) % 32) -+ -+#define MT_BCN_BYPASS_MASK 0x108c -+ -+#define MT_MAC_APC_BSSID_BASE 0x1090 -+#define MT_MAC_APC_BSSID_L(_n) (MT_MAC_APC_BSSID_BASE + ((_n) * 8)) -+#define MT_MAC_APC_BSSID_H(_n) (MT_MAC_APC_BSSID_BASE + ((_n) * 8 + 4)) -+#define MT_MAC_APC_BSSID_H_ADDR GENMASK(15, 0) -+#define MT_MAC_APC_BSSID0_H_EN BIT(16) -+ -+#define MT_XIFS_TIME_CFG 0x1100 -+#define MT_XIFS_TIME_CFG_CCK_SIFS GENMASK(7, 0) -+#define MT_XIFS_TIME_CFG_OFDM_SIFS GENMASK(15, 8) -+#define MT_XIFS_TIME_CFG_OFDM_XIFS GENMASK(19, 16) -+#define MT_XIFS_TIME_CFG_EIFS GENMASK(28, 20) -+#define MT_XIFS_TIME_CFG_BB_RXEND_EN BIT(29) -+ -+#define MT_BKOFF_SLOT_CFG 0x1104 -+#define MT_BKOFF_SLOT_CFG_SLOTTIME GENMASK(7, 0) -+#define MT_BKOFF_SLOT_CFG_CC_DELAY GENMASK(11, 8) -+ -+#define MT_BEACON_TIME_CFG 0x1114 -+#define MT_BEACON_TIME_CFG_INTVAL GENMASK(15, 0) -+#define MT_BEACON_TIME_CFG_TIMER_EN BIT(16) -+#define MT_BEACON_TIME_CFG_SYNC_MODE GENMASK(18, 17) -+#define MT_BEACON_TIME_CFG_TBTT_EN BIT(19) -+#define MT_BEACON_TIME_CFG_BEACON_TX BIT(20) -+#define MT_BEACON_TIME_CFG_TSF_COMP GENMASK(31, 24) -+ -+#define MT_TBTT_SYNC_CFG 0x1118 -+#define MT_TBTT_TIMER_CFG 0x1124 -+ -+#define MT_INT_TIMER_CFG 0x1128 -+#define MT_INT_TIMER_CFG_PRE_TBTT GENMASK(15, 0) -+#define MT_INT_TIMER_CFG_GP_TIMER GENMASK(31, 16) -+ -+#define MT_INT_TIMER_EN 0x112c -+#define MT_INT_TIMER_EN_PRE_TBTT_EN BIT(0) -+#define MT_INT_TIMER_EN_GP_TIMER_EN BIT(1) -+ -+#define MT_MAC_STATUS 0x1200 -+#define MT_MAC_STATUS_TX BIT(0) -+#define MT_MAC_STATUS_RX BIT(1) -+ -+#define MT_PWR_PIN_CFG 0x1204 -+#define MT_AUX_CLK_CFG 0x120c -+ -+#define MT_BB_PA_MODE_CFG0 0x1214 -+#define MT_BB_PA_MODE_CFG1 0x1218 -+#define MT_RF_PA_MODE_CFG0 0x121c -+#define MT_RF_PA_MODE_CFG1 0x1220 -+ -+#define MT_RF_PA_MODE_ADJ0 0x1228 -+#define MT_RF_PA_MODE_ADJ1 0x122c -+ -+#define MT_DACCLK_EN_DLY_CFG 0x1264 -+ -+#define MT_EDCA_CFG_BASE 0x1300 -+#define MT_EDCA_CFG_AC(_n) (MT_EDCA_CFG_BASE + ((_n) << 2)) -+#define MT_EDCA_CFG_TXOP GENMASK(7, 0) -+#define MT_EDCA_CFG_AIFSN GENMASK(11, 8) -+#define MT_EDCA_CFG_CWMIN GENMASK(15, 12) -+#define MT_EDCA_CFG_CWMAX GENMASK(19, 16) -+ -+#define MT_TX_PWR_CFG_0 0x1314 -+#define MT_TX_PWR_CFG_1 0x1318 -+#define MT_TX_PWR_CFG_2 0x131c -+#define MT_TX_PWR_CFG_3 0x1320 -+#define MT_TX_PWR_CFG_4 0x1324 -+ -+#define MT_TX_BAND_CFG 0x132c -+#define MT_TX_BAND_CFG_UPPER_40M BIT(0) -+#define MT_TX_BAND_CFG_5G BIT(1) -+#define MT_TX_BAND_CFG_2G BIT(2) -+ -+#define MT_HT_FBK_TO_LEGACY 0x1384 -+#define MT_TX_MPDU_ADJ_INT 0x1388 -+ -+#define MT_TX_PWR_CFG_7 0x13d4 -+#define MT_TX_PWR_CFG_8 0x13d8 -+#define MT_TX_PWR_CFG_9 0x13dc -+ -+#define MT_TX_SW_CFG0 0x1330 -+#define MT_TX_SW_CFG1 0x1334 -+#define MT_TX_SW_CFG2 0x1338 -+ -+#define MT_TXOP_CTRL_CFG 0x1340 -+#define MT_TXOP_TRUN_EN GENMASK(5, 0) -+#define MT_TXOP_EXT_CCA_DLY GENMASK(15, 8) -+#define MT_TXOP_CTRL -+ -+#define MT_TX_RTS_CFG 0x1344 -+#define MT_TX_RTS_CFG_RETRY_LIMIT GENMASK(7, 0) -+#define MT_TX_RTS_CFG_THRESH GENMASK(23, 8) -+#define MT_TX_RTS_FALLBACK BIT(24) -+ -+#define MT_TX_TIMEOUT_CFG 0x1348 -+#define MT_TX_RETRY_CFG 0x134c -+#define MT_TX_LINK_CFG 0x1350 -+#define MT_HT_FBK_CFG0 0x1354 -+#define MT_HT_FBK_CFG1 0x1358 -+#define MT_LG_FBK_CFG0 0x135c -+#define MT_LG_FBK_CFG1 0x1360 -+ -+#define MT_CCK_PROT_CFG 0x1364 -+#define MT_OFDM_PROT_CFG 0x1368 -+#define MT_MM20_PROT_CFG 0x136c -+#define MT_MM40_PROT_CFG 0x1370 -+#define MT_GF20_PROT_CFG 0x1374 -+#define MT_GF40_PROT_CFG 0x1378 -+ -+#define MT_PROT_RATE GENMASK(15, 0) -+#define MT_PROT_CTRL_RTS_CTS BIT(16) -+#define MT_PROT_CTRL_CTS2SELF BIT(17) -+#define MT_PROT_NAV_SHORT BIT(18) -+#define MT_PROT_NAV_LONG BIT(19) -+#define MT_PROT_TXOP_ALLOW_CCK BIT(20) -+#define MT_PROT_TXOP_ALLOW_OFDM BIT(21) -+#define MT_PROT_TXOP_ALLOW_MM20 BIT(22) -+#define MT_PROT_TXOP_ALLOW_MM40 BIT(23) -+#define MT_PROT_TXOP_ALLOW_GF20 BIT(24) -+#define MT_PROT_TXOP_ALLOW_GF40 BIT(25) -+#define MT_PROT_RTS_THR_EN BIT(26) -+#define MT_PROT_RATE_CCK_11 0x0003 -+#define MT_PROT_RATE_OFDM_6 0x4000 -+#define MT_PROT_RATE_OFDM_24 0x4004 -+#define MT_PROT_RATE_DUP_OFDM_24 0x4084 -+#define MT_PROT_TXOP_ALLOW_ALL GENMASK(25, 20) -+#define MT_PROT_TXOP_ALLOW_BW20 (MT_PROT_TXOP_ALLOW_ALL & \ -+ ~MT_PROT_TXOP_ALLOW_MM40 & \ -+ ~MT_PROT_TXOP_ALLOW_GF40) -+ -+#define MT_EXP_ACK_TIME 0x1380 -+ -+#define MT_TX_PWR_CFG_0_EXT 0x1390 -+#define MT_TX_PWR_CFG_1_EXT 0x1394 -+ -+#define MT_TX_FBK_LIMIT 0x1398 -+#define MT_TX_FBK_LIMIT_MPDU_FBK GENMASK(7, 0) -+#define MT_TX_FBK_LIMIT_AMPDU_FBK GENMASK(15, 8) -+#define MT_TX_FBK_LIMIT_MPDU_UP_CLEAR BIT(16) -+#define MT_TX_FBK_LIMIT_AMPDU_UP_CLEAR BIT(17) -+#define MT_TX_FBK_LIMIT_RATE_LUT BIT(18) -+ -+#define MT_TX0_RF_GAIN_CORR 0x13a0 -+#define MT_TX1_RF_GAIN_CORR 0x13a4 -+#define MT_TX0_RF_GAIN_ATTEN 0x13a8 -+ -+#define MT_TX_ALC_CFG_0 0x13b0 -+#define MT_TX_ALC_CFG_0_CH_INIT_0 GENMASK(5, 0) -+#define MT_TX_ALC_CFG_0_CH_INIT_1 GENMASK(13, 8) -+#define MT_TX_ALC_CFG_0_LIMIT_0 GENMASK(21, 16) -+#define MT_TX_ALC_CFG_0_LIMIT_1 GENMASK(29, 24) -+ -+#define MT_TX_ALC_CFG_1 0x13b4 -+#define MT_TX_ALC_CFG_1_TEMP_COMP GENMASK(5, 0) -+ -+#define MT_TX_ALC_CFG_2 0x13a8 -+#define MT_TX_ALC_CFG_2_TEMP_COMP GENMASK(5, 0) -+ -+#define MT_TX0_BB_GAIN_ATTEN 0x13c0 -+ -+#define MT_TX_ALC_VGA3 0x13c8 -+ -+#define MT_TX_PROT_CFG6 0x13e0 -+#define MT_TX_PROT_CFG7 0x13e4 -+#define MT_TX_PROT_CFG8 0x13e8 -+ -+#define MT_PIFS_TX_CFG 0x13ec -+ -+#define MT_RX_FILTR_CFG 0x1400 -+ -+#define MT_RX_FILTR_CFG_CRC_ERR BIT(0) -+#define MT_RX_FILTR_CFG_PHY_ERR BIT(1) -+#define MT_RX_FILTR_CFG_PROMISC BIT(2) -+#define MT_RX_FILTR_CFG_OTHER_BSS BIT(3) -+#define MT_RX_FILTR_CFG_VER_ERR BIT(4) -+#define MT_RX_FILTR_CFG_MCAST BIT(5) -+#define MT_RX_FILTR_CFG_BCAST BIT(6) -+#define MT_RX_FILTR_CFG_DUP BIT(7) -+#define MT_RX_FILTR_CFG_CFACK BIT(8) -+#define MT_RX_FILTR_CFG_CFEND BIT(9) -+#define MT_RX_FILTR_CFG_ACK BIT(10) -+#define MT_RX_FILTR_CFG_CTS BIT(11) -+#define MT_RX_FILTR_CFG_RTS BIT(12) -+#define MT_RX_FILTR_CFG_PSPOLL BIT(13) -+#define MT_RX_FILTR_CFG_BA BIT(14) -+#define MT_RX_FILTR_CFG_BAR BIT(15) -+#define MT_RX_FILTR_CFG_CTRL_RSV BIT(16) -+ -+#define MT_AUTO_RSP_CFG 0x1404 -+ -+#define MT_AUTO_RSP_PREAMB_SHORT BIT(4) -+ -+#define MT_LEGACY_BASIC_RATE 0x1408 -+#define MT_HT_BASIC_RATE 0x140c -+ -+#define MT_RX_PARSER_CFG 0x1418 -+#define MT_RX_PARSER_RX_SET_NAV_ALL BIT(0) -+ -+#define MT_EXT_CCA_CFG 0x141c -+#define MT_EXT_CCA_CFG_CCA0 GENMASK(1, 0) -+#define MT_EXT_CCA_CFG_CCA1 GENMASK(3, 2) -+#define MT_EXT_CCA_CFG_CCA2 GENMASK(5, 4) -+#define MT_EXT_CCA_CFG_CCA3 GENMASK(7, 6) -+#define MT_EXT_CCA_CFG_CCA_MASK GENMASK(11, 8) -+#define MT_EXT_CCA_CFG_ED_CCA_MASK GENMASK(15, 12) -+ -+#define MT_TX_SW_CFG3 0x1478 -+ -+#define MT_PN_PAD_MODE 0x150c -+ -+#define MT_TXOP_HLDR_ET 0x1608 -+ -+#define MT_PROT_AUTO_TX_CFG 0x1648 -+ -+#define MT_RX_STA_CNT0 0x1700 -+#define MT_RX_STA_CNT1 0x1704 -+#define MT_RX_STA_CNT2 0x1708 -+#define MT_TX_STA_CNT0 0x170c -+#define MT_TX_STA_CNT1 0x1710 -+#define MT_TX_STA_CNT2 0x1714 -+ -+/* Vendor driver defines content of the second word of STAT_FIFO as follows: -+ * MT_TX_STAT_FIFO_RATE GENMASK(26, 16) -+ * MT_TX_STAT_FIFO_ETXBF BIT(27) -+ * MT_TX_STAT_FIFO_SND BIT(28) -+ * MT_TX_STAT_FIFO_ITXBF BIT(29) -+ * However, tests show that b16-31 have the same layout as TXWI rate_ctl -+ * with rate set to rate at which frame was acked. -+ */ -+#define MT_TX_STAT_FIFO 0x1718 -+#define MT_TX_STAT_FIFO_VALID BIT(0) -+#define MT_TX_STAT_FIFO_PID_TYPE GENMASK(4, 1) -+#define MT_TX_STAT_FIFO_SUCCESS BIT(5) -+#define MT_TX_STAT_FIFO_AGGR BIT(6) -+#define MT_TX_STAT_FIFO_ACKREQ BIT(7) -+#define MT_TX_STAT_FIFO_WCID GENMASK(15, 8) -+#define MT_TX_STAT_FIFO_RATE GENMASK(31, 16) -+ -+#define MT_TX_AGG_STAT 0x171c -+ -+#define MT_TX_AGG_CNT_BASE0 0x1720 -+ -+#define MT_MPDU_DENSITY_CNT 0x1740 -+ -+#define MT_TX_AGG_CNT_BASE1 0x174c -+ -+#define MT_TX_AGG_CNT(_id) ((_id) < 8 ? \ -+ MT_TX_AGG_CNT_BASE0 + ((_id) << 2) : \ -+ MT_TX_AGG_CNT_BASE1 + ((_id - 8) << 2)) -+ -+#define MT_TX_STAT_FIFO_EXT 0x1798 -+#define MT_TX_STAT_FIFO_EXT_RETRY GENMASK(7, 0) -+ -+#define MT_BBP_CORE_BASE 0x2000 -+#define MT_BBP_IBI_BASE 0x2100 -+#define MT_BBP_AGC_BASE 0x2300 -+#define MT_BBP_TXC_BASE 0x2400 -+#define MT_BBP_RXC_BASE 0x2500 -+#define MT_BBP_TXO_BASE 0x2600 -+#define MT_BBP_TXBE_BASE 0x2700 -+#define MT_BBP_RXFE_BASE 0x2800 -+#define MT_BBP_RXO_BASE 0x2900 -+#define MT_BBP_DFS_BASE 0x2a00 -+#define MT_BBP_TR_BASE 0x2b00 -+#define MT_BBP_CAL_BASE 0x2c00 -+#define MT_BBP_DSC_BASE 0x2e00 -+#define MT_BBP_PFMU_BASE 0x2f00 -+ -+#define MT_BBP(_type, _n) (MT_BBP_##_type##_BASE + ((_n) << 2)) -+ -+#define MT_BBP_CORE_R1_BW GENMASK(4, 3) -+ -+#define MT_BBP_AGC_R0_CTRL_CHAN GENMASK(9, 8) -+#define MT_BBP_AGC_R0_BW GENMASK(14, 12) -+ -+/* AGC, R4/R5 */ -+#define MT_BBP_AGC_LNA_GAIN GENMASK(21, 16) -+ -+/* AGC, R8/R9 */ -+#define MT_BBP_AGC_GAIN GENMASK(14, 8) -+ -+#define MT_BBP_AGC20_RSSI0 GENMASK(7, 0) -+#define MT_BBP_AGC20_RSSI1 GENMASK(15, 8) -+ -+#define MT_BBP_TXBE_R0_CTRL_CHAN GENMASK(1, 0) -+ -+#define MT_WCID_ADDR_BASE 0x1800 -+#define MT_WCID_ADDR(_n) (MT_WCID_ADDR_BASE + (_n) * 8) -+ -+#define MT_SRAM_BASE 0x4000 -+ -+#define MT_WCID_KEY_BASE 0x8000 -+#define MT_WCID_KEY(_n) (MT_WCID_KEY_BASE + (_n) * 32) -+ -+#define MT_WCID_IV_BASE 0xa000 -+#define MT_WCID_IV(_n) (MT_WCID_IV_BASE + (_n) * 8) -+ -+#define MT_WCID_ATTR_BASE 0xa800 -+#define MT_WCID_ATTR(_n) (MT_WCID_ATTR_BASE + (_n) * 4) -+ -+#define MT_WCID_ATTR_PAIRWISE BIT(0) -+#define MT_WCID_ATTR_PKEY_MODE GENMASK(3, 1) -+#define MT_WCID_ATTR_BSS_IDX GENMASK(6, 4) -+#define MT_WCID_ATTR_RXWI_UDF GENMASK(9, 7) -+#define MT_WCID_ATTR_PKEY_MODE_EXT BIT(10) -+#define MT_WCID_ATTR_BSS_IDX_EXT BIT(11) -+#define MT_WCID_ATTR_WAPI_MCBC BIT(15) -+#define MT_WCID_ATTR_WAPI_KEYID GENMASK(31, 24) -+ -+#define MT_SKEY_BASE_0 0xac00 -+#define MT_SKEY_BASE_1 0xb400 -+#define MT_SKEY_0(_bss, _idx) \ -+ (MT_SKEY_BASE_0 + (4 * (_bss) + _idx) * 32) -+#define MT_SKEY_1(_bss, _idx) \ -+ (MT_SKEY_BASE_1 + (4 * ((_bss) & 7) + _idx) * 32) -+#define MT_SKEY(_bss, _idx) \ -+ ((_bss & 8) ? MT_SKEY_1(_bss, _idx) : MT_SKEY_0(_bss, _idx)) -+ -+#define MT_SKEY_MODE_BASE_0 0xb000 -+#define MT_SKEY_MODE_BASE_1 0xb3f0 -+#define MT_SKEY_MODE_0(_bss) \ -+ (MT_SKEY_MODE_BASE_0 + ((_bss / 2) << 2)) -+#define MT_SKEY_MODE_1(_bss) \ -+ (MT_SKEY_MODE_BASE_1 + ((((_bss) & 7) / 2) << 2)) -+#define MT_SKEY_MODE(_bss) \ -+ ((_bss & 8) ? MT_SKEY_MODE_1(_bss) : MT_SKEY_MODE_0(_bss)) -+#define MT_SKEY_MODE_MASK GENMASK(3, 0) -+#define MT_SKEY_MODE_SHIFT(_bss, _idx) (4 * ((_idx) + 4 * (_bss & 1))) -+ -+#define MT_BEACON_BASE 0xc000 -+ -+#define MT_TEMP_SENSOR 0x1d000 -+#define MT_TEMP_SENSOR_VAL GENMASK(6, 0) -+ -+enum mt76_cipher_type { -+ MT_CIPHER_NONE, -+ MT_CIPHER_WEP40, -+ MT_CIPHER_WEP104, -+ MT_CIPHER_TKIP, -+ MT_CIPHER_AES_CCMP, -+ MT_CIPHER_CKIP40, -+ MT_CIPHER_CKIP104, -+ MT_CIPHER_CKIP128, -+ MT_CIPHER_WAPI, -+}; -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/trace.c b/drivers/net/wireless/mediatek/mt7601u/trace.c -new file mode 100644 -index 0000000..8abdd3c ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/trace.c -@@ -0,0 +1,21 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+ -+#ifndef __CHECKER__ -+#define CREATE_TRACE_POINTS -+#include "trace.h" -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/trace.h b/drivers/net/wireless/mediatek/mt7601u/trace.h -new file mode 100644 -index 0000000..2898973 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/trace.h -@@ -0,0 +1,400 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#if !defined(__MT7601U_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define __MT7601U_TRACE_H -+ -+#include -+#include "mt7601u.h" -+#include "mac.h" -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM mt7601u -+ -+#define MAXNAME 32 -+#define DEV_ENTRY __array(char, wiphy_name, 32) -+#define DEV_ASSIGN strlcpy(__entry->wiphy_name, \ -+ wiphy_name(dev->hw->wiphy), MAXNAME) -+#define DEV_PR_FMT "%s " -+#define DEV_PR_ARG __entry->wiphy_name -+ -+#define REG_ENTRY __field(u32, reg) __field(u32, val) -+#define REG_ASSIGN __entry->reg = reg; __entry->val = val -+#define REG_PR_FMT "%04x=%08x" -+#define REG_PR_ARG __entry->reg, __entry->val -+ -+DECLARE_EVENT_CLASS(dev_reg_evt, -+ TP_PROTO(struct mt7601u_dev *dev, u32 reg, u32 val), -+ TP_ARGS(dev, reg, val), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ REG_ENTRY -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ REG_ASSIGN; -+ ), -+ TP_printk( -+ DEV_PR_FMT REG_PR_FMT, -+ DEV_PR_ARG, REG_PR_ARG -+ ) -+); -+ -+DEFINE_EVENT(dev_reg_evt, reg_read, -+ TP_PROTO(struct mt7601u_dev *dev, u32 reg, u32 val), -+ TP_ARGS(dev, reg, val) -+); -+ -+DEFINE_EVENT(dev_reg_evt, reg_write, -+ TP_PROTO(struct mt7601u_dev *dev, u32 reg, u32 val), -+ TP_ARGS(dev, reg, val) -+); -+ -+TRACE_EVENT(mt_submit_urb, -+ TP_PROTO(struct mt7601u_dev *dev, struct urb *u), -+ TP_ARGS(dev, u), -+ TP_STRUCT__entry( -+ DEV_ENTRY __field(unsigned, pipe) __field(u32, len) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->pipe = u->pipe; -+ __entry->len = u->transfer_buffer_length; -+ ), -+ TP_printk(DEV_PR_FMT "p:%08x len:%u", -+ DEV_PR_ARG, __entry->pipe, __entry->len) -+); -+ -+#define trace_mt_submit_urb_sync(__dev, __pipe, __len) ({ \ -+ struct urb u; \ -+ u.pipe = __pipe; \ -+ u.transfer_buffer_length = __len; \ -+ trace_mt_submit_urb(__dev, &u); \ -+}) -+ -+TRACE_EVENT(mt_mcu_msg_send, -+ TP_PROTO(struct mt7601u_dev *dev, -+ struct sk_buff *skb, u32 csum, bool resp), -+ TP_ARGS(dev, skb, csum, resp), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u32, info) -+ __field(u32, csum) -+ __field(bool, resp) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->info = *(u32 *)skb->data; -+ __entry->csum = csum; -+ __entry->resp = resp; -+ ), -+ TP_printk(DEV_PR_FMT "i:%08x c:%08x r:%d", -+ DEV_PR_ARG, __entry->info, __entry->csum, __entry->resp) -+); -+ -+TRACE_EVENT(mt_vend_req, -+ TP_PROTO(struct mt7601u_dev *dev, unsigned pipe, u8 req, u8 req_type, -+ u16 val, u16 offset, void *buf, size_t buflen, int ret), -+ TP_ARGS(dev, pipe, req, req_type, val, offset, buf, buflen, ret), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(unsigned, pipe) __field(u8, req) __field(u8, req_type) -+ __field(u16, val) __field(u16, offset) __field(void*, buf) -+ __field(int, buflen) __field(int, ret) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->pipe = pipe; -+ __entry->req = req; -+ __entry->req_type = req_type; -+ __entry->val = val; -+ __entry->offset = offset; -+ __entry->buf = buf; -+ __entry->buflen = buflen; -+ __entry->ret = ret; -+ ), -+ TP_printk(DEV_PR_FMT -+ "%d p:%08x req:%02hhx %02hhx val:%04hx %04hx buf:%d %d", -+ DEV_PR_ARG, __entry->ret, __entry->pipe, __entry->req, -+ __entry->req_type, __entry->val, __entry->offset, -+ !!__entry->buf, __entry->buflen) -+); -+ -+TRACE_EVENT(ee_read, -+ TP_PROTO(struct mt7601u_dev *dev, int offset, u16 val), -+ TP_ARGS(dev, offset, val), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(int, o) __field(u16, v) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->o = offset; -+ __entry->v = val; -+ ), -+ TP_printk(DEV_PR_FMT "%04x=%04x", DEV_PR_ARG, __entry->o, __entry->v) -+); -+ -+DECLARE_EVENT_CLASS(dev_rf_reg_evt, -+ TP_PROTO(struct mt7601u_dev *dev, u8 bank, u8 reg, u8 val), -+ TP_ARGS(dev, bank, reg, val), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u8, bank) -+ __field(u8, reg) -+ __field(u8, val) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ REG_ASSIGN; -+ __entry->bank = bank; -+ ), -+ TP_printk( -+ DEV_PR_FMT "%02hhx:%02hhx=%02hhx", -+ DEV_PR_ARG, __entry->bank, __entry->reg, __entry->val -+ ) -+); -+ -+DEFINE_EVENT(dev_rf_reg_evt, rf_read, -+ TP_PROTO(struct mt7601u_dev *dev, u8 bank, u8 reg, u8 val), -+ TP_ARGS(dev, bank, reg, val) -+); -+ -+DEFINE_EVENT(dev_rf_reg_evt, rf_write, -+ TP_PROTO(struct mt7601u_dev *dev, u8 bank, u8 reg, u8 val), -+ TP_ARGS(dev, bank, reg, val) -+); -+ -+DECLARE_EVENT_CLASS(dev_bbp_reg_evt, -+ TP_PROTO(struct mt7601u_dev *dev, u8 reg, u8 val), -+ TP_ARGS(dev, reg, val), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u8, reg) -+ __field(u8, val) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ REG_ASSIGN; -+ ), -+ TP_printk( -+ DEV_PR_FMT "%02hhx=%02hhx", -+ DEV_PR_ARG, __entry->reg, __entry->val -+ ) -+); -+ -+DEFINE_EVENT(dev_bbp_reg_evt, bbp_read, -+ TP_PROTO(struct mt7601u_dev *dev, u8 reg, u8 val), -+ TP_ARGS(dev, reg, val) -+); -+ -+DEFINE_EVENT(dev_bbp_reg_evt, bbp_write, -+ TP_PROTO(struct mt7601u_dev *dev, u8 reg, u8 val), -+ TP_ARGS(dev, reg, val) -+); -+ -+DECLARE_EVENT_CLASS(dev_simple_evt, -+ TP_PROTO(struct mt7601u_dev *dev, u8 val), -+ TP_ARGS(dev, val), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u8, val) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->val = val; -+ ), -+ TP_printk( -+ DEV_PR_FMT "%02hhx", DEV_PR_ARG, __entry->val -+ ) -+); -+ -+DEFINE_EVENT(dev_simple_evt, temp_mode, -+ TP_PROTO(struct mt7601u_dev *dev, u8 val), -+ TP_ARGS(dev, val) -+); -+ -+DEFINE_EVENT(dev_simple_evt, read_temp, -+ TP_PROTO(struct mt7601u_dev *dev, u8 val), -+ TP_ARGS(dev, val) -+); -+ -+DEFINE_EVENT(dev_simple_evt, freq_cal_adjust, -+ TP_PROTO(struct mt7601u_dev *dev, u8 val), -+ TP_ARGS(dev, val) -+); -+ -+TRACE_EVENT(freq_cal_offset, -+ TP_PROTO(struct mt7601u_dev *dev, u8 phy_mode, s8 freq_off), -+ TP_ARGS(dev, phy_mode, freq_off), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u8, phy_mode) -+ __field(s8, freq_off) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->phy_mode = phy_mode; -+ __entry->freq_off = freq_off; -+ ), -+ TP_printk(DEV_PR_FMT "phy:%02hhx off:%02hhx", -+ DEV_PR_ARG, __entry->phy_mode, __entry->freq_off) -+); -+ -+TRACE_EVENT(mt_rx, -+ TP_PROTO(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi, u32 f), -+ TP_ARGS(dev, rxwi, f), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field_struct(struct mt7601u_rxwi, rxwi) -+ __field(u32, fce_info) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->rxwi = *rxwi; -+ __entry->fce_info = f; -+ ), -+ TP_printk(DEV_PR_FMT "rxi:%08x ctl:%08x frag_sn:%04hx rate:%04hx " -+ "uknw:%02hhx z:%02hhx%02hhx%02hhx snr:%02hhx " -+ "ant:%02hhx gain:%02hhx freq_o:%02hhx " -+ "r:%08x ea:%08x fce:%08x", DEV_PR_ARG, -+ le32_to_cpu(__entry->rxwi.rxinfo), -+ le32_to_cpu(__entry->rxwi.ctl), -+ le16_to_cpu(__entry->rxwi.frag_sn), -+ le16_to_cpu(__entry->rxwi.rate), -+ __entry->rxwi.unknown, -+ __entry->rxwi.zero[0], __entry->rxwi.zero[1], -+ __entry->rxwi.zero[2], -+ __entry->rxwi.snr, __entry->rxwi.ant, -+ __entry->rxwi.gain, __entry->rxwi.freq_off, -+ __entry->rxwi.resv2, __entry->rxwi.expert_ant, -+ __entry->fce_info) -+); -+ -+TRACE_EVENT(mt_tx, -+ TP_PROTO(struct mt7601u_dev *dev, struct sk_buff *skb, -+ struct mt76_sta *sta, struct mt76_txwi *h), -+ TP_ARGS(dev, skb, sta, h), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field_struct(struct mt76_txwi, h) -+ __field(struct sk_buff *, skb) -+ __field(struct mt76_sta *, sta) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->h = *h; -+ __entry->skb = skb; -+ __entry->sta = sta; -+ ), -+ TP_printk(DEV_PR_FMT "skb:%p sta:%p flg:%04hx rate_ctl:%04hx " -+ "ack:%02hhx wcid:%02hhx len_ctl:%05hx", DEV_PR_ARG, -+ __entry->skb, __entry->sta, -+ le16_to_cpu(__entry->h.flags), -+ le16_to_cpu(__entry->h.rate_ctl), -+ __entry->h.ack_ctl, __entry->h.wcid, -+ le16_to_cpu(__entry->h.len_ctl)) -+); -+ -+TRACE_EVENT(mt_tx_dma_done, -+ TP_PROTO(struct mt7601u_dev *dev, struct sk_buff *skb), -+ TP_ARGS(dev, skb), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(struct sk_buff *, skb) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->skb = skb; -+ ), -+ TP_printk(DEV_PR_FMT "%p", DEV_PR_ARG, __entry->skb) -+); -+ -+TRACE_EVENT(mt_tx_status_cleaned, -+ TP_PROTO(struct mt7601u_dev *dev, int cleaned), -+ TP_ARGS(dev, cleaned), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(int, cleaned) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->cleaned = cleaned; -+ ), -+ TP_printk(DEV_PR_FMT "%d", DEV_PR_ARG, __entry->cleaned) -+); -+ -+TRACE_EVENT(mt_tx_status, -+ TP_PROTO(struct mt7601u_dev *dev, u32 stat1, u32 stat2), -+ TP_ARGS(dev, stat1, stat2), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u32, stat1) __field(u32, stat2) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->stat1 = stat1; -+ __entry->stat2 = stat2; -+ ), -+ TP_printk(DEV_PR_FMT "%08x %08x", -+ DEV_PR_ARG, __entry->stat1, __entry->stat2) -+); -+ -+TRACE_EVENT(mt_rx_dma_aggr, -+ TP_PROTO(struct mt7601u_dev *dev, int cnt, bool paged), -+ TP_ARGS(dev, cnt, paged), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u8, cnt) -+ __field(bool, paged) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->cnt = cnt; -+ __entry->paged = paged; -+ ), -+ TP_printk(DEV_PR_FMT "cnt:%d paged:%d", -+ DEV_PR_ARG, __entry->cnt, __entry->paged) -+); -+ -+DEFINE_EVENT(dev_simple_evt, set_key, -+ TP_PROTO(struct mt7601u_dev *dev, u8 val), -+ TP_ARGS(dev, val) -+); -+ -+TRACE_EVENT(set_shared_key, -+ TP_PROTO(struct mt7601u_dev *dev, u8 vid, u8 key), -+ TP_ARGS(dev, vid, key), -+ TP_STRUCT__entry( -+ DEV_ENTRY -+ __field(u8, vid) -+ __field(u8, key) -+ ), -+ TP_fast_assign( -+ DEV_ASSIGN; -+ __entry->vid = vid; -+ __entry->key = key; -+ ), -+ TP_printk(DEV_PR_FMT "phy:%02hhx off:%02hhx", -+ DEV_PR_ARG, __entry->vid, __entry->key) -+); -+ -+#endif -+ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#undef TRACE_INCLUDE_FILE -+#define TRACE_INCLUDE_FILE trace -+ -+#include -diff --git a/drivers/net/wireless/mediatek/mt7601u/tx.c b/drivers/net/wireless/mediatek/mt7601u/tx.c -new file mode 100644 -index 0000000..0be2080 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/tx.c -@@ -0,0 +1,319 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+#include "trace.h" -+ -+enum mt76_txq_id { -+ MT_TXQ_VO = IEEE80211_AC_VO, -+ MT_TXQ_VI = IEEE80211_AC_VI, -+ MT_TXQ_BE = IEEE80211_AC_BE, -+ MT_TXQ_BK = IEEE80211_AC_BK, -+ MT_TXQ_PSD, -+ MT_TXQ_MCU, -+ __MT_TXQ_MAX -+}; -+ -+/* Hardware uses mirrored order of queues with Q0 having the highest priority */ -+static u8 q2hwq(u8 q) -+{ -+ return q ^ 0x3; -+} -+ -+/* Take mac80211 Q id from the skb and translate it to hardware Q id */ -+static u8 skb2q(struct sk_buff *skb) -+{ -+ int qid = skb_get_queue_mapping(skb); -+ -+ if (WARN_ON(qid >= MT_TXQ_PSD)) { -+ qid = MT_TXQ_BE; -+ skb_set_queue_mapping(skb, qid); -+ } -+ -+ return q2hwq(qid); -+} -+ -+/* Note: TX retry reporting is a bit broken. -+ * Retries are reported only once per AMPDU and often come a frame early -+ * i.e. they are reported in the last status preceding the AMPDU. Apart -+ * from the fact that it's hard to know the length of the AMPDU (which is -+ * required to know to how many consecutive frames retries should be -+ * applied), if status comes early on full FIFO it gets lost and retries -+ * of the whole AMPDU become invisible. -+ * As a work-around encode the desired rate in PKT_ID of TX descriptor -+ * and based on that guess the retries (every rate is tried once). -+ * Only downside here is that for MCS0 we have to rely solely on -+ * transmission failures as no retries can ever be reported. -+ * Not having to read EXT_FIFO has a nice effect of doubling the number -+ * of reports which can be fetched. -+ * Also the vendor driver never uses the EXT_FIFO register so it may be -+ * undertested. -+ */ -+static u8 mt7601u_tx_pktid_enc(struct mt7601u_dev *dev, u8 rate, bool is_probe) -+{ -+ u8 encoded = (rate + 1) + is_probe * 8; -+ -+ /* Because PKT_ID 0 disables status reporting only 15 values are -+ * available but 16 are needed (8 MCS * 2 for encoding is_probe) -+ * - we need to cram together two rates. MCS0 and MCS7 with is_probe -+ * share PKT_ID 9. -+ */ -+ if (is_probe && rate == 7) -+ return encoded - 7; -+ -+ return encoded; -+} -+ -+static void -+mt7601u_tx_pktid_dec(struct mt7601u_dev *dev, struct mt76_tx_status *stat) -+{ -+ u8 req_rate = stat->pktid; -+ u8 eff_rate = stat->rate & 0x7; -+ -+ req_rate -= 1; -+ -+ if (req_rate > 7) { -+ stat->is_probe = true; -+ req_rate -= 8; -+ -+ /* Decide between MCS0 and MCS7 which share pktid 9 */ -+ if (!req_rate && eff_rate) -+ req_rate = 7; -+ } -+ -+ stat->retry = req_rate - eff_rate; -+} -+ -+static void mt7601u_tx_skb_remove_dma_overhead(struct sk_buff *skb, -+ struct ieee80211_tx_info *info) -+{ -+ int pkt_len = (unsigned long)info->status.status_driver_data[0]; -+ -+ skb_pull(skb, sizeof(struct mt76_txwi) + 4); -+ if (ieee80211_get_hdrlen_from_skb(skb) % 4) -+ mt76_remove_hdr_pad(skb); -+ -+ skb_trim(skb, pkt_len); -+} -+ -+void mt7601u_tx_status(struct mt7601u_dev *dev, struct sk_buff *skb) -+{ -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ -+ mt7601u_tx_skb_remove_dma_overhead(skb, info); -+ -+ ieee80211_tx_info_clear_status(info); -+ info->status.rates[0].idx = -1; -+ info->flags |= IEEE80211_TX_STAT_ACK; -+ ieee80211_tx_status(dev->hw, skb); -+} -+ -+static int mt7601u_skb_rooms(struct mt7601u_dev *dev, struct sk_buff *skb) -+{ -+ int hdr_len = ieee80211_get_hdrlen_from_skb(skb); -+ u32 need_head; -+ -+ need_head = sizeof(struct mt76_txwi) + 4; -+ if (hdr_len % 4) -+ need_head += 2; -+ -+ return skb_cow(skb, need_head); -+} -+ -+static struct mt76_txwi * -+mt7601u_push_txwi(struct mt7601u_dev *dev, struct sk_buff *skb, -+ struct ieee80211_sta *sta, struct mt76_wcid *wcid, -+ int pkt_len) -+{ -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_tx_rate *rate = &info->control.rates[0]; -+ struct mt76_txwi *txwi; -+ unsigned long flags; -+ bool is_probe; -+ u32 pkt_id; -+ u16 rate_ctl; -+ u8 nss; -+ -+ txwi = (struct mt76_txwi *)skb_push(skb, sizeof(struct mt76_txwi)); -+ memset(txwi, 0, sizeof(*txwi)); -+ -+ if (!wcid->tx_rate_set) -+ ieee80211_get_tx_rates(info->control.vif, sta, skb, -+ info->control.rates, 1); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ if (rate->idx < 0 || !rate->count) -+ rate_ctl = wcid->tx_rate; -+ else -+ rate_ctl = mt76_mac_tx_rate_val(dev, rate, &nss); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ txwi->rate_ctl = cpu_to_le16(rate_ctl); -+ -+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) -+ txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; -+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) -+ txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; -+ -+ if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { -+ u8 ba_size = IEEE80211_MIN_AMPDU_BUF; -+ -+ ba_size <<= sta->ht_cap.ampdu_factor; -+ ba_size = min_t(int, 63, ba_size); -+ if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) -+ ba_size = 0; -+ txwi->ack_ctl |= MT76_SET(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); -+ -+ txwi->flags = cpu_to_le16(MT_TXWI_FLAGS_AMPDU | -+ MT76_SET(MT_TXWI_FLAGS_MPDU_DENSITY, -+ sta->ht_cap.ampdu_density)); -+ if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) -+ txwi->flags = 0; -+ } -+ -+ txwi->wcid = wcid->idx; -+ -+ is_probe = !!(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); -+ pkt_id = mt7601u_tx_pktid_enc(dev, rate_ctl & 0x7, is_probe); -+ pkt_len |= MT76_SET(MT_TXWI_LEN_PKTID, pkt_id); -+ txwi->len_ctl = cpu_to_le16(pkt_len); -+ -+ return txwi; -+} -+ -+void mt7601u_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, -+ struct sk_buff *skb) -+{ -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct mt7601u_dev *dev = hw->priv; -+ struct ieee80211_vif *vif = info->control.vif; -+ struct ieee80211_sta *sta = control->sta; -+ struct mt76_sta *msta = NULL; -+ struct mt76_wcid *wcid = dev->mon_wcid; -+ struct mt76_txwi *txwi; -+ int pkt_len = skb->len; -+ int hw_q = skb2q(skb); -+ -+ BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); -+ info->status.status_driver_data[0] = (void *)(unsigned long)pkt_len; -+ -+ if (mt7601u_skb_rooms(dev, skb) || mt76_insert_hdr_pad(skb)) { -+ ieee80211_free_txskb(dev->hw, skb); -+ return; -+ } -+ -+ if (sta) { -+ msta = (struct mt76_sta *) sta->drv_priv; -+ wcid = &msta->wcid; -+ } else if (vif) { -+ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; -+ -+ wcid = &mvif->group_wcid; -+ } -+ -+ txwi = mt7601u_push_txwi(dev, skb, sta, wcid, pkt_len); -+ -+ if (mt7601u_dma_enqueue_tx(dev, skb, wcid, hw_q)) -+ return; -+ -+ trace_mt_tx(dev, skb, msta, txwi); -+} -+ -+void mt7601u_tx_stat(struct work_struct *work) -+{ -+ struct mt7601u_dev *dev = container_of(work, struct mt7601u_dev, -+ stat_work.work); -+ struct mt76_tx_status stat; -+ unsigned long flags; -+ int cleaned = 0; -+ -+ while (!test_bit(MT7601U_STATE_REMOVED, &dev->state)) { -+ stat = mt7601u_mac_fetch_tx_status(dev); -+ if (!stat.valid) -+ break; -+ -+ mt7601u_tx_pktid_dec(dev, &stat); -+ mt76_send_tx_status(dev, &stat); -+ -+ cleaned++; -+ } -+ trace_mt_tx_status_cleaned(dev, cleaned); -+ -+ spin_lock_irqsave(&dev->tx_lock, flags); -+ if (cleaned) -+ queue_delayed_work(dev->stat_wq, &dev->stat_work, -+ msecs_to_jiffies(10)); -+ else if (test_and_clear_bit(MT7601U_STATE_MORE_STATS, &dev->state)) -+ queue_delayed_work(dev->stat_wq, &dev->stat_work, -+ msecs_to_jiffies(20)); -+ else -+ clear_bit(MT7601U_STATE_READING_STATS, &dev->state); -+ spin_unlock_irqrestore(&dev->tx_lock, flags); -+} -+ -+int mt7601u_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ u16 queue, const struct ieee80211_tx_queue_params *params) -+{ -+ struct mt7601u_dev *dev = hw->priv; -+ u8 cw_min = 5, cw_max = 10, hw_q = q2hwq(queue); -+ u32 val; -+ -+ /* TODO: should we do funny things with the parameters? -+ * See what mt7601u_set_default_edca() used to do in init.c. -+ */ -+ -+ if (params->cw_min) -+ cw_min = fls(params->cw_min); -+ if (params->cw_max) -+ cw_max = fls(params->cw_max); -+ -+ WARN_ON(params->txop > 0xff); -+ WARN_ON(params->aifs > 0xf); -+ WARN_ON(cw_min > 0xf); -+ WARN_ON(cw_max > 0xf); -+ -+ val = MT76_SET(MT_EDCA_CFG_AIFSN, params->aifs) | -+ MT76_SET(MT_EDCA_CFG_CWMIN, cw_min) | -+ MT76_SET(MT_EDCA_CFG_CWMAX, cw_max); -+ /* TODO: based on user-controlled EnableTxBurst var vendor drv sets -+ * a really long txop on AC0 (see connect.c:2009) but only on -+ * connect? When not connected should be 0. -+ */ -+ if (!hw_q) -+ val |= 0x60; -+ else -+ val |= MT76_SET(MT_EDCA_CFG_TXOP, params->txop); -+ mt76_wr(dev, MT_EDCA_CFG_AC(hw_q), val); -+ -+ val = mt76_rr(dev, MT_WMM_TXOP(hw_q)); -+ val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(hw_q)); -+ val |= params->txop << MT_WMM_TXOP_SHIFT(hw_q); -+ mt76_wr(dev, MT_WMM_TXOP(hw_q), val); -+ -+ val = mt76_rr(dev, MT_WMM_AIFSN); -+ val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(hw_q)); -+ val |= params->aifs << MT_WMM_AIFSN_SHIFT(hw_q); -+ mt76_wr(dev, MT_WMM_AIFSN, val); -+ -+ val = mt76_rr(dev, MT_WMM_CWMIN); -+ val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(hw_q)); -+ val |= cw_min << MT_WMM_CWMIN_SHIFT(hw_q); -+ mt76_wr(dev, MT_WMM_CWMIN, val); -+ -+ val = mt76_rr(dev, MT_WMM_CWMAX); -+ val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(hw_q)); -+ val |= cw_max << MT_WMM_CWMAX_SHIFT(hw_q); -+ mt76_wr(dev, MT_WMM_CWMAX, val); -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/usb.c b/drivers/net/wireless/mediatek/mt7601u/usb.c -new file mode 100644 -index 0000000..54dba40 ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/usb.c -@@ -0,0 +1,367 @@ -+/* -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+ -+#include "mt7601u.h" -+#include "usb.h" -+#include "trace.h" -+ -+static struct usb_device_id mt7601u_device_table[] = { -+ { USB_DEVICE(0x0b05, 0x17d3) }, -+ { USB_DEVICE(0x0e8d, 0x760a) }, -+ { USB_DEVICE(0x0e8d, 0x760b) }, -+ { USB_DEVICE(0x13d3, 0x3431) }, -+ { USB_DEVICE(0x13d3, 0x3434) }, -+ { USB_DEVICE(0x148f, 0x7601) }, -+ { USB_DEVICE(0x148f, 0x760a) }, -+ { USB_DEVICE(0x148f, 0x760b) }, -+ { USB_DEVICE(0x148f, 0x760c) }, -+ { USB_DEVICE(0x148f, 0x760d) }, -+ { USB_DEVICE(0x2001, 0x3d04) }, -+ { USB_DEVICE(0x2717, 0x4106) }, -+ { USB_DEVICE(0x2955, 0x0001) }, -+ { USB_DEVICE(0x2955, 0x1001) }, -+ { USB_DEVICE(0x2a5f, 0x1000) }, -+ { USB_DEVICE(0x7392, 0x7710) }, -+ { 0, } -+}; -+ -+bool mt7601u_usb_alloc_buf(struct mt7601u_dev *dev, size_t len, -+ struct mt7601u_dma_buf *buf) -+{ -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ -+ buf->len = len; -+ buf->urb = usb_alloc_urb(0, GFP_KERNEL); -+ buf->buf = usb_alloc_coherent(usb_dev, buf->len, GFP_KERNEL, &buf->dma); -+ -+ return !buf->urb || !buf->buf; -+} -+ -+void mt7601u_usb_free_buf(struct mt7601u_dev *dev, struct mt7601u_dma_buf *buf) -+{ -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ -+ usb_free_coherent(usb_dev, buf->len, buf->buf, buf->dma); -+ usb_free_urb(buf->urb); -+} -+ -+int mt7601u_usb_submit_buf(struct mt7601u_dev *dev, int dir, int ep_idx, -+ struct mt7601u_dma_buf *buf, gfp_t gfp, -+ usb_complete_t complete_fn, void *context) -+{ -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ unsigned pipe; -+ int ret; -+ -+ if (dir == USB_DIR_IN) -+ pipe = usb_rcvbulkpipe(usb_dev, dev->in_eps[ep_idx]); -+ else -+ pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[ep_idx]); -+ -+ usb_fill_bulk_urb(buf->urb, usb_dev, pipe, buf->buf, buf->len, -+ complete_fn, context); -+ buf->urb->transfer_dma = buf->dma; -+ buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -+ -+ trace_mt_submit_urb(dev, buf->urb); -+ ret = usb_submit_urb(buf->urb, gfp); -+ if (ret) -+ dev_err(dev->dev, "Error: submit URB dir:%d ep:%d failed:%d\n", -+ dir, ep_idx, ret); -+ return ret; -+} -+ -+void mt7601u_complete_urb(struct urb *urb) -+{ -+ struct completion *cmpl = urb->context; -+ -+ complete(cmpl); -+} -+ -+static int -+__mt7601u_vendor_request(struct mt7601u_dev *dev, const u8 req, -+ const u8 direction, const u16 val, const u16 offset, -+ void *buf, const size_t buflen) -+{ -+ int i, ret; -+ struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); -+ const u8 req_type = direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE; -+ const unsigned int pipe = (direction == USB_DIR_IN) ? -+ usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); -+ -+ for (i = 0; i < MT_VEND_REQ_MAX_RETRY; i++) { -+ ret = usb_control_msg(usb_dev, pipe, req, req_type, -+ val, offset, buf, buflen, -+ MT_VEND_REQ_TOUT_MS); -+ trace_mt_vend_req(dev, pipe, req, req_type, val, offset, -+ buf, buflen, ret); -+ -+ if (ret >= 0 || ret == -ENODEV) -+ return ret; -+ -+ msleep(5); -+ } -+ -+ dev_err(dev->dev, "Vendor request req:%02x off:%04x failed:%d\n", -+ req, offset, ret); -+ -+ return ret; -+} -+ -+int -+mt7601u_vendor_request(struct mt7601u_dev *dev, const u8 req, -+ const u8 direction, const u16 val, const u16 offset, -+ void *buf, const size_t buflen) -+{ -+ int ret; -+ -+ mutex_lock(&dev->vendor_req_mutex); -+ -+ ret = __mt7601u_vendor_request(dev, req, direction, val, offset, -+ buf, buflen); -+ if (ret == -ENODEV) -+ set_bit(MT7601U_STATE_REMOVED, &dev->state); -+ -+ mutex_unlock(&dev->vendor_req_mutex); -+ -+ return ret; -+} -+ -+void mt7601u_vendor_reset(struct mt7601u_dev *dev) -+{ -+ mt7601u_vendor_request(dev, MT_VEND_DEV_MODE, USB_DIR_OUT, -+ MT_VEND_DEV_MODE_RESET, 0, NULL, 0); -+} -+ -+u32 mt7601u_rr(struct mt7601u_dev *dev, u32 offset) -+{ -+ int ret; -+ __le32 reg; -+ u32 val; -+ -+ WARN_ONCE(offset > USHRT_MAX, "read high off:%08x", offset); -+ -+ ret = mt7601u_vendor_request(dev, MT_VEND_MULTI_READ, USB_DIR_IN, -+ 0, offset, ®, sizeof(reg)); -+ val = le32_to_cpu(reg); -+ if (ret > 0 && ret != sizeof(reg)) { -+ dev_err(dev->dev, "Error: wrong size read:%d off:%08x\n", -+ ret, offset); -+ val = ~0; -+ } -+ -+ trace_reg_read(dev, offset, val); -+ return val; -+} -+ -+int mt7601u_vendor_single_wr(struct mt7601u_dev *dev, const u8 req, -+ const u16 offset, const u32 val) -+{ -+ int ret; -+ -+ ret = mt7601u_vendor_request(dev, req, USB_DIR_OUT, -+ val & 0xffff, offset, NULL, 0); -+ if (ret) -+ return ret; -+ return mt7601u_vendor_request(dev, req, USB_DIR_OUT, -+ val >> 16, offset + 2, NULL, 0); -+} -+ -+void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val) -+{ -+ WARN_ONCE(offset > USHRT_MAX, "write high off:%08x", offset); -+ -+ mt7601u_vendor_single_wr(dev, MT_VEND_WRITE, offset, val); -+ trace_reg_write(dev, offset, val); -+} -+ -+u32 mt7601u_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val) -+{ -+ val |= mt7601u_rr(dev, offset) & ~mask; -+ mt7601u_wr(dev, offset, val); -+ return val; -+} -+ -+u32 mt7601u_rmc(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val) -+{ -+ u32 reg = mt7601u_rr(dev, offset); -+ -+ val |= reg & ~mask; -+ if (reg != val) -+ mt7601u_wr(dev, offset, val); -+ return val; -+} -+ -+void mt7601u_wr_copy(struct mt7601u_dev *dev, u32 offset, -+ const void *data, int len) -+{ -+ WARN_ONCE(offset & 3, "unaligned write copy off:%08x", offset); -+ WARN_ONCE(len & 3, "short write copy off:%08x", offset); -+ -+ mt7601u_burst_write_regs(dev, offset, data, len / 4); -+} -+ -+void mt7601u_addr_wr(struct mt7601u_dev *dev, const u32 offset, const u8 *addr) -+{ -+ mt7601u_wr(dev, offset, get_unaligned_le32(addr)); -+ mt7601u_wr(dev, offset + 4, addr[4] | addr[5] << 8); -+} -+ -+static int mt7601u_assign_pipes(struct usb_interface *usb_intf, -+ struct mt7601u_dev *dev) -+{ -+ struct usb_endpoint_descriptor *ep_desc; -+ struct usb_host_interface *intf_desc = usb_intf->cur_altsetting; -+ unsigned i, ep_i = 0, ep_o = 0; -+ -+ BUILD_BUG_ON(sizeof(dev->in_eps) < __MT_EP_IN_MAX); -+ BUILD_BUG_ON(sizeof(dev->out_eps) < __MT_EP_OUT_MAX); -+ -+ for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) { -+ ep_desc = &intf_desc->endpoint[i].desc; -+ -+ if (usb_endpoint_is_bulk_in(ep_desc) && -+ ep_i++ < __MT_EP_IN_MAX) { -+ dev->in_eps[ep_i - 1] = usb_endpoint_num(ep_desc); -+ dev->in_max_packet = usb_endpoint_maxp(ep_desc); -+ /* Note: this is ignored by usb sub-system but vendor -+ * code does it. We can drop this at some point. -+ */ -+ dev->in_eps[ep_i - 1] |= USB_DIR_IN; -+ } else if (usb_endpoint_is_bulk_out(ep_desc) && -+ ep_o++ < __MT_EP_OUT_MAX) { -+ dev->out_eps[ep_o - 1] = usb_endpoint_num(ep_desc); -+ dev->out_max_packet = usb_endpoint_maxp(ep_desc); -+ } -+ } -+ -+ if (ep_i != __MT_EP_IN_MAX || ep_o != __MT_EP_OUT_MAX) { -+ dev_err(dev->dev, "Error: wrong pipe number in:%d out:%d\n", -+ ep_i, ep_o); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int mt7601u_probe(struct usb_interface *usb_intf, -+ const struct usb_device_id *id) -+{ -+ struct usb_device *usb_dev = interface_to_usbdev(usb_intf); -+ struct mt7601u_dev *dev; -+ u32 asic_rev, mac_rev; -+ int ret; -+ -+ dev = mt7601u_alloc_device(&usb_intf->dev); -+ if (!dev) -+ return -ENOMEM; -+ -+ usb_dev = usb_get_dev(usb_dev); -+ usb_reset_device(usb_dev); -+ -+ usb_set_intfdata(usb_intf, dev); -+ -+ ret = mt7601u_assign_pipes(usb_intf, dev); -+ if (ret) -+ goto err; -+ ret = mt7601u_wait_asic_ready(dev); -+ if (ret) -+ goto err; -+ -+ asic_rev = mt7601u_rr(dev, MT_ASIC_VERSION); -+ mac_rev = mt7601u_rr(dev, MT_MAC_CSR0); -+ dev_info(dev->dev, "ASIC revision: %08x MAC revision: %08x\n", -+ asic_rev, mac_rev); -+ -+ /* Note: vendor driver skips this check for MT7601U */ -+ if (!(mt7601u_rr(dev, MT_EFUSE_CTRL) & MT_EFUSE_CTRL_SEL)) -+ dev_warn(dev->dev, "Warning: eFUSE not present\n"); -+ -+ ret = mt7601u_init_hardware(dev); -+ if (ret) -+ goto err; -+ ret = mt7601u_register_device(dev); -+ if (ret) -+ goto err_hw; -+ -+ set_bit(MT7601U_STATE_INITIALIZED, &dev->state); -+ -+ return 0; -+err_hw: -+ mt7601u_cleanup(dev); -+err: -+ usb_set_intfdata(usb_intf, NULL); -+ usb_put_dev(interface_to_usbdev(usb_intf)); -+ -+ destroy_workqueue(dev->stat_wq); -+ ieee80211_free_hw(dev->hw); -+ return ret; -+} -+ -+static void mt7601u_disconnect(struct usb_interface *usb_intf) -+{ -+ struct mt7601u_dev *dev = usb_get_intfdata(usb_intf); -+ -+ ieee80211_unregister_hw(dev->hw); -+ mt7601u_cleanup(dev); -+ -+ usb_set_intfdata(usb_intf, NULL); -+ usb_put_dev(interface_to_usbdev(usb_intf)); -+ -+ destroy_workqueue(dev->stat_wq); -+ ieee80211_free_hw(dev->hw); -+} -+ -+static int mt7601u_suspend(struct usb_interface *usb_intf, pm_message_t state) -+{ -+ struct mt7601u_dev *dev = usb_get_intfdata(usb_intf); -+ -+ mt7601u_cleanup(dev); -+ -+ return 0; -+} -+ -+static int mt7601u_resume(struct usb_interface *usb_intf) -+{ -+ struct mt7601u_dev *dev = usb_get_intfdata(usb_intf); -+ int ret; -+ -+ ret = mt7601u_init_hardware(dev); -+ if (ret) -+ return ret; -+ -+ set_bit(MT7601U_STATE_INITIALIZED, &dev->state); -+ -+ return 0; -+} -+ -+MODULE_DEVICE_TABLE(usb, mt7601u_device_table); -+MODULE_FIRMWARE(MT7601U_FIRMWARE); -+MODULE_LICENSE("GPL"); -+ -+static struct usb_driver mt7601u_driver = { -+ .name = KBUILD_MODNAME, -+ .id_table = mt7601u_device_table, -+ .probe = mt7601u_probe, -+ .disconnect = mt7601u_disconnect, -+ .suspend = mt7601u_suspend, -+ .resume = mt7601u_resume, -+ .reset_resume = mt7601u_resume, -+ .soft_unbind = 1, -+ .disable_hub_initiated_lpm = 1, -+}; -+module_usb_driver(mt7601u_driver); -diff --git a/drivers/net/wireless/mediatek/mt7601u/usb.h b/drivers/net/wireless/mediatek/mt7601u/usb.h -new file mode 100644 -index 0000000..49e188f ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/usb.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (C) 2015 Jakub Kicinski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT7601U_USB_H -+#define __MT7601U_USB_H -+ -+#include "mt7601u.h" -+ -+#define MT7601U_FIRMWARE "mt7601u.bin" -+ -+#define MT_VEND_REQ_MAX_RETRY 10 -+#define MT_VEND_REQ_TOUT_MS 300 -+ -+#define MT_VEND_DEV_MODE_RESET 1 -+ -+enum mt_vendor_req { -+ MT_VEND_DEV_MODE = 1, -+ MT_VEND_WRITE = 2, -+ MT_VEND_MULTI_READ = 7, -+ MT_VEND_WRITE_FCE = 0x42, -+}; -+ -+enum mt_usb_ep_in { -+ MT_EP_IN_PKT_RX, -+ MT_EP_IN_CMD_RESP, -+ __MT_EP_IN_MAX, -+}; -+ -+enum mt_usb_ep_out { -+ MT_EP_OUT_INBAND_CMD, -+ MT_EP_OUT_AC_BK, -+ MT_EP_OUT_AC_BE, -+ MT_EP_OUT_AC_VI, -+ MT_EP_OUT_AC_VO, -+ MT_EP_OUT_HCCA, -+ __MT_EP_OUT_MAX, -+}; -+ -+static inline struct usb_device *mt7601u_to_usb_dev(struct mt7601u_dev *mt7601u) -+{ -+ return interface_to_usbdev(to_usb_interface(mt7601u->dev)); -+} -+ -+static inline bool mt7601u_urb_has_error(struct urb *urb) -+{ -+ return urb->status && -+ urb->status != -ENOENT && -+ urb->status != -ECONNRESET && -+ urb->status != -ESHUTDOWN; -+} -+ -+bool mt7601u_usb_alloc_buf(struct mt7601u_dev *dev, size_t len, -+ struct mt7601u_dma_buf *buf); -+void mt7601u_usb_free_buf(struct mt7601u_dev *dev, struct mt7601u_dma_buf *buf); -+int mt7601u_usb_submit_buf(struct mt7601u_dev *dev, int dir, int ep_idx, -+ struct mt7601u_dma_buf *buf, gfp_t gfp, -+ usb_complete_t complete_fn, void *context); -+void mt7601u_complete_urb(struct urb *urb); -+ -+int mt7601u_vendor_request(struct mt7601u_dev *dev, const u8 req, -+ const u8 direction, const u16 val, const u16 offset, -+ void *buf, const size_t buflen); -+void mt7601u_vendor_reset(struct mt7601u_dev *dev); -+int mt7601u_vendor_single_wr(struct mt7601u_dev *dev, const u8 req, -+ const u16 offset, const u32 val); -+ -+#endif -diff --git a/drivers/net/wireless/mediatek/mt7601u/util.c b/drivers/net/wireless/mediatek/mt7601u/util.c -new file mode 100644 -index 0000000..7c1787c ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/util.c -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "mt7601u.h" -+ -+void mt76_remove_hdr_pad(struct sk_buff *skb) -+{ -+ int len = ieee80211_get_hdrlen_from_skb(skb); -+ -+ memmove(skb->data + 2, skb->data, len); -+ skb_pull(skb, 2); -+} -+ -+int mt76_insert_hdr_pad(struct sk_buff *skb) -+{ -+ int len = ieee80211_get_hdrlen_from_skb(skb); -+ int ret; -+ -+ if (len % 4 == 0) -+ return 0; -+ -+ ret = skb_cow(skb, 2); -+ if (ret) -+ return ret; -+ -+ skb_push(skb, 2); -+ memmove(skb->data, skb->data + 2, len); -+ -+ skb->data[len] = 0; -+ skb->data[len + 1] = 0; -+ return 0; -+} -diff --git a/drivers/net/wireless/mediatek/mt7601u/util.h b/drivers/net/wireless/mediatek/mt7601u/util.h -new file mode 100644 -index 0000000..b89140b ---- /dev/null -+++ b/drivers/net/wireless/mediatek/mt7601u/util.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2004 - 2009 Ivo van Doorn -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT76_UTIL_H -+#define __MT76_UTIL_H -+ -+/* -+ * Power of two check, this will check -+ * if the mask that has been given contains and contiguous set of bits. -+ * Note that we cannot use the is_power_of_2() function since this -+ * check must be done at compile-time. -+ */ -+#define is_power_of_two(x) ( !((x) & ((x)-1)) ) -+#define low_bit_mask(x) ( ((x)-1) & ~(x) ) -+#define is_valid_mask(x) is_power_of_two(1LU + (x) + low_bit_mask(x)) -+ -+/* -+ * Macros to find first set bit in a variable. -+ * These macros behave the same as the __ffs() functions but -+ * the most important difference that this is done during -+ * compile-time rather then run-time. -+ */ -+#define compile_ffs2(__x) \ -+ __builtin_choose_expr(((__x) & 0x1), 0, 1) -+ -+#define compile_ffs4(__x) \ -+ __builtin_choose_expr(((__x) & 0x3), \ -+ (compile_ffs2((__x))), \ -+ (compile_ffs2((__x) >> 2) + 2)) -+ -+#define compile_ffs8(__x) \ -+ __builtin_choose_expr(((__x) & 0xf), \ -+ (compile_ffs4((__x))), \ -+ (compile_ffs4((__x) >> 4) + 4)) -+ -+#define compile_ffs16(__x) \ -+ __builtin_choose_expr(((__x) & 0xff), \ -+ (compile_ffs8((__x))), \ -+ (compile_ffs8((__x) >> 8) + 8)) -+ -+#define compile_ffs32(__x) \ -+ __builtin_choose_expr(((__x) & 0xffff), \ -+ (compile_ffs16((__x))), \ -+ (compile_ffs16((__x) >> 16) + 16)) -+ -+/* -+ * This macro will check the requirements for the FIELD{8,16,32} macros -+ * The mask should be a constant non-zero contiguous set of bits which -+ * does not exceed the given typelimit. -+ */ -+#define FIELD_CHECK(__mask) \ -+ BUILD_BUG_ON(!(__mask) || !is_valid_mask(__mask)) -+ -+#define MT76_SET(_mask, _val) \ -+ ({ \ -+ FIELD_CHECK(_mask); \ -+ (((u32) (_val)) << compile_ffs32(_mask)) & _mask; \ -+ }) -+ -+#define MT76_GET(_mask, _val) \ -+ ({ \ -+ FIELD_CHECK(_mask); \ -+ (u32) (((_val) & _mask) >> compile_ffs32(_mask)); \ -+ }) -+ -+#endif diff --git a/packages/linux/patches/4.1.12/linux-003-no_dev_console.patch b/packages/linux/patches/4.3/linux-003-no_dev_console.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-003-no_dev_console.patch rename to packages/linux/patches/4.3/linux-003-no_dev_console.patch diff --git a/packages/linux/patches/4.3/linux-004-fix-build-with-gcc-5.patch b/packages/linux/patches/4.3/linux-004-fix-build-with-gcc-5.patch new file mode 100644 index 0000000000..b2e8d91d38 --- /dev/null +++ b/packages/linux/patches/4.3/linux-004-fix-build-with-gcc-5.patch @@ -0,0 +1,16 @@ +# see https://github.com/wongsyrone/openwrt-1/commit/93c0a5173414cfa7684547de3c3a1f3dc4240383 +# and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932 + +diff -Naur linux-4.3-rc5.orig/arch/arm/Makefile linux-4.3-rc5/arch/arm/Makefile +--- linux-4.3-rc5.orig/arch/arm/Makefile 2015-10-11 11:09:45.000000000 -0700 ++++ linux-4.3-rc5/arch/arm/Makefile 2015-10-20 12:24:44.507102957 -0700 +@@ -130,7 +130,8 @@ + endif + + # Need -Uarm for gcc < 3.x +-KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm ++# Maybe we need -fno-ipa-sra for gcc > 4.9.x ++KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm -fno-ipa-sra + KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float + + CHECKFLAGS += -D__arm__ diff --git a/packages/linux/patches/4.1.12/linux-051-ouya_controller_support.patch b/packages/linux/patches/4.3/linux-051-ouya_controller_support.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-051-ouya_controller_support.patch rename to packages/linux/patches/4.3/linux-051-ouya_controller_support.patch diff --git a/packages/linux/patches/4.1.12/linux-052-XBOX_remote_support.patch b/packages/linux/patches/4.3/linux-052-XBOX_remote_support.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-052-XBOX_remote_support.patch rename to packages/linux/patches/4.3/linux-052-XBOX_remote_support.patch diff --git a/packages/linux/patches/4.1.12/linux-053-spinelplus-remote-0.2.patch b/packages/linux/patches/4.3/linux-053-spinelplus-remote-0.2.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-053-spinelplus-remote-0.2.patch rename to packages/linux/patches/4.3/linux-053-spinelplus-remote-0.2.patch diff --git a/packages/linux/patches/4.1.12/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch b/packages/linux/patches/4.3/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch rename to packages/linux/patches/4.3/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch diff --git a/packages/linux/patches/4.1.12/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch b/packages/linux/patches/4.3/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch rename to packages/linux/patches/4.3/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch diff --git a/packages/linux/patches/4.1.12/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch b/packages/linux/patches/4.3/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch rename to packages/linux/patches/4.3/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch diff --git a/packages/linux/patches/4.1.12/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch b/packages/linux/patches/4.3/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch rename to packages/linux/patches/4.3/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch diff --git a/packages/linux/patches/4.1.12/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch b/packages/linux/patches/4.3/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch similarity index 78% rename from packages/linux/patches/4.1.12/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch rename to packages/linux/patches/4.3/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch index 6fa866dfe8..c3d77a7028 100644 --- a/packages/linux/patches/4.1.12/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch +++ b/packages/linux/patches/4.3/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch @@ -24,10 +24,14 @@ This compiled against the hid-sony driver with the PS3 remote changes merged, but I have done no testing of it. If the approach seems reasonable, I'll try to test it when the MythTV is idle. --- -diff -Naur linux-3.17.1/drivers/hid/hid-sony.c linux-3.17.1.patch/drivers/hid/hid-sony.c ---- linux-3.17.1/drivers/hid/hid-sony.c 2014-10-15 12:29:30.000000000 +0200 -+++ linux-3.17.1.patch/drivers/hid/hid-sony.c 2014-10-16 12:55:43.979181366 +0200 -@@ -875,6 +875,25 @@ + drivers/hid/hid-sony.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c +index 661f94f..2256e35 100644 +--- a/drivers/hid/hid-sony.c ++++ b/drivers/hid/hid-sony.c +@@ -1111,6 +1111,25 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, return 1; } @@ -53,12 +57,14 @@ diff -Naur linux-3.17.1/drivers/hid/hid-sony.c linux-3.17.1.patch/drivers/hid/hi static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { -@@ -1932,6 +1951,8 @@ - goto err_stop; - +@@ -2339,6 +2358,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) sony_init_work(sc, dualshock4_state_worker); + } else if (sc->quirks & MOTION_CONTROLLER) { + sony_init_work(sc, motion_state_worker); + } else if (sc->quirks & PS3REMOTE) { + ret = ps3remote_setup_repeat(hdev); } else { ret = 0; } +-- +1.9.1 diff --git a/packages/linux/patches/4.1.12/linux-062-imon_pad_ignore_diagonal.patch b/packages/linux/patches/4.3/linux-062-imon_pad_ignore_diagonal.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-062-imon_pad_ignore_diagonal.patch rename to packages/linux/patches/4.3/linux-062-imon_pad_ignore_diagonal.patch diff --git a/packages/linux/patches/4.1.12/linux-063-xpad-fix_xbox360_wireless.patch b/packages/linux/patches/4.3/linux-063-xpad-fix_xbox360_wireless.patch similarity index 63% rename from packages/linux/patches/4.1.12/linux-063-xpad-fix_xbox360_wireless.patch rename to packages/linux/patches/4.3/linux-063-xpad-fix_xbox360_wireless.patch index 11ffb9e7fa..d0c30cbb0e 100644 --- a/packages/linux/patches/4.1.12/linux-063-xpad-fix_xbox360_wireless.patch +++ b/packages/linux/patches/4.3/linux-063-xpad-fix_xbox360_wireless.patch @@ -1,6 +1,6 @@ -From 0f578b91219bd354a170eb53359336f67bbfda57 Mon Sep 17 00:00:00 2001 +From e99d241a9074888a6c1da714bcdd64c45cf19d3b Mon Sep 17 00:00:00 2001 From: Matt DeVillier -Date: Tue, 28 Jul 2015 11:19:40 -0500 +Date: Mon, 26 Oct 2015 18:02:08 -0500 Subject: [PATCH 1/1] linux/drivers/input/joystick/xpad: fixes for xbox360/one controllers merged from https://github.com/paroj/xpad @@ -14,14 +14,48 @@ merged from https://github.com/paroj/xpad Signed-off-by: Matt DeVillier --- - drivers/input/joystick/xpad.c | 647 +++++++++++++++++++++++++----------------- - 1 file changed, 387 insertions(+), 260 deletions(-) + drivers/input/joystick/xpad.c | 715 +++++++++++++++++++++++++----------------- + 1 file changed, 431 insertions(+), 284 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index 61c7611..afecd26 100644 +index f8850f9..3ba9914 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c -@@ -328,10 +328,8 @@ struct usb_xpad { +@@ -74,7 +74,7 @@ + * + * Later changes can be tracked in SCM. + */ +- ++#define DEBUG + #include + #include + #include +@@ -125,6 +125,7 @@ static const struct xpad_device { + { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, + { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, + { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, ++ { 0x045e, 0x02dd, "Microsoft X-Box One pad (Covert Forces)", 0, XTYPE_XBOXONE }, + { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, + { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, +@@ -204,7 +205,7 @@ static const struct xpad_device { + { 0x1bad, 0xf900, "Harmonix Xbox 360 Controller", 0, XTYPE_XBOX360 }, + { 0x1bad, 0xf901, "Gamestop Xbox 360 Controller", 0, XTYPE_XBOX360 }, + { 0x1bad, 0xf903, "Tron Xbox 360 controller", 0, XTYPE_XBOX360 }, +- { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", 0, XTYPE_XBOX360 }, ++ { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 }, + { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, + { 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo", 0, XTYPE_XBOX360 }, +@@ -242,7 +243,6 @@ static const signed short xpad_btn_triggers[] = { + -1 + }; + +- + static const signed short xpad360_btn[] = { /* buttons for x360 controller */ + BTN_TL, BTN_TR, /* Button LB/RB */ + BTN_MODE, /* The big X button */ +@@ -328,13 +328,17 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; @@ -32,26 +66,35 @@ index 61c7611..afecd26 100644 + int irq_out_active; /* we must not use an active URB */ unsigned char *odata; /* output data */ dma_addr_t odata_dma; - struct mutex odata_mutex; -@@ -344,8 +342,17 @@ struct usb_xpad { +- struct mutex odata_mutex; ++ spinlock_t odata_lock; ++ ++ unsigned char rum_odata[XPAD_PKT_LEN]; /* cache for rumble data */ ++ unsigned char led_odata[XPAD_PKT_LEN]; /* cache for led data */ ++ unsigned pend_rum; /* length of cached rumble data */ ++ unsigned pend_led; /* length of cached led data */ ++ int force_led; /* force send led cache next */ + + #if defined(CONFIG_JOYSTICK_XPAD_LEDS) + struct xpad_led *led; +@@ -344,9 +348,15 @@ struct usb_xpad { int mapping; /* map d-pad to buttons or to axes */ int xtype; /* type of xbox device */ -+ unsigned long pad_nr; /* the order x360 pads were attached */ +- unsigned long led_no; /* led to lit on xbox360 controllers */ ++ int pad_nr; /* the order x360 pads were attached */ + const char *name; /* name of the device */ + struct work_struct work; /* init/remove device from callback */ + unsigned char odata_serial; /* serial number for xbox one protocol */ }; -+static unsigned long xpad_pad_seq; -+ +static int xpad_init_input(struct usb_xpad *xpad); +static void xpad_deinit_input(struct usb_xpad *xpad); + /* * xpad_process_packet * -@@ -355,7 +362,6 @@ struct usb_xpad { +@@ -356,7 +366,6 @@ struct usb_xpad { * The used report descriptor was taken from ITO Takayukis website: * http://euc.jp/periphs/xbox-controller.ja.html */ @@ -59,28 +102,28 @@ index 61c7611..afecd26 100644 static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; -@@ -438,7 +444,14 @@ static void xpad360_process_packet(struct usb_xpad *xpad, +@@ -439,7 +448,16 @@ static void xpad360_process_packet(struct usb_xpad *xpad, input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); - } else { + } -+ /* this should be a simple else block. However historically xbox360w -+ * has mapped DPAD to buttons while xbox360 did not. -+ * This made no sense, but now we can not just switch back and have to ++ ++ /* ++ * This should be a simple else block. However historically ++ * xbox360w has mapped DPAD to buttons while xbox360 did not. This ++ * made no sense, but now we can not just switch back and have to + * support both behaviors. + */ + if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) || -+ xpad->xtype == XTYPE_XBOX360W) { ++ xpad->xtype == XTYPE_XBOX360W) { input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); input_report_abs(dev, ABS_HAT0Y, -@@ -488,6 +501,24 @@ static void xpad360_process_packet(struct usb_xpad *xpad, - input_sync(dev); - } +@@ -491,6 +509,22 @@ static void xpad360_process_packet(struct usb_xpad *xpad, + + static void xpad_identify_controller(struct usb_xpad *xpad); -+static void xpad_identify_controller(struct usb_xpad *xpad); -+ +static void presence_work_function(struct work_struct *work) +{ + struct usb_xpad *xpad = container_of(work, struct usb_xpad, work); @@ -100,7 +143,7 @@ index 61c7611..afecd26 100644 /* * xpad360w_process_packet * -@@ -502,16 +533,18 @@ static void xpad360_process_packet(struct usb_xpad *xpad, +@@ -505,21 +539,18 @@ static void xpad_identify_controller(struct usb_xpad *xpad); * 01.1 - Pad state (Bytes 4+) valid * */ @@ -114,6 +157,11 @@ index 61c7611..afecd26 100644 - if (data[1] & 0x80) { - xpad->pad_present = 1; - usb_submit_urb(xpad->bulk_out, GFP_ATOMIC); +- /* +- * Light up the segment corresponding to +- * controller number. +- */ +- xpad_identify_controller(xpad); - } else - xpad->pad_present = 0; + presence = (data[1] & 0x80) != 0; @@ -125,7 +173,7 @@ index 61c7611..afecd26 100644 } /* Valid pad data */ -@@ -666,28 +699,6 @@ exit: +@@ -674,40 +705,40 @@ exit: __func__, retval); } @@ -154,15 +202,42 @@ index 61c7611..afecd26 100644 static void xpad_irq_out(struct urb *urb) { struct usb_xpad *xpad = urb->context; -@@ -699,6 +710,7 @@ static void xpad_irq_out(struct urb *urb) + struct device *dev = &xpad->intf->dev; + int retval, status; ++ unsigned long flags; + + status = urb->status; + switch (status) { case 0: /* success */ -+ xpad->irq_out_active = 0; - return; +- return; ++ if(!xpad->pend_led && !xpad->pend_rum) { ++ xpad->irq_out_active = 0; ++ return; ++ } ++ ++ spin_lock_irqsave(&xpad->odata_lock, flags); ++ ++ if(xpad->pend_led && (!xpad->pend_rum || xpad->force_led)) { ++ xpad->irq_out->transfer_buffer_length = xpad->pend_led; ++ memcpy(xpad->odata, xpad->led_odata, xpad->pend_led); ++ xpad->pend_led = 0; ++ xpad->force_led = 0; ++ dev_dbg(dev, "%s - sending pending led\n", __func__); ++ break; ++ } ++ ++ xpad->irq_out->transfer_buffer_length = xpad->pend_rum; ++ memcpy(xpad->odata, xpad->rum_odata, xpad->pend_rum); ++ xpad->pend_rum = 0; ++ xpad->force_led = 1; ++ dev_dbg(dev, "%s - sending pending rumble\n", __func__); ++ break; case -ECONNRESET: -@@ -707,6 +719,7 @@ static void xpad_irq_out(struct urb *urb) + case -ENOENT: +@@ -715,16 +746,19 @@ static void xpad_irq_out(struct urb *urb) /* this urb is terminated, clean up */ dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status); @@ -170,7 +245,21 @@ index 61c7611..afecd26 100644 return; default: -@@ -726,7 +739,6 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) + dev_dbg(dev, "%s - nonzero urb status received: %d\n", + __func__, status); +- goto exit; ++ ++ spin_lock_irqsave(&xpad->odata_lock, flags); ++ break; + } + +-exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); ++ spin_unlock_irqrestore(&xpad->odata_lock, flags); + if (retval) + dev_err(dev, "%s - usb_submit_urb failed with result %d\n", + __func__, retval); +@@ -734,7 +768,6 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { struct usb_endpoint_descriptor *ep_irq_out; int ep_irq_out_idx; @@ -178,7 +267,7 @@ index 61c7611..afecd26 100644 if (xpad->xtype == XTYPE_UNKNOWN) return 0; -@@ -734,16 +746,15 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) +@@ -742,16 +775,18 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->odata_dma); if (!xpad->odata) { @@ -187,7 +276,11 @@ index 61c7611..afecd26 100644 + return -ENOMEM; } - mutex_init(&xpad->odata_mutex); +- mutex_init(&xpad->odata_mutex); ++ spin_lock_init(&xpad->odata_lock); ++ xpad->pend_led = 0; ++ xpad->pend_rum = 0; ++ xpad->force_led = 0; xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) { @@ -198,7 +291,7 @@ index 61c7611..afecd26 100644 } /* Xbox One controller has in/out endpoints swapped. */ -@@ -758,9 +769,6 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) +@@ -766,9 +801,6 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; return 0; @@ -208,13 +301,101 @@ index 61c7611..afecd26 100644 } static void xpad_stop_output(struct usb_xpad *xpad) -@@ -782,80 +790,94 @@ static void xpad_deinit_output(struct usb_xpad *xpad) +@@ -786,84 +818,143 @@ static void xpad_deinit_output(struct usb_xpad *xpad) + } + } + ++static int xpad_inquiry_pad_presence(struct usb_xpad *xpad) ++{ ++ int retval; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&xpad->odata_lock, flags); ++ ++ xpad->odata[0] = 0x08; ++ xpad->odata[1] = 0x00; ++ xpad->odata[2] = 0x0F; ++ xpad->odata[3] = 0xC0; ++ xpad->odata[4] = 0x00; ++ xpad->odata[5] = 0x00; ++ xpad->odata[6] = 0x00; ++ xpad->odata[7] = 0x00; ++ xpad->odata[8] = 0x00; ++ xpad->odata[9] = 0x00; ++ xpad->odata[10] = 0x00; ++ xpad->odata[11] = 0x00; ++ xpad->irq_out->transfer_buffer_length = 12; ++ ++ if (!xpad->irq_out_active) { ++ retval = usb_submit_urb(xpad->irq_out, GFP_KERNEL); ++ xpad->irq_out_active = 1; ++ } else { ++ dev_dbg(&xpad->dev->dev, "%s - dropped, irq_out is active\n", ++ __func__); ++ retval = -EIO; ++ } ++ ++ spin_unlock_irqrestore(&xpad->odata_lock, flags); ++ ++ return retval; ++} ++ + #ifdef CONFIG_JOYSTICK_XPAD_FF static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) { struct usb_xpad *xpad = input_get_drvdata(dev); + __u16 strong; + __u16 weak; + int retval; ++ ++ unsigned long flags; ++ ++ if (effect->type != FF_RUMBLE) ++ return 0; ++ ++ strong = effect->u.rumble.strong_magnitude; ++ weak = effect->u.rumble.weak_magnitude; ++ ++ spin_lock_irqsave(&xpad->odata_lock, flags); ++ ++ switch (xpad->xtype) { ++ case XTYPE_XBOX: ++ xpad->odata[0] = 0x00; ++ xpad->odata[1] = 0x06; ++ xpad->odata[2] = 0x00; ++ xpad->odata[3] = strong / 256; /* left actuator */ ++ xpad->odata[4] = 0x00; ++ xpad->odata[5] = weak / 256; /* right actuator */ ++ xpad->irq_out->transfer_buffer_length = 6; ++ break; ++ ++ case XTYPE_XBOX360: ++ xpad->odata[0] = 0x00; ++ xpad->odata[1] = 0x08; ++ xpad->odata[2] = 0x00; ++ xpad->odata[3] = strong / 256; /* left actuator? */ ++ xpad->odata[4] = weak / 256; /* right actuator? */ ++ xpad->odata[5] = 0x00; ++ xpad->odata[6] = 0x00; ++ xpad->odata[7] = 0x00; ++ xpad->irq_out->transfer_buffer_length = 8; ++ break; ++ ++ case XTYPE_XBOX360W: ++ xpad->odata[0] = 0x00; ++ xpad->odata[1] = 0x01; ++ xpad->odata[2] = 0x0F; ++ xpad->odata[3] = 0xC0; ++ xpad->odata[4] = 0x00; ++ xpad->odata[5] = strong / 256; ++ xpad->odata[6] = weak / 256; ++ xpad->odata[7] = 0x00; ++ xpad->odata[8] = 0x00; ++ xpad->odata[9] = 0x00; ++ xpad->odata[10] = 0x00; ++ xpad->odata[11] = 0x00; ++ xpad->irq_out->transfer_buffer_length = 12; ++ break; - if (effect->type == FF_RUMBLE) { - __u16 strong = effect->u.rumble.strong_magnitude; @@ -281,58 +462,6 @@ index 61c7611..afecd26 100644 - return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); - - default: -- dev_dbg(&xpad->dev->dev, -- "%s - rumble command sent to unsupported xpad type: %d\n", -- __func__, xpad->xtype); -- return -1; -- } -+ if (effect->type != FF_RUMBLE) -+ return 0; -+ -+ strong = effect->u.rumble.strong_magnitude; -+ weak = effect->u.rumble.weak_magnitude; -+ -+ mutex_lock(&xpad->odata_mutex); -+ -+ switch (xpad->xtype) { -+ case XTYPE_XBOX: -+ xpad->odata[0] = 0x00; -+ xpad->odata[1] = 0x06; -+ xpad->odata[2] = 0x00; -+ xpad->odata[3] = strong / 256; /* left actuator */ -+ xpad->odata[4] = 0x00; -+ xpad->odata[5] = weak / 256; /* right actuator */ -+ xpad->irq_out->transfer_buffer_length = 6; -+ break; -+ -+ case XTYPE_XBOX360: -+ xpad->odata[0] = 0x00; -+ xpad->odata[1] = 0x08; -+ xpad->odata[2] = 0x00; -+ xpad->odata[3] = strong / 256; /* left actuator? */ -+ xpad->odata[4] = weak / 256; /* right actuator? */ -+ xpad->odata[5] = 0x00; -+ xpad->odata[6] = 0x00; -+ xpad->odata[7] = 0x00; -+ xpad->irq_out->transfer_buffer_length = 8; -+ break; -+ -+ case XTYPE_XBOX360W: -+ xpad->odata[0] = 0x00; -+ xpad->odata[1] = 0x01; -+ xpad->odata[2] = 0x0F; -+ xpad->odata[3] = 0xC0; -+ xpad->odata[4] = 0x00; -+ xpad->odata[5] = strong / 256; -+ xpad->odata[6] = weak / 256; -+ xpad->odata[7] = 0x00; -+ xpad->odata[8] = 0x00; -+ xpad->odata[9] = 0x00; -+ xpad->odata[10] = 0x00; -+ xpad->odata[11] = 0x00; -+ xpad->irq_out->transfer_buffer_length = 12; -+ break; -+ + case XTYPE_XBOXONE: + xpad->odata[0] = 0x09; /* activate rumble */ + xpad->odata[1] = 0x08; @@ -351,169 +480,182 @@ index 61c7611..afecd26 100644 + break; + + default: -+ mutex_unlock(&xpad->odata_mutex); ++ spin_unlock_irqrestore(&xpad->odata_lock, flags); + dev_dbg(&xpad->dev->dev, + "%s - rumble command sent to unsupported xpad type: %d\n", + __func__, xpad->xtype); + return -EINVAL; - } - -- return 0; ++ } ++ + if (!xpad->irq_out_active) { + retval = usb_submit_urb(xpad->irq_out, GFP_ATOMIC); + xpad->irq_out_active = 1; + } else { -+ retval = -EIO; -+ dev_dbg(&xpad->dev->dev, "%s - dropped, irq_out is active\n", -+ __func__); -+ } ++ retval = 0; + -+ mutex_unlock(&xpad->odata_mutex); ++ if(xpad->pend_rum) { + dev_dbg(&xpad->dev->dev, +- "%s - rumble command sent to unsupported xpad type: %d\n", +- __func__, xpad->xtype); +- return -1; ++ "%s - overwriting pending\n", __func__); ++ ++ retval = -EIO; + } ++ ++ xpad->pend_rum = xpad->irq_out->transfer_buffer_length; ++ memcpy(xpad->rum_odata, xpad->odata, xpad->pend_rum); + } + +- return 0; ++ spin_unlock_irqrestore(&xpad->odata_lock, flags); + + return retval; } static int xpad_init_ff(struct usb_xpad *xpad) -@@ -881,17 +903,78 @@ struct xpad_led { - struct usb_xpad *xpad; +@@ -882,6 +973,9 @@ static int xpad_init_ff(struct usb_xpad *xpad) { return 0; } + + #if defined(CONFIG_JOYSTICK_XPAD_LEDS) + #include ++#include ++ ++static DEFINE_IDA(xpad_pad_seq); + + struct xpad_led { + char name[16]; +@@ -890,6 +984,7 @@ struct xpad_led { }; -+/** + /** + * set the LEDs on Xbox360 / Wireless Controllers -+ * @param command -+ * 0: off -+ * 1: all blink, then previous setting -+ * 2: 1/top-left blink, then on -+ * 3: 2/top-right blink, then on -+ * 4: 3/bottom-left blink, then on -+ * 5: 4/bottom-right blink, then on -+ * 6: 1/top-left on -+ * 7: 2/top-right on -+ * 8: 3/bottom-left on -+ * 9: 4/bottom-right on -+ * 10: rotate -+ * 11: blink, based on previous setting -+ * 12: slow blink, based on previous setting -+ * 13: rotate with two lights -+ * 14: persistent slow all blink -+ * 15: blink once, then previous setting -+ */ + * @param command + * 0: off + * 1: all blink, then previous setting +@@ -910,9 +1005,11 @@ struct xpad_led { + */ static void xpad_send_led_command(struct usb_xpad *xpad, int command) { -- if (command >= 0 && command < 14) { -- mutex_lock(&xpad->odata_mutex); -+ command %= 16; ++ unsigned long flags; + -+ mutex_lock(&xpad->odata_mutex); -+ -+ switch (xpad->xtype) { -+ case XTYPE_XBOX360: - xpad->odata[0] = 0x01; - xpad->odata[1] = 0x03; - xpad->odata[2] = command; - xpad->irq_out->transfer_buffer_length = 3; -- usb_submit_urb(xpad->irq_out, GFP_KERNEL); -- mutex_unlock(&xpad->odata_mutex); -+ break; -+ case XTYPE_XBOX360W: -+ xpad->odata[0] = 0x00; -+ xpad->odata[1] = 0x00; -+ xpad->odata[2] = 0x08; -+ xpad->odata[3] = 0x40 + command; -+ xpad->odata[4] = 0x00; -+ xpad->odata[5] = 0x00; -+ xpad->odata[6] = 0x00; -+ xpad->odata[7] = 0x00; -+ xpad->odata[8] = 0x00; -+ xpad->odata[9] = 0x00; -+ xpad->odata[10] = 0x00; -+ xpad->odata[11] = 0x00; -+ xpad->irq_out->transfer_buffer_length = 12; -+ break; + command %= 16; + +- mutex_lock(&xpad->odata_mutex); ++ spin_lock_irqsave(&xpad->odata_lock, flags); + + switch (xpad->xtype) { + case XTYPE_XBOX360: +@@ -938,14 +1035,29 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command) + break; } -+ + +- usb_submit_urb(xpad->irq_out, GFP_KERNEL); +- mutex_unlock(&xpad->odata_mutex); + if (!xpad->irq_out_active) { + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + xpad->irq_out_active = 1; -+ } else -+ dev_dbg(&xpad->dev->dev, "%s - dropped, irq_out is active\n", -+ __func__); ++ } else { ++ if(xpad->pend_led) { ++ dev_dbg(&xpad->dev->dev, ++ "%s - overwriting pending\n", __func__); ++ } + -+ mutex_unlock(&xpad->odata_mutex); -+} ++ xpad->pend_led = xpad->irq_out->transfer_buffer_length; ++ memcpy(xpad->led_odata, xpad->odata, xpad->pend_led); ++ } + ++ spin_unlock_irqrestore(&xpad->odata_lock, flags); + } + +/* -+ * Light up the segment corresponding to the pad number on Xbox 360 Controllers ++ * Light up the segment corresponding to the pad number on ++ * Xbox 360 Controllers. + */ -+static void xpad_identify_controller(struct usb_xpad *xpad) -+{ -+ if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W) -+ return; -+ -+ xpad->pad_nr = find_first_zero_bit(&xpad_pad_seq, 32); -+ set_bit(xpad->pad_nr, &xpad_pad_seq); -+ + static void xpad_identify_controller(struct usb_xpad *xpad) + { +- /* Light up the segment corresponding to controller number */ +- xpad_send_led_command(xpad, (xpad->led_no % 4) + 2); + xpad_send_led_command(xpad, (xpad->pad_nr % 4) + 2); } static void xpad_led_set(struct led_classdev *led_cdev, -@@ -905,22 +988,18 @@ static void xpad_led_set(struct led_classdev *led_cdev, +@@ -959,7 +1071,6 @@ static void xpad_led_set(struct led_classdev *led_cdev, static int xpad_led_probe(struct usb_xpad *xpad) { -- static atomic_t led_seq = ATOMIC_INIT(-1); -- unsigned long led_no; +- static atomic_t led_seq = ATOMIC_INIT(-1); struct xpad_led *led; struct led_classdev *led_cdev; int error; - -- if (xpad->xtype != XTYPE_XBOX360) -+ if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W) - return 0; - - xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL); +@@ -971,9 +1082,13 @@ static int xpad_led_probe(struct usb_xpad *xpad) if (!led) return -ENOMEM; -- led_no = atomic_inc_return(&led_seq); -- -- snprintf(led->name, sizeof(led->name), "xpad%lu", led_no); -+ snprintf(led->name, sizeof(led->name), "xpad%lu", xpad->pad_nr); +- xpad->led_no = atomic_inc_return(&led_seq); ++ xpad->pad_nr = ida_simple_get(&xpad_pad_seq, 0, 0, GFP_KERNEL); ++ if (xpad->pad_nr < 0) { ++ error = xpad->pad_nr; ++ goto err_free_mem; ++ } + +- snprintf(led->name, sizeof(led->name), "xpad%lu", xpad->led_no); ++ snprintf(led->name, sizeof(led->name), "xpad%d", xpad->pad_nr); led->xpad = xpad; led_cdev = &led->led_cdev; -@@ -934,11 +1013,6 @@ static int xpad_led_probe(struct usb_xpad *xpad) - return error; - } +@@ -981,16 +1096,19 @@ static int xpad_led_probe(struct usb_xpad *xpad) + led_cdev->brightness_set = xpad_led_set; + + error = led_classdev_register(&xpad->udev->dev, led_cdev); +- if (error) { +- kfree(led); +- xpad->led = NULL; +- return error; +- } ++ if (error) ++ goto err_free_id; + +- /* Light up the segment corresponding to controller number */ + xpad_identify_controller(xpad); -- /* -- * Light up the segment corresponding to controller number -- */ -- xpad_send_led_command(xpad, (led_no % 4) + 2); -- return 0; ++ ++err_free_id: ++ ida_simple_remove(&xpad_pad_seq, xpad->pad_nr); ++err_free_mem: ++ kfree(led); ++ xpad->led = NULL; ++ return error; } -@@ -954,12 +1028,14 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) - #else - static int xpad_led_probe(struct usb_xpad *xpad) { return 0; } - static void xpad_led_disconnect(struct usb_xpad *xpad) { } -+static void xpad_identify_controller(struct usb_xpad *xpad) { } + static void xpad_led_disconnect(struct usb_xpad *xpad) +@@ -999,6 +1117,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) + + if (xpad_led) { + led_classdev_unregister(&xpad_led->led_cdev); ++ ida_simple_remove(&xpad_pad_seq, xpad->pad_nr); + kfree(xpad_led); + } + } +@@ -1008,10 +1127,12 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) { } + static void xpad_identify_controller(struct usb_xpad *xpad) { } #endif - +- static int xpad_open(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); + int retval; ++ ++ unsigned long flags; /* URB was submitted in probe */ if (xpad->xtype == XTYPE_XBOX360W) -@@ -970,11 +1046,17 @@ static int xpad_open(struct input_dev *dev) +@@ -1022,11 +1143,17 @@ static int xpad_open(struct input_dev *dev) return -EIO; if (xpad->xtype == XTYPE_XBOXONE) { -+ mutex_lock(&xpad->odata_mutex); ++ spin_lock_irqsave(&xpad->odata_lock, flags); /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; xpad->odata[1] = 0x20; @@ -524,15 +666,21 @@ index 61c7611..afecd26 100644 + xpad->odata[4] = 0x00; + xpad->irq_out->transfer_buffer_length = 5; + retval = usb_submit_urb(xpad->irq_out, GFP_KERNEL); -+ mutex_unlock(&xpad->odata_mutex); ++ spin_unlock_irqrestore(&xpad->odata_lock, flags); + return retval; } return 0; -@@ -1016,11 +1098,103 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) +@@ -1068,11 +1195,107 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) } } ++static void xpad_deinit_input(struct usb_xpad *xpad) ++{ ++ xpad_led_disconnect(xpad); ++ input_unregister_device(xpad->dev); ++} ++ +static int xpad_init_input(struct usb_xpad *xpad) +{ + struct input_dev *input_dev; @@ -553,10 +701,10 @@ index 61c7611..afecd26 100644 + input_dev->open = xpad_open; + input_dev->close = xpad_close; + -+ input_dev->evbit[0] = BIT_MASK(EV_KEY); ++ __set_bit(EV_KEY, input_dev->evbit); + + if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { -+ input_dev->evbit[0] |= BIT_MASK(EV_ABS); ++ __set_bit(EV_ABS, input_dev->evbit); + /* set up axes */ + for (i = 0; xpad_abs[i] >= 0; i++) + xpad_set_up_abs(input_dev, xpad_abs[i]); @@ -580,13 +728,15 @@ index 61c7611..afecd26 100644 + for (i = 0; xpad_btn_pad[i] >= 0; i++) + __set_bit(xpad_btn_pad[i], input_dev->keybit); + } -+ /* this should be a simple else block. However historically xbox360w -+ * has mapped DPAD to buttons while xbox360 did not. -+ * This made no sense, but now we can not just switch back and have to ++ ++ /* ++ * This should be a simple else block. However historically ++ * xbox360w has mapped DPAD to buttons while xbox360 did not. This ++ * made no sense, but now we can not just switch back and have to + * support both behaviors. + */ -+ if(!(xpad->mapping & MAP_DPAD_TO_BUTTONS) || -+ xpad->xtype == XTYPE_XBOX360W) { ++ if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) || ++ xpad->xtype == XTYPE_XBOX360W) { + for (i = 0; xpad_abs_pad[i] >= 0; i++) + xpad_set_up_abs(input_dev, xpad_abs_pad[i]); + } @@ -599,29 +749,25 @@ index 61c7611..afecd26 100644 + xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); + } + -+ xpad_identify_controller(xpad); -+ + error = xpad_init_ff(xpad); + if (error) -+ goto fail_init_ff; ++ goto err_free_input; + + error = xpad_led_probe(xpad); + if (error) -+ goto fail_init_led; ++ goto err_destroy_ff; + + error = input_register_device(xpad->dev); + if (error) -+ goto fail_input_register; ++ goto err_disconnect_led; + + return 0; + -+fail_input_register: ++err_disconnect_led: + xpad_led_disconnect(xpad); -+ -+fail_init_led: ++err_destroy_ff: + input_ff_destroy(input_dev); -+ -+fail_init_ff: ++err_free_input: + input_free_device(input_dev); + return error; +} @@ -634,24 +780,37 @@ index 61c7611..afecd26 100644 struct usb_endpoint_descriptor *ep_irq_in; int ep_irq_in_idx; int i, error; -@@ -1042,12 +1216,14 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id +@@ -1094,29 +1317,31 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!xpad || !input_dev) { -+ if (!xpad) { - error = -ENOMEM; - goto fail1; - } - +- error = -ENOMEM; +- goto fail1; +- } ++ if (!xpad) ++ return -ENOMEM; ++ + usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); + strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); -+ + xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) { -@@ -1065,6 +1241,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id + error = -ENOMEM; +- goto fail1; ++ goto err_free_mem; + } + + xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); + if (!xpad->irq_in) { + error = -ENOMEM; +- goto fail2; ++ goto err_free_idata; + } + + xpad->udev = udev; xpad->intf = intf; xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; @@ -660,7 +819,18 @@ index 61c7611..afecd26 100644 if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { -@@ -1083,71 +1261,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id +@@ -1124,8 +1349,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id + xpad->xtype = XTYPE_XBOX360W; + else + xpad->xtype = XTYPE_XBOX360; +- } else ++ } else { + xpad->xtype = XTYPE_XBOX; ++ } + + if (dpad_to_buttons) + xpad->mapping |= MAP_DPAD_TO_BUTTONS; +@@ -1135,70 +1361,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->mapping |= MAP_STICKS_TO_NULL; } @@ -719,8 +889,8 @@ index 61c7611..afecd26 100644 - error = xpad_init_output(intf, xpad); if (error) - goto fail3; - +- goto fail3; +- - error = xpad_init_ff(xpad); - if (error) - goto fail4; @@ -728,11 +898,11 @@ index 61c7611..afecd26 100644 - error = xpad_led_probe(xpad); - if (error) - goto fail5; -- ++ goto err_free_in_urb; + /* Xbox One controller has in/out endpoints swapped. */ ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0; - ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; -@@ -1159,60 +1276,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id +@@ -1211,60 +1376,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -793,53 +963,30 @@ index 61c7611..afecd26 100644 * Submit the int URB immediately rather than waiting for open * because we get status messages from the device whether * or not any controllers are attached. In fact, it's -@@ -1221,56 +1288,116 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id - */ +@@ -1274,55 +1389,87 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); -+ if (error) { -+ usb_kill_urb(xpad->irq_in); -+ goto fail4; -+ } -+ + if (error) +- goto fail9; +- } ++ goto err_deinit_output; + + /* -+ * send presence packet ++ * Send presence packet. + * This will force the controller to resend connection packets. + * This is useful in the case we activate the module after the + * adapter has been plugged in, as it won't automatically + * send us info about the controllers. + */ -+ mutex_lock(&xpad->odata_mutex); -+ xpad->odata[0] = 0x08; -+ xpad->odata[1] = 0x00; -+ xpad->odata[2] = 0x0F; -+ xpad->odata[3] = 0xC0; -+ xpad->odata[4] = 0x00; -+ xpad->odata[5] = 0x00; -+ xpad->odata[6] = 0x00; -+ xpad->odata[7] = 0x00; -+ xpad->odata[8] = 0x00; -+ xpad->odata[9] = 0x00; -+ xpad->odata[10] = 0x00; -+ xpad->odata[11] = 0x00; -+ xpad->irq_out->transfer_buffer_length = 12; -+ -+ if (!xpad->irq_out_active) { -+ usb_submit_urb(xpad->irq_out, GFP_KERNEL); -+ xpad->irq_out_active = 1; -+ } else -+ dev_dbg(&xpad->dev->dev, -+ "%s - dropped, irq_out is active\n", __func__); -+ -+ mutex_unlock(&xpad->odata_mutex); ++ error = xpad_inquiry_pad_presence(xpad); ++ if (error) ++ goto err_kill_in_urb; + } else { + xpad->pad_present = 1; + error = xpad_init_input(xpad); - if (error) -- goto fail9; -+ goto fail4; - } - ++ if (error) ++ goto err_deinit_output; ++ } return 0; - fail9: kfree(xpad->bdata); @@ -849,54 +996,53 @@ index 61c7611..afecd26 100644 - fail6: xpad_led_disconnect(xpad); - fail5: if (input_dev) - input_ff_destroy(input_dev); - fail4: xpad_deinit_output(xpad); - fail3: usb_free_urb(xpad->irq_in); - fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); +- fail4: xpad_deinit_output(xpad); +- fail3: usb_free_urb(xpad->irq_in); +- fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); - fail1: input_free_device(input_dev); -- kfree(xpad); -+ fail1: kfree(xpad); ++err_kill_in_urb: ++ usb_kill_urb(xpad->irq_in); ++err_deinit_output: ++ xpad_deinit_output(xpad); ++err_free_in_urb: ++ usb_free_urb(xpad->irq_in); ++err_free_idata: ++ usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); ++err_free_mem: + kfree(xpad); return error; } --static void xpad_disconnect(struct usb_interface *intf) -+static void xpad_deinit_input(struct usb_xpad *xpad) - { -- struct usb_xpad *xpad = usb_get_intfdata (intf); -- - xpad_led_disconnect(xpad); - input_unregister_device(xpad->dev); -- xpad_deinit_output(xpad); -+ -+ if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W) -+ return; -+ -+ clear_bit(xpad->pad_nr, &xpad_pad_seq); -+} -+ +static void xpad_stop_communication(struct usb_xpad *xpad) { + xpad_stop_output(xpad); - - if (xpad->xtype == XTYPE_XBOX360W) { -- usb_kill_urb(xpad->bulk_out); -- usb_free_urb(xpad->bulk_out); - usb_kill_urb(xpad->irq_in); - } - ++ ++ if (xpad->xtype == XTYPE_XBOX360W) { ++ usb_kill_urb(xpad->irq_in); ++ } ++ + cancel_work_sync(&xpad->work); +} + -+static void xpad_disconnect(struct usb_interface *intf) -+{ -+ struct usb_xpad *xpad = usb_get_intfdata (intf); -+ + static void xpad_disconnect(struct usb_interface *intf) + { + struct usb_xpad *xpad = usb_get_intfdata (intf); + +- xpad_led_disconnect(xpad); +- input_unregister_device(xpad->dev); +- xpad_deinit_output(xpad); + if (xpad->pad_present) + xpad_deinit_input(xpad); -+ + +- if (xpad->xtype == XTYPE_XBOX360W) { +- usb_kill_urb(xpad->bulk_out); +- usb_free_urb(xpad->bulk_out); +- usb_kill_urb(xpad->irq_in); +- } + xpad_stop_communication(xpad); + + xpad_deinit_output(xpad); -+ + usb_free_urb(xpad->irq_in); usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); diff --git a/packages/linux/patches/4.1.12/linux-203-stb0899_enable_low_symbol_rate.patch b/packages/linux/patches/4.3/linux-203-stb0899_enable_low_symbol_rate.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-203-stb0899_enable_low_symbol_rate.patch rename to packages/linux/patches/4.3/linux-203-stb0899_enable_low_symbol_rate.patch diff --git a/packages/linux/patches/4.1.12/linux-212-mantis_stb0899_faster_lock.patch b/packages/linux/patches/4.3/linux-212-mantis_stb0899_faster_lock.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-212-mantis_stb0899_faster_lock.patch rename to packages/linux/patches/4.3/linux-212-mantis_stb0899_faster_lock.patch diff --git a/packages/linux/patches/4.3/linux-221-ngene-octopus.todo b/packages/linux/patches/4.3/linux-221-ngene-octopus.todo new file mode 100644 index 0000000000..91fdbc9d67 --- /dev/null +++ b/packages/linux/patches/4.3/linux-221-ngene-octopus.todo @@ -0,0 +1,34137 @@ +From 4e0cb03f8d73ecda1283c6690f30b2944f169455 Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Thu, 11 Jun 2015 10:45:56 +0300 +Subject: [PATCH] dvb: ngene/octopus + +source: http://linuxtv.org/hg/~endriss/media_build_experimental/ + +note: SYS_DVBC2 not added. ci extensions (en50221) not added. +--- + drivers/media/dvb-core/Makefile | 2 +- + drivers/media/dvb-core/dvb_netstream.c | 259 ++ + drivers/media/dvb-core/dvb_netstream.h | 94 + + drivers/media/dvb-core/dvbdev.c | 11 +- + drivers/media/dvb-core/dvbdev.h | 4 + + drivers/media/dvb-frontends/Kconfig | 27 + + drivers/media/dvb-frontends/Makefile | 3 + + drivers/media/dvb-frontends/cxd2843.c | 2022 ++++++++++++ + drivers/media/dvb-frontends/cxd2843.h | 30 + + drivers/media/dvb-frontends/drxk_hard.c | 3614 +++++++++----------- + drivers/media/dvb-frontends/drxk_hard.h | 298 +- + drivers/media/dvb-frontends/drxk_map.h | 3 - + drivers/media/dvb-frontends/lnbh25.c | 153 + + drivers/media/dvb-frontends/lnbh25.h | 28 + + drivers/media/dvb-frontends/stv0367dd.c | 2331 +++++++++++++ + drivers/media/dvb-frontends/stv0367dd.h | 17 + + drivers/media/dvb-frontends/stv0367dd_regs.h | 3431 +++++++++++++++++++ + drivers/media/dvb-frontends/stv090x.c | 45 +- + drivers/media/dvb-frontends/stv0910.c | 1371 ++++++++ + drivers/media/dvb-frontends/stv0910.h | 31 + + drivers/media/dvb-frontends/stv0910_regs.h | 3998 +++++++++++++++++++++++ + drivers/media/dvb-frontends/stv6111.c | 450 +++ + drivers/media/dvb-frontends/stv6111.h | 5 + + drivers/media/dvb-frontends/tda18212dd.c | 974 ++++++ + drivers/media/dvb-frontends/tda18212dd.h | 5 + + drivers/media/dvb-frontends/tda18271c2dd.c | 17 +- + drivers/media/dvb-frontends/tda18271c2dd.h | 6 +- + drivers/media/dvb-frontends/tda18271c2dd_maps.h | 8 +- + drivers/media/pci/ddbridge/Kconfig | 11 +- + drivers/media/pci/ddbridge/Makefile | 2 - + drivers/media/pci/ddbridge/ddbridge-core.c | 3941 ++++++++++++++++------ + drivers/media/pci/ddbridge/ddbridge-i2c.c | 257 ++ + drivers/media/pci/ddbridge/ddbridge-i2c.h | 105 + + drivers/media/pci/ddbridge/ddbridge-mod.c | 1148 +++++++ + drivers/media/pci/ddbridge/ddbridge-ns.c | 489 +++ + drivers/media/pci/ddbridge/ddbridge-regs.h | 347 +- + drivers/media/pci/ddbridge/ddbridge.c | 470 +++ + drivers/media/pci/ddbridge/ddbridge.h | 419 ++- + drivers/media/pci/ddbridge/octonet.c | 199 ++ + drivers/media/pci/ngene/Kconfig | 4 + + drivers/media/pci/ngene/Makefile | 3 +- + drivers/media/pci/ngene/ngene-av.c | 348 ++ + drivers/media/pci/ngene/ngene-cards.c | 975 ++++-- + drivers/media/pci/ngene/ngene-core.c | 410 ++- + drivers/media/pci/ngene/ngene-dvb.c | 379 ++- + drivers/media/pci/ngene/ngene-eeprom.c | 284 ++ + drivers/media/pci/ngene/ngene-i2c.c | 113 + + drivers/media/pci/ngene/ngene.h | 42 +- + include/uapi/linux/dvb/mod.h | 22 + + include/uapi/linux/dvb/ns.h | 68 + + 50 files changed, 25733 insertions(+), 3540 deletions(-) + create mode 100644 drivers/media/dvb-core/dvb_netstream.c + create mode 100644 drivers/media/dvb-core/dvb_netstream.h + create mode 100644 drivers/media/dvb-frontends/cxd2843.c + create mode 100644 drivers/media/dvb-frontends/cxd2843.h + create mode 100644 drivers/media/dvb-frontends/lnbh25.c + create mode 100644 drivers/media/dvb-frontends/lnbh25.h + create mode 100644 drivers/media/dvb-frontends/stv0367dd.c + create mode 100644 drivers/media/dvb-frontends/stv0367dd.h + create mode 100644 drivers/media/dvb-frontends/stv0367dd_regs.h + create mode 100644 drivers/media/dvb-frontends/stv0910.c + create mode 100644 drivers/media/dvb-frontends/stv0910.h + create mode 100644 drivers/media/dvb-frontends/stv0910_regs.h + create mode 100644 drivers/media/dvb-frontends/stv6111.c + create mode 100644 drivers/media/dvb-frontends/stv6111.h + create mode 100644 drivers/media/dvb-frontends/tda18212dd.c + create mode 100644 drivers/media/dvb-frontends/tda18212dd.h + create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.c + create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.h + create mode 100644 drivers/media/pci/ddbridge/ddbridge-mod.c + create mode 100644 drivers/media/pci/ddbridge/ddbridge-ns.c + create mode 100644 drivers/media/pci/ddbridge/ddbridge.c + create mode 100644 drivers/media/pci/ddbridge/octonet.c + create mode 100644 drivers/media/pci/ngene/ngene-av.c + create mode 100644 drivers/media/pci/ngene/ngene-eeprom.c + create mode 100644 include/uapi/linux/dvb/mod.h + create mode 100644 include/uapi/linux/dvb/ns.h + +diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile +index 8f22bcd..5ff851a 100644 +--- a/drivers/media/dvb-core/Makefile ++++ b/drivers/media/dvb-core/Makefile +@@ -6,6 +6,6 @@ dvb-net-$(CONFIG_DVB_NET) := dvb_net.o + + dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ + dvb_ca_en50221.o dvb_frontend.o \ +- $(dvb-net-y) dvb_ringbuffer.o dvb_math.o ++ $(dvb-net-y) dvb_ringbuffer.o dvb_math.o dvb_netstream.o + + obj-$(CONFIG_DVB_CORE) += dvb-core.o +diff --git a/drivers/media/dvb-core/dvb_netstream.c b/drivers/media/dvb-core/dvb_netstream.c +new file mode 100644 +index 0000000..43322c7 +--- /dev/null ++++ b/drivers/media/dvb-core/dvb_netstream.c +@@ -0,0 +1,259 @@ ++/* ++ * dvb_netstream.c: support for DVB to network streaming hardware ++ * ++ * Copyright (C) 2012-2013 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include "dvb_netstream.h" ++ ++static ssize_t ns_write(struct file *file, const char *buf, ++ size_t count, loff_t *ppos) ++{ ++ printk("%s\n", __func__); ++ return 0; ++} ++ ++static ssize_t ns_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ printk("%s\n", __func__); ++ return 0; ++} ++ ++static unsigned int ns_poll(struct file *file, poll_table *wait) ++{ ++ printk("%s\n", __func__); ++ return 0; ++} ++ ++static int ns_stop(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ ++ mutex_lock(&ns->mutex); ++ if (nss->running && ns->stop) { ++ ns->stop(nss); ++ nss->running = 0; ++ } ++ mutex_unlock(&ns->mutex); ++ return 0; ++} ++ ++static int ns_release(struct inode *inode, struct file *file) ++{ ++ struct dvbnss *nss = file->private_data; ++ struct dvb_netstream *ns = nss->ns; ++ ++ ns_stop(nss); ++ if (ns->free) ++ ns->free(nss); ++ mutex_lock(&ns->mutex); ++ list_del(&nss->nssl); ++ mutex_unlock(&ns->mutex); ++ vfree(nss); ++ return 0; ++} ++ ++static int ns_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct dvb_netstream *ns = dvbdev->priv; ++ struct dvbnss *nss; ++ ++ nss = vmalloc(sizeof(*nss)); ++ if (!nss) ++ return -ENOMEM; ++ nss->ns = ns; ++ if (ns->alloc && ns->alloc(nss) < 0) { ++ vfree(nss); ++ return -EBUSY; ++ } ++ file->private_data = nss; ++ nss->running = 0; ++ mutex_lock(&ns->mutex); ++ list_add(&nss->nssl, &ns->nssl); ++ mutex_unlock(&ns->mutex); ++ return 0; ++} ++ ++static int set_net(struct dvbnss *nss, struct dvb_ns_params *p) ++{ ++ return 0; ++} ++ ++static int do_ioctl(struct file *file, unsigned int cmd, void *parg) ++{ ++ struct dvbnss *nss = file->private_data; ++ struct dvb_netstream *ns = nss->ns; ++ //unsigned long arg = (unsigned long) parg; ++ int ret = 0; ++ ++ switch (cmd) { ++ case NS_SET_RTCP_MSG: ++ { ++ struct dvb_ns_rtcp *rtcpm = parg; ++ ++ if (ns->set_rtcp_msg) { ++ //printk("%s calling NS_SET_RTCP_MSG\n", __func__); ++ ret = ns->set_rtcp_msg(nss, rtcpm->msg, rtcpm->len); ++ } ++ break; ++ } ++ ++ case NS_SET_NET: ++ memcpy(&nss->params, parg, sizeof(nss->params)); ++ if (ns->set_net) { ++ ret = ns->set_net(nss); ++ } else ++ ret = set_net(nss, (struct dvb_ns_params *) parg); ++ break; ++ ++ case NS_START: ++ mutex_lock(&ns->mutex); ++ if (nss->running) { ++ ret = -EBUSY; ++ } else if (ns->start) { ++ ret = ns->start(nss); ++ nss->running = 1; ++ } ++ mutex_unlock(&ns->mutex); ++ break; ++ ++ case NS_STOP: ++ ns_stop(nss); ++ break; ++ ++ case NS_SET_PACKETS: ++ { ++ struct dvb_ns_packet *packet = parg; ++ if (ns->set_ts_packets) { ++ ret = ns->set_ts_packets(nss, packet->buf, packet->count * 188); ++ } ++ break; ++ } ++ ++ case NS_INSERT_PACKETS: ++ { ++ u8 count = *(u8 *) parg; ++ if (ns->insert_ts_packets) ++ ret = ns->insert_ts_packets(nss, count); ++ break; ++ } ++ ++ case NS_SET_PID: ++ { ++ u16 pid = *(u16 *) parg; ++ u16 byte = (pid & 0x1fff) >> 3; ++ u8 bit = 1 << (pid & 7); ++ ++ if (pid & 0x2000) { ++ if (pid & 0x8000) ++ memset(nss->pids, 0xff, 0x400); ++ else ++ memset(nss->pids, 0x00, 0x400); ++ } else { ++ if (pid & 0x8000) ++ nss->pids[byte] |= bit; ++ else ++ nss->pids[byte] &= ~bit; ++ } ++ if (ns->set_pid) ++ ret = ns->set_pid(nss, pid); ++ break; ++ } ++ ++ case NS_SET_PIDS: ++ ret = copy_from_user(nss->pids, *(u8 **) parg, 0x400); ++ if (ret < 0) ++ return ret; ++ if (ns->set_pids) ++ ret = ns->set_pids(nss); ++ break; ++ ++ case NS_SET_CI: ++ { ++ u8 ci = *(u8 *) parg; ++ ++ if (nss->running) ++ ret = -EBUSY; ++ else if (ns->set_ci) ++ ret = ns->set_ci(nss, ci); ++ break; ++ } ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static long ns_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy(file, cmd, arg, do_ioctl); ++} ++ ++static const struct file_operations ns_fops = { ++ .owner = THIS_MODULE, ++ .read = ns_read, ++ .write = ns_write, ++ .open = ns_open, ++ .release = ns_release, ++ .poll = ns_poll, ++ .mmap = 0, ++ .unlocked_ioctl = ns_ioctl, ++}; ++ ++static struct dvb_device ns_dev = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 1, ++ .fops = &ns_fops, ++}; ++ ++ ++int dvb_netstream_init(struct dvb_adapter *dvb_adapter, struct dvb_netstream *ns) ++{ ++ mutex_init(&ns->mutex); ++ spin_lock_init(&ns->lock); ++ ns->exit = 0; ++ dvb_register_device(dvb_adapter, &ns->dvbdev, &ns_dev, ns, ++ DVB_DEVICE_NS); ++ INIT_LIST_HEAD(&ns->nssl); ++ return 0; ++} ++ ++EXPORT_SYMBOL(dvb_netstream_init); ++ ++void dvb_netstream_release(struct dvb_netstream *ns) ++{ ++ ns->exit=1; ++ if (ns->dvbdev->users > 1) { ++ wait_event(ns->dvbdev->wait_queue, ++ ns->dvbdev->users == 1); ++ } ++ dvb_unregister_device(ns->dvbdev); ++} ++ ++EXPORT_SYMBOL(dvb_netstream_release); +diff --git a/drivers/media/dvb-core/dvb_netstream.h b/drivers/media/dvb-core/dvb_netstream.h +new file mode 100644 +index 0000000..df73ed5 +--- /dev/null ++++ b/drivers/media/dvb-core/dvb_netstream.h +@@ -0,0 +1,94 @@ ++/* ++ * dvb_netstream.c: support for DVB to network streaming hardware ++ * ++ * Copyright (C) 2012-2013 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#ifndef _DVB_NETSTREAM_H_ ++#define _DVB_NETSTREAM_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvbdev.h" ++ ++#define DVBNS_MAXPIDS 32 ++ ++struct dvbnss { ++ struct dvb_netstream *ns; ++ void *priv; ++ ++ u8 pids[1024]; ++ u8 packet[1328]; ++ u32 pp; ++ ++ struct socket *sock; ++ struct sockaddr_in sadr; ++ u32 sn; ++ ++ struct dvb_ns_params params; ++ ++ struct list_head nssl; ++ int running; ++}; ++ ++#define MAX_DVBNSS 32 ++ ++struct dvb_netstream { ++ void *priv; ++ ++ struct mutex mutex; ++ spinlock_t lock; ++ struct dvb_device *dvbdev; ++ int exit; ++ ++ struct list_head nssl; ++ ++ int (*set_net) (struct dvbnss *); ++ int (*set_pid) (struct dvbnss *, u16); ++ int (*set_pids) (struct dvbnss *); ++ int (*set_ci) (struct dvbnss *, u8); ++ int (*set_rtcp_msg) (struct dvbnss *, u8 *, u32); ++ int (*set_ts_packets) (struct dvbnss *, u8 *, u32); ++ int (*insert_ts_packets) (struct dvbnss *, u8); ++ int (*start) (struct dvbnss *); ++ int (*stop) (struct dvbnss *); ++ int (*alloc) (struct dvbnss *); ++ void (*free) (struct dvbnss *); ++ ++}; ++ ++ ++void dvb_netstream_release(struct dvb_netstream *); ++int dvb_netstream_init(struct dvb_adapter *, struct dvb_netstream *); ++ ++ ++#endif +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 13bb57f..ef320af 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -47,7 +47,7 @@ static DEFINE_MUTEX(dvbdev_register_lock); + + static const char * const dnames[] = { + "video", "audio", "sec", "frontend", "demux", "dvr", "ca", +- "net", "osd" ++ "net", "osd", "ci", "mod", "ns", "nsd" + }; + + #ifdef CONFIG_DVB_DYNAMIC_MINORS +@@ -68,7 +68,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) + { + struct dvb_device *dvbdev; + +- mutex_lock(&dvbdev_mutex); ++ //mutex_lock(&dvbdev_mutex); + down_read(&minor_rwsem); + dvbdev = dvb_minors[iminor(inode)]; + +@@ -84,12 +84,12 @@ static int dvb_device_open(struct inode *inode, struct file *file) + if (file->f_op->open) + err = file->f_op->open(inode,file); + up_read(&minor_rwsem); +- mutex_unlock(&dvbdev_mutex); ++ //mutex_unlock(&dvbdev_mutex); + return err; + } + fail: + up_read(&minor_rwsem); +- mutex_unlock(&dvbdev_mutex); ++ //mutex_unlock(&dvbdev_mutex); + return -ENODEV; + } + +@@ -553,8 +553,10 @@ int dvb_usercopy(struct file *file, + } + + /* call driver */ ++ //mutex_lock(&dvbdev_mutex); + if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) + err = -ENOTTY; ++ //mutex_unlock(&dvbdev_mutex); + + if (err < 0) + goto out; +@@ -573,6 +575,7 @@ out: + kfree(mbuf); + return err; + } ++EXPORT_SYMBOL(dvb_usercopy); + + static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) + { +diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h +index 12629b8..e918a09 100644 +--- a/drivers/media/dvb-core/dvbdev.h ++++ b/drivers/media/dvb-core/dvbdev.h +@@ -48,6 +48,10 @@ + #define DVB_DEVICE_CA 6 + #define DVB_DEVICE_NET 7 + #define DVB_DEVICE_OSD 8 ++#define DVB_DEVICE_CI 9 ++#define DVB_DEVICE_MOD 10 ++#define DVB_DEVICE_NS 11 ++#define DVB_DEVICE_NSD 12 + + #define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \ + static short adapter_nr[] = \ +diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig +index 97c151d..2bf9390 100644 +--- a/drivers/media/dvb-frontends/Kconfig ++++ b/drivers/media/dvb-frontends/Kconfig +@@ -72,6 +72,33 @@ config DVB_SI2165 + + Say Y when you want to support this frontend. + ++config DVB_STV0367DD ++ tristate "STV 0367 (DD)" ++ depends on DVB_CORE && I2C ++ default m if !MEDIA_SUBDRV_AUTOSELECT ++ help ++ STV 0367 DVB-C/T demodulator (Digital Devices driver). ++ ++ Say Y when you want to support this frontend. ++ ++config DVB_TDA18212DD ++ tristate "NXP TDA18212 silicon tuner (DD)" ++ depends on DVB_CORE && I2C ++ default m if !MEDIA_SUBDRV_AUTOSELECT ++ help ++ NXP TDA18212 silicon tuner (Digital Devices driver). ++ ++ Say Y when you want to support this tuner. ++ ++config DVB_CXD2843 ++ tristate "Sony CXD2843 DVB-C/T demodulator family" ++ depends on DVB_CORE && I2C ++ default m if !MEDIA_SUBDRV_AUTOSELECT ++ help ++ Sony CXD2843 demodulator (Digital Devices driver). ++ ++ Say Y when you want to support this frontend. ++ + comment "DVB-S (satellite) frontends" + depends on DVB_CORE + +diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile +index 23d399b..db9b87a 100644 +--- a/drivers/media/dvb-frontends/Makefile ++++ b/drivers/media/dvb-frontends/Makefile +@@ -106,6 +106,9 @@ obj-$(CONFIG_DVB_STV0367) += stv0367.o + obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o + obj-$(CONFIG_DVB_DRXK) += drxk.o + obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o ++obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o ++obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o ++obj-$(CONFIG_DVB_CXD2843) += cxd2843.o + obj-$(CONFIG_DVB_SI2165) += si2165.o + obj-$(CONFIG_DVB_A8293) += a8293.o + obj-$(CONFIG_DVB_SP2) += sp2.o +diff --git a/drivers/media/dvb-frontends/cxd2843.c b/drivers/media/dvb-frontends/cxd2843.c +new file mode 100644 +index 0000000..27e5eac +--- /dev/null ++++ b/drivers/media/dvb-frontends/cxd2843.c +@@ -0,0 +1,2022 @@ ++/* ++ * Driver for the Sony CXD2843ER DVB-T/T2/C/C2 demodulator. ++ * Also supports the CXD2837ER DVB-T/T2/C and the ++ * CXD2838ER ISDB-T demodulator. ++ * ++ * Copyright (C) 2013-2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "cxd2843.h" ++ ++#define USE_ALGO 1 ++ ++enum EDemodType { CXD2843, CXD2837, CXD2838 }; ++enum EDemodState { Unknown, Shutdown, Sleep, ActiveT, ++ ActiveT2, ActiveC, ActiveC2, ActiveIT }; ++enum ET2Profile { T2P_Base, T2P_Lite }; ++enum omode { OM_NONE, OM_DVBT, OM_DVBT2, OM_DVBC, ++ OM_QAM_ITU_C, OM_DVBC2, OM_ISDBT }; ++ ++struct cxd_state { ++ struct dvb_frontend frontend; ++ struct i2c_adapter *i2c; ++ struct mutex mutex; ++ ++ u8 adrt; ++ u8 curbankt; ++ ++ u8 adrx; ++ u8 curbankx; ++ ++ enum EDemodType type; ++ enum EDemodState state; ++ enum ET2Profile T2Profile; ++ enum omode omode; ++ ++ u8 IF_FS; ++ int ContinuousClock; ++ int SerialMode; ++ u8 SerialClockFrequency; ++ ++ u32 LockTimeout; ++ u32 TSLockTimeout; ++ u32 L1PostTimeout; ++ u32 DataSliceID; ++ int FirstTimeLock; ++ u32 plp; ++ u32 last_status; ++ ++ u32 bandwidth; ++ u32 bw; ++ ++ unsigned long tune_time; ++ ++ u32 LastBERNominator; ++ u32 LastBERDenominator; ++ u8 BERScaleMax; ++}; ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = { ++ .addr = adr, .flags = 0, .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("cxd2843: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int writeregs(struct cxd_state *state, u8 adr, u8 reg, ++ u8 *regd, u16 len) ++{ ++ u8 data[len + 1]; ++ ++ data[0] = reg; ++ memcpy(data + 1, regd, len); ++ return i2c_write(state->i2c, adr, data, len + 1); ++} ++ ++static int writereg(struct cxd_state *state, u8 adr, u8 reg, u8 dat) ++{ ++ u8 mm[2] = {reg, dat}; ++ ++ return i2c_write(state->i2c, adr, mm, 2); ++} ++ ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ pr_err("cxd2843: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int readregs(struct cxd_state *state, u8 adr, u8 reg, ++ u8 *val, int count) ++{ ++ return i2c_read(state->i2c, adr, ®, 1, val, count); ++} ++ ++static int readregst_unlocked(struct cxd_state *cxd, u8 bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (bank != 0xFF && cxd->curbankt != bank) { ++ status = writereg(cxd, cxd->adrt, 0, bank); ++ if (status < 0) { ++ cxd->curbankt = 0xFF; ++ return status; ++ } ++ cxd->curbankt = bank; ++ } ++ status = readregs(cxd, cxd->adrt, Address, pValue, count); ++ return status; ++} ++ ++static int readregst(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregst_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int readregsx_unlocked(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (Bank != 0xFF && cxd->curbankx != Bank) { ++ status = writereg(cxd, cxd->adrx, 0, Bank); ++ if (status < 0) { ++ cxd->curbankx = 0xFF; ++ return status; ++ } ++ cxd->curbankx = Bank; ++ } ++ status = readregs(cxd, cxd->adrx, Address, pValue, count); ++ return status; ++} ++ ++static int readregsx(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregsx_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writeregsx_unlocked(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (Bank != 0xFF && cxd->curbankx != Bank) { ++ status = writereg(cxd, cxd->adrx, 0, Bank); ++ if (status < 0) { ++ cxd->curbankx = 0xFF; ++ return status; ++ } ++ cxd->curbankx = Bank; ++ } ++ status = writeregs(cxd, cxd->adrx, Address, pValue, count); ++ return status; ++} ++ ++static int writeregsx(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = writeregsx_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writeregx(struct cxd_state *cxd, u8 Bank, u8 Address, u8 val) ++{ ++ return writeregsx(cxd, Bank, Address, &val, 1); ++} ++ ++static int writeregst_unlocked(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (Bank != 0xFF && cxd->curbankt != Bank) { ++ status = writereg(cxd, cxd->adrt, 0, Bank); ++ if (status < 0) { ++ cxd->curbankt = 0xFF; ++ return status; ++ } ++ cxd->curbankt = Bank; ++ } ++ status = writeregs(cxd, cxd->adrt, Address, pValue, count); ++ return status; ++} ++ ++static int writeregst(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = writeregst_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writeregt(struct cxd_state *cxd, u8 Bank, u8 Address, u8 val) ++{ ++ return writeregst(cxd, Bank, Address, &val, 1); ++} ++ ++static int writebitsx(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 Value, u8 Mask) ++{ ++ int status = 0; ++ u8 tmp; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1); ++ if (status < 0) ++ return status; ++ tmp = (tmp & ~Mask) | Value; ++ status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writebitst(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 Value, u8 Mask) ++{ ++ int status = 0; ++ u8 Tmp = 0x00; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1); ++ if (status < 0) ++ return status; ++ Tmp = (Tmp & ~Mask) | Value; ++ status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int freeze_regst(struct cxd_state *cxd) ++{ ++ mutex_lock(&cxd->mutex); ++ return writereg(cxd, cxd->adrt, 1, 1); ++} ++ ++static int unfreeze_regst(struct cxd_state *cxd) ++{ ++ int status = 0; ++ ++ status = writereg(cxd, cxd->adrt, 1, 0); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++/* TPSData[0] [7:6] CNST[1:0] */ ++/* TPSData[0] [5:3] HIER[2:0] */ ++/* TPSData[0] [2:0] HRATE[2:0] */ ++/* TPSData[1] [7:5] LRATE[2:0] */ ++/* TPSData[1] [4:3] GI[1:0] */ ++/* TPSData[1] [2:1] MODE[1:0] */ ++/* TPSData[2] [7:6] FNUM[1:0] */ ++/* TPSData[2] [5:0] LENGTH_INDICATOR[5:0] */ ++/* TPSData[3] [7:0] CELLID[15:8] */ ++/* TPSData[4] [7:0] CELLID[7:0] */ ++/* TPSData[5] [5:0] RESERVE_EVEN[5:0] */ ++/* TPSData[6] [5:0] RESERVE_ODD[5:0] */ ++ ++static int read_tps(struct cxd_state *state, u8 *tps) ++{ ++ if (state->last_status != 0x1f) ++ return 0; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x10, 0x2f, tps, 7); ++ unfreeze_regst(state); ++ return 0; ++} ++ ++static void Active_to_Sleep(struct cxd_state *state) ++{ ++ if (state->state <= Sleep) ++ return; ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++ writeregt(state, 0x00, 0x80, 0x3F); /* Enable HighZ 1 */ ++ writeregt(state, 0x00, 0x81, 0xFF); /* Enable HighZ 2 */ ++ writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ ++ writeregt(state, 0x00, 0x43, 0x0A); /* Disable ADC 2 */ ++ writeregt(state, 0x00, 0x41, 0x0A); /* Disable ADC 1 */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Disable ADC Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF level Monitor */ ++ writeregt(state, 0x00, 0x2C, 0x00); /* Disable Demod Clock */ ++ state->state = Sleep; ++} ++ ++static void ActiveT2_to_Sleep(struct cxd_state *state) ++{ ++ if (state->state <= Sleep) ++ return; ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++ writeregt(state, 0x00, 0x80, 0x3F); /* Enable HighZ 1 */ ++ writeregt(state, 0x00, 0x81, 0xFF); /* Enable HighZ 2 */ ++ ++ writeregt(state, 0x13, 0x83, 0x40); ++ writeregt(state, 0x13, 0x86, 0x21); ++ writebitst(state, 0x13, 0x9E, 0x09, 0x0F); ++ writeregt(state, 0x13, 0x9F, 0xFB); ++ ++ writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ ++ writeregt(state, 0x00, 0x43, 0x0A); /* Disable ADC 2 */ ++ writeregt(state, 0x00, 0x41, 0x0A); /* Disable ADC 1 */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Disable ADC Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF level Monitor */ ++ writeregt(state, 0x00, 0x2C, 0x00); /* Disable Demod Clock */ ++ state->state = Sleep; ++} ++ ++static void ActiveC2_to_Sleep(struct cxd_state *state) ++{ ++ if (state->state <= Sleep) ++ return; ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++ writeregt(state, 0x00, 0x80, 0x3F); /* Enable HighZ 1 */ ++ writeregt(state, 0x00, 0x81, 0xFF); /* Enable HighZ 2 */ ++ ++ writeregt(state, 0x20, 0xC2, 0x11); ++ writebitst(state, 0x25, 0x6A, 0x02, 0x03); ++ { ++ static u8 data[3] = { 0x07, 0x61, 0x36 }; ++ writeregst(state, 0x25, 0x89, data, sizeof(data)); ++ } ++ writebitst(state, 0x25, 0xCB, 0x05, 0x07); ++ { ++ static u8 data[4] = { 0x2E, 0xE0, 0x2E, 0xE0 }; ++ writeregst(state, 0x25, 0xDC, data, sizeof(data)); ++ } ++ writeregt(state, 0x25, 0xE2, 0x2F); ++ writeregt(state, 0x25, 0xE5, 0x2F); ++ writebitst(state, 0x27, 0x20, 0x00, 0x01); ++ writebitst(state, 0x27, 0x35, 0x00, 0x01); ++ writebitst(state, 0x27, 0xD9, 0x19, 0x3F); ++ writebitst(state, 0x2A, 0x78, 0x01, 0x07); ++ writeregt(state, 0x2A, 0x86, 0x08); ++ writeregt(state, 0x2A, 0x88, 0x14); ++ writebitst(state, 0x2B, 0x2B, 0x00, 0x1F); ++ { ++ u8 data[2] = { 0x75, 0x75 }; ++ writeregst(state, 0x2D, 0x24, data, sizeof(data)); ++ } ++ ++ writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ ++ writeregt(state, 0x00, 0x43, 0x0A); /* Disable ADC 2 */ ++ writeregt(state, 0x00, 0x41, 0x0A); /* Disable ADC 1 */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Disable ADC Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF level Monitor */ ++ writeregt(state, 0x00, 0x2C, 0x00); /* Disable Demod Clock */ ++ state->state = Sleep; ++} ++ ++static int ConfigureTS(struct cxd_state *state, ++ enum EDemodState newDemodState) ++{ ++ int status = 0; ++ u8 OSERCKMODE = state->SerialMode ? 1 : 0; ++ u8 OSERDUTYMODE = state->SerialMode ? 1 : 0; ++ u8 OTSCKPERIOD = 8; ++ u8 OREG_CKSEL_TSIF = state->SerialMode ? ++ state->SerialClockFrequency : 0; ++ ++ if (state->SerialMode && state->SerialClockFrequency >= 3) { ++ OSERCKMODE = 2; ++ OSERDUTYMODE = 2; ++ OTSCKPERIOD = 16; ++ OREG_CKSEL_TSIF = state->SerialClockFrequency - 3; ++ } ++ writebitst(state, 0x00, 0xC4, OSERCKMODE, 0x03); /* OSERCKMODE */ ++ writebitst(state, 0x00, 0xD1, OSERDUTYMODE, 0x03); /* OSERDUTYMODE */ ++ writeregt(state, 0x00, 0xD9, OTSCKPERIOD); /* OTSCKPERIOD */ ++ writebitst(state, 0x00, 0x32, 0x00, 0x01); /* Disable TS IF */ ++ /* OREG_CKSEL_TSIF */ ++ writebitst(state, 0x00, 0x33, OREG_CKSEL_TSIF, 0x03); ++ writebitst(state, 0x00, 0x32, 0x01, 0x01); /* Enable TS IF */ ++ ++ if (newDemodState == ActiveT) ++ writebitst(state, 0x10, 0x66, 0x01, 0x01); ++ if (newDemodState == ActiveC) ++ writebitst(state, 0x40, 0x66, 0x01, 0x01); ++ ++ return status; ++} ++ ++static void BandSettingT(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = { (iffreq >> 16) & 0xff, ++ (iffreq >> 8) & 0xff, iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x01, 0xE0 }; ++ u8 NF_data[] = { 0x01, 0x02 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x00, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ case 7: ++ { ++ u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x12, 0xF8 }; ++ u8 NF_data[] = { 0x00, 0x03 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x02, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ case 6: ++ { ++ u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; ++ u8 CL_data[] = { 0x1F, 0xDC }; ++ u8 NF_data[] = { 0x00, 0x03 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x04, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ case 5: ++ { ++ static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; ++ static u8 CL_data[] = { 0x26, 0x3C }; ++ static u8 NF_data[] = { 0x00, 0x03 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x06, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ } ++} ++ ++static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveT); ++ writeregx(state, 0x00, 0x17, 0x01); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IF AGC Gain */ ++ writeregt(state, 0x11, 0x6A, 0x48); /* BB AGC Target Level */ ++ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writebitst(state, 0x18, 0x36, 0x40, 0x07); /* Pre RS Monitoring */ ++ writebitst(state, 0x18, 0x30, 0x01, 0x01); /* FEC Autorecover */ ++ writebitst(state, 0x18, 0x31, 0x01, 0x01); /* FEC Autorecover */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ BandSettingT(state, iffreq); ++ ++ writebitst(state, 0x10, 0x60, 0x11, 0x1f); /* BER scaling */ ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++static void BandSettingT2(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = {(iffreq >> 16) & 0xff, (iffreq >> 8) & 0xff, ++ iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; ++ /* Timing recovery */ ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ /* Add EQ Optimisation for tuner here */ ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ /* System Bandwidth */ ++ writebitst(state, 0x10, 0xD7, 0x00, 0x07); ++ } ++ break; ++ case 7: ++ { ++ u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x02, 0x07); ++ } ++ break; ++ case 6: ++ { ++ u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x04, 0x07); ++ } ++ break; ++ case 5: ++ { ++ u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x06, 0x07); ++ } ++ break; ++ case 2: /* 1.7 MHz */ ++ { ++ u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x03, 0x07); ++ } ++ break; ++ } ++} ++ ++ ++static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveT2); ++ ++ writeregx(state, 0x00, 0x17, 0x02); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IFAGC coarse gain */ ++ writeregt(state, 0x11, 0x6A, 0x50); /* BB AGC Target Level */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writeregt(state, 0x20, 0x8B, 0x3C); /* SNR Good count */ ++ writebitst(state, 0x2B, 0x76, 0x20, 0x70); /* Noise Gain ACQ */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ writeregt(state, 0x13, 0x83, 0x10); /* T2 Inital settings */ ++ writeregt(state, 0x13, 0x86, 0x34); ++ writebitst(state, 0x13, 0x9E, 0x09, 0x0F); ++ writeregt(state, 0x13, 0x9F, 0xD8); ++ ++ BandSettingT2(state, iffreq); ++ ++ writebitst(state, 0x20, 0x72, 0x08, 0x0f); /* BER scaling */ ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++ ++static void BandSettingC(struct cxd_state *state, u32 iffreq) ++{ ++ u8 data[3]; ++ ++ data[0] = (iffreq >> 16) & 0xFF; ++ data[1] = (iffreq >> 8) & 0xFF; ++ data[2] = (iffreq) & 0xFF; ++ writeregst(state, 0x10, 0xB6, data, 3); ++} ++ ++static void Sleep_to_ActiveC(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveC); ++ ++ writeregx(state, 0x00, 0x17, 0x04); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x09, 0x1F); /* IF AGC Gain */ ++ writeregt(state, 0x11, 0x6A, 0x48); /* BB AGC Target Level */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writebitst(state, 0x40, 0xC3, 0x00, 0x04); /* OREG_BNDET_EN_64 */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ BandSettingC(state, iffreq); ++ ++ writebitst(state, 0x40, 0x60, 0x11, 0x1f); /* BER scaling */ ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++static void BandSettingC2(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = { (iffreq >> 16) & 0xff, ++ (iffreq >> 8) & 0xff, iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; ++ u8 data[2] = { 0x11, 0x9E }; ++ ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x00, 0x07); ++ writeregst(state, 0x50, 0xEC, data, sizeof(data)); ++ writeregt(state, 0x50, 0xEF, 0x11); ++ writeregt(state, 0x50, 0xF1, 0x9E); ++ } ++ break; ++ case 6: ++ { ++ u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; ++ u8 data[2] = { 0x17, 0x70 }; ++ ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x04, 0x07); ++ writeregst(state, 0x50, 0xEC, data, sizeof(data)); ++ writeregt(state, 0x50, 0xEF, 0x17); ++ writeregt(state, 0x50, 0xF1, 0x70); ++ } ++ break; ++ } ++} ++ ++static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveC2); ++ ++ writeregx(state, 0x00, 0x17, 0x05); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, sizeof(data)); ++ /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IFAGC coarse gain */ ++ writeregt(state, 0x11, 0x6A, 0x50); /* BB AGC Target Level */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ writeregt(state, 0x20, 0xC2, 0x00); ++ writebitst(state, 0x25, 0x6A, 0x00, 0x03); ++ { ++ u8 data[3] = { 0x0C, 0xD1, 0x40 }; ++ writeregst(state, 0x25, 0x89, data, sizeof(data)); ++ } ++ writebitst(state, 0x25, 0xCB, 0x01, 0x07); ++ { ++ u8 data[4] = { 0x7B, 0x00, 0x7B, 0x00 }; ++ writeregst(state, 0x25, 0xDC, data, sizeof(data)); ++ } ++ writeregt(state, 0x25, 0xE2, 0x30); ++ writeregt(state, 0x25, 0xE5, 0x30); ++ writebitst(state, 0x27, 0x20, 0x01, 0x01); ++ writebitst(state, 0x27, 0x35, 0x01, 0x01); ++ writebitst(state, 0x27, 0xD9, 0x18, 0x3F); ++ writebitst(state, 0x2A, 0x78, 0x00, 0x07); ++ writeregt(state, 0x2A, 0x86, 0x20); ++ writeregt(state, 0x2A, 0x88, 0x32); ++ writebitst(state, 0x2B, 0x2B, 0x10, 0x1F); ++ { ++ u8 data[2] = { 0x01, 0x01 }; ++ writeregst(state, 0x2D, 0x24, data, sizeof(data)); ++ } ++ ++ BandSettingC2(state, iffreq); ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++ ++static void BandSettingIT(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = { (iffreq >> 16) & 0xff, ++ (iffreq >> 8) & 0xff, iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */ ++ u8 CL_data[] = { 0x15, 0xA8 }; ++ ++ /*u8 TR_data[] = { 0x11, 0xB8, 0x00, 0x00, 0x00 }; */ /* 24 */ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ /* Add EQ Optimisation for tuner here */ ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ ++ writeregt(state, 0x10, 0xD7, 0x00); /* System Bandwidth */ ++ /*u8 CL_data[] = { 0x13, 0xFC }; */ ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ } ++ break; ++ case 7: ++ { ++ u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x1B, 0x5D }; ++ ++ /*u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; */ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ ++ writeregt(state, 0x10, 0xD7, 0x02); ++ /*static u8 CL_data[] = { 0x1A, 0xFA };*/ ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ } ++ break; ++ case 6: ++ { ++ u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x1F, 0xEC }; ++ /*u8 TR_data[] = { 0x17, 0xA0, 0x00, 0x00, 0x00 }; */ ++ /*u8 CL_data[] = { 0x1F, 0x79 }; */ ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writeregt(state, 0x10, 0xD7, 0x04); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ } ++ break; ++ } ++} ++ ++static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) ++{ ++ u8 data2[3] = { 0xB9, 0xBA, 0x63 }; /* 20.5/41 MHz */ ++ /*u8 data2[3] = { 0xB7,0x1B,0x00 }; */ /* 24 MHz */ ++ u8 TSIF_data[2] = { 0x61, 0x60 } ; /* 20.5/41 MHz */ ++ /*u8 TSIF_data[2] = { 0x60,0x00 } ; */ /* 24 MHz */ ++ ++ pr_info("%s\n", __func__); ++ ++ ConfigureTS(state, ActiveIT); ++ ++ /* writeregx(state, 0x00,0x17,0x01); */ /* 2838 has only one Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz, 24 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writeregst(state, 0x60, 0xA8, data2, sizeof(data2)); ++ ++ writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data)); ++ ++ writeregt(state, 0x10, 0xE2, 0xCE); /* OREG_PNC_DISABLE */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ BandSettingIT(state, iffreq); ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++static void T2_SetParameters(struct cxd_state *state) ++{ ++ u8 Profile = 0x01; /* Profile Base */ ++ u8 notT2time = 12; /* early unlock detection time */ ++ ++ if (state->T2Profile == T2P_Lite) { ++ Profile = 0x05; ++ notT2time = 40; ++ } ++ ++ if (state->plp != 0xffffffff) { ++ state->T2Profile = ((state->plp & 0x100) != 0) ? ++ T2P_Lite : T2P_Base; ++ writeregt(state, 0x23, 0xAF, state->plp); ++ writeregt(state, 0x23, 0xAD, 0x01); ++ } else { ++ state->T2Profile = T2P_Base; ++ writeregt(state, 0x23, 0xAD, 0x00); ++ } ++ ++ writebitst(state, 0x2E, 0x10, Profile, 0x07); ++ writeregt(state, 0x2B, 0x19, notT2time); ++} ++ ++static void C2_ReleasePreset(struct cxd_state *state) ++{ ++ { ++ static u8 data[2] = { 0x02, 0x80}; ++ writeregst(state, 0x27, 0xF4, data, sizeof(data)); ++ } ++ writebitst(state, 0x27, 0x51, 0x40, 0xF0); ++ writebitst(state, 0x27, 0x73, 0x07, 0x0F); ++ writebitst(state, 0x27, 0x74, 0x19, 0x3F); ++ writebitst(state, 0x27, 0x75, 0x19, 0x3F); ++ writebitst(state, 0x27, 0x76, 0x19, 0x3F); ++ if (state->bw == 6) { ++ static u8 data[5] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA}; ++ writeregst(state, 0x20, 0x9F, data, sizeof(data)); ++ } else { ++ static u8 data[5] = { 0x11, 0xF0, 0x00, 0x00, 0x00}; ++ writeregst(state, 0x20, 0x9F, data, sizeof(data)); ++ } ++ writebitst(state, 0x27, 0xC9, 0x07, 0x07); ++ writebitst(state, 0x20, 0xC2, 0x11, 0x33); ++ { ++ static u8 data[10] = { 0x16, 0xF0, 0x2B, 0xD8, ++ 0x16, 0x16, 0xF0, 0x2C, 0xD8, 0x16 }; ++ writeregst(state, 0x2A, 0x20, data, sizeof(data)); ++ } ++ { ++ static u8 data[4] = { 0x00, 0x00, 0x00, 0x00 }; ++ writeregst(state, 0x50, 0x6B, data, sizeof(data)); ++ } ++ writebitst(state, 0x50, 0x6F, 0x00, 0x40); /* Disable Preset */ ++} ++ ++static void C2_DemodSetting2(struct cxd_state *state) ++{ ++ u8 data[6]; ++ u32 TunePosition = ++ state->frontend.dtv_property_cache.frequency / 1000; ++ ++ if (state->bw == 6) ++ TunePosition = ((TunePosition * 1792) / 3) / 1000; ++ else ++ TunePosition = (TunePosition * 448) / 1000; ++ ++ TunePosition = ((TunePosition + 6) / 12) * 12; ++ ++ pr_info("TunePosition = %u\n", TunePosition); ++ ++ data[0] = ((TunePosition >> 16) & 0xFF); ++ data[1] = ((TunePosition >> 8) & 0xFF); ++ data[2] = (TunePosition & 0xFF); ++ data[3] = 0x02; ++ data[4] = (state->DataSliceID & 0xFF); ++ data[5] = (state->plp & 0xFF); ++ writeregst(state, 0x50, 0x7A, data, sizeof(data)); ++ writebitst(state, 0x50, 0x87, 0x01, 0x01); /* Preset Clear */ ++} ++ ++static void Stop(struct cxd_state *state) ++{ ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++} ++ ++static void ShutDown(struct cxd_state *state) ++{ ++ switch (state->state) { ++ case ActiveT2: ++ ActiveT2_to_Sleep(state); ++ break; ++ case ActiveC2: ++ ActiveC2_to_Sleep(state); ++ break; ++ default: ++ Active_to_Sleep(state); ++ break; ++ } ++} ++ ++static int gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ ++ return writebitsx(state, 0xFF, 0x08, enable ? 0x01 : 0x00, 0x01); ++} ++ ++static void release(struct dvb_frontend *fe) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ ++ Stop(state); ++ ShutDown(state); ++ kfree(state); ++} ++ ++static int Start(struct cxd_state *state, u32 IntermediateFrequency) ++{ ++ enum EDemodState newDemodState = Unknown; ++ u32 iffreq; ++ ++ if (state->state < Sleep) ++ return -EINVAL; ++ ++ iffreq = MulDiv32(IntermediateFrequency, 16777216, 41000000); ++ ++ switch (state->omode) { ++ case OM_DVBT: ++ if (state->type == CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveT; ++ break; ++ case OM_DVBT2: ++ if (state->type == CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveT2; ++ break; ++ case OM_DVBC: ++ case OM_QAM_ITU_C: ++ if (state->type == CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveC; ++ break; ++ case OM_DVBC2: ++ if (state->type != CXD2843) ++ return -EINVAL; ++ newDemodState = ActiveC2; ++ break; ++ case OM_ISDBT: ++ if (state->type != CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveIT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ state->LockTimeout = 0; ++ state->TSLockTimeout = 0; ++ state->L1PostTimeout = 0; ++ state->last_status = 0; ++ state->FirstTimeLock = 1; ++ state->LastBERNominator = 0; ++ state->LastBERDenominator = 1; ++ state->BERScaleMax = 19; ++ ++ if (state->state == newDemodState) { ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS Output */ ++ switch (newDemodState) { ++ case ActiveT: ++ /* Stick with HP ( 0x01 = LP ) */ ++ writeregt(state, 0x10, 0x67, 0x00); ++ BandSettingT(state, iffreq); ++ state->BERScaleMax = 18; ++ break; ++ case ActiveT2: ++ T2_SetParameters(state); ++ BandSettingT2(state, iffreq); ++ state->BERScaleMax = 12; ++ break; ++ case ActiveC: ++ BandSettingC(state, iffreq); ++ state->BERScaleMax = 19; ++ break; ++ case ActiveC2: ++ BandSettingC2(state, iffreq); ++ C2_ReleasePreset(state); ++ C2_DemodSetting2(state); ++ break; ++ case ActiveIT: ++ BandSettingIT(state, iffreq); ++ break; ++ default: ++ break; ++ } ++ } else { ++ if (state->state > Sleep) { ++ switch (state->state) { ++ case ActiveT2: ++ ActiveT2_to_Sleep(state); ++ break; ++ case ActiveC2: ++ ActiveC2_to_Sleep(state); ++ break; ++ default: ++ Active_to_Sleep(state); ++ break; ++ } ++ } ++ switch (newDemodState) { ++ case ActiveT: ++ /* Stick with HP ( 0x01 = LP ) */ ++ writeregt(state, 0x10, 0x67, 0x00); ++ Sleep_to_ActiveT(state, iffreq); ++ state->BERScaleMax = 18; ++ break; ++ case ActiveT2: ++ T2_SetParameters(state); ++ Sleep_to_ActiveT2(state, iffreq); ++ state->BERScaleMax = 12; ++ break; ++ case ActiveC: ++ Sleep_to_ActiveC(state, iffreq); ++ state->BERScaleMax = 19; ++ break; ++ case ActiveC2: ++ Sleep_to_ActiveC2(state, iffreq); ++ C2_ReleasePreset(state); ++ C2_DemodSetting2(state); ++ break; ++ case ActiveIT: ++ Sleep_to_ActiveIT(state, iffreq); ++ break; ++ default: ++ break; ++ } ++ } ++ state->state = newDemodState; ++ writeregt(state, 0x00, 0xFE, 0x01); /* SW Reset */ ++ writeregt(state, 0x00, 0xC3, 0x00); /* Enable TS Output */ ++ ++ return 0; ++} ++ ++static int set_parameters(struct dvb_frontend *fe) ++{ ++ int stat; ++ struct cxd_state *state = fe->demodulator_priv; ++ u32 IF; ++ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ state->omode = OM_DVBC; ++ break; ++ case SYS_DVBT: ++ state->omode = OM_DVBT; ++ break; ++ case SYS_DVBT2: ++ state->omode = OM_DVBT2; ++ break; ++ case SYS_ISDBT: ++ state->omode = OM_ISDBT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe); ++ state->bandwidth = fe->dtv_property_cache.bandwidth_hz; ++ state->bw = (fe->dtv_property_cache.bandwidth_hz + 999999) / 1000000; ++ if (fe->dtv_property_cache.stream_id == 0xffffffff) { ++ state->DataSliceID = 0xffffffff; ++ state->plp = 0xffffffff; ++ } else { ++ state->DataSliceID = (fe->dtv_property_cache.stream_id >> 8) ++ & 0xff; ++ state->plp = fe->dtv_property_cache.stream_id & 0xff; ++ } ++ /* printk("PLP = %08x, bw = %u\n", state->plp, state->bw); */ ++ fe->ops.tuner_ops.get_if_frequency(fe, &IF); ++ stat = Start(state, IF); ++ return stat; ++} ++ ++ ++static void init(struct cxd_state *state) ++{ ++ u8 data[2] = {0x00, 0x00}; /* 20.5 MHz */ ++ ++ state->omode = OM_NONE; ++ state->state = Unknown; ++ ++ writeregx(state, 0xFF, 0x02, 0x00); ++ usleep_range(4000, 5000); ++ writeregx(state, 0x00, 0x15, 0x01); ++ if (state->type != CXD2838) ++ writeregx(state, 0x00, 0x17, 0x01); ++ usleep_range(4000, 5000); ++ ++ writeregx(state, 0x00, 0x10, 0x01); ++ ++ writeregsx(state, 0x00, 0x13, data, 2); ++ writeregx(state, 0x00, 0x15, 0x00); ++ usleep_range(3000, 4000); ++ writeregx(state, 0x00, 0x10, 0x00); ++ usleep_range(2000, 3000); ++ ++ state->curbankx = 0xFF; ++ state->curbankt = 0xFF; ++ ++ writeregt(state, 0x00, 0x43, 0x0A); ++ writeregt(state, 0x00, 0x41, 0x0A); ++ if (state->type == CXD2838) ++ writeregt(state, 0x60, 0x5A, 0x00); ++ ++ writebitst(state, 0x10, 0xCB, 0x00, 0x40); ++ writeregt(state, 0x10, 0xCD, state->IF_FS); ++ ++ writebitst(state, 0x00, 0xC4, state->SerialMode ? 0x80 : 0x00, 0x98); ++ writebitst(state, 0x00, 0xC5, 0x01, 0x07); ++ writebitst(state, 0x00, 0xCB, 0x00, 0x01); ++ writebitst(state, 0x00, 0xC6, 0x00, 0x1D); ++ writebitst(state, 0x00, 0xC8, 0x01, 0x1D); ++ writebitst(state, 0x00, 0xC9, 0x00, 0x1D); ++ writebitst(state, 0x00, 0x83, 0x00, 0x07); ++ writeregt(state, 0x00, 0x84, 0x00); ++ writebitst(state, 0x00, 0xD3, ++ (state->type == CXD2838) ? 0x01 : 0x00, 0x01); ++ writebitst(state, 0x00, 0xDE, 0x00, 0x01); ++ ++ state->state = Sleep; ++} ++ ++ ++static void init_state(struct cxd_state *state, struct cxd2843_cfg *cfg) ++{ ++ state->adrt = cfg->adr; ++ state->adrx = cfg->adr + 0x02; ++ state->curbankt = 0xff; ++ state->curbankx = 0xff; ++ mutex_init(&state->mutex); ++ ++ state->SerialMode = cfg->parallel ? 0 : 1; ++ state->ContinuousClock = 1; ++ state->SerialClockFrequency = ++ (cfg->ts_clock >= 1 && cfg->ts_clock <= 5) ? ++ cfg->ts_clock : 1; /* 1 = fastest (82 MBit/s), 5 = slowest */ ++ state->SerialClockFrequency = 1; ++ /* IF Fullscale 0x50 = 1.4V, 0x39 = 1V, 0x28 = 0.7V */ ++ state->IF_FS = 0x50; ++} ++ ++static int get_tune_settings(struct dvb_frontend *fe, ++ struct dvb_frontend_tune_settings *sets) ++{ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ case SYS_DVBC_ANNEX_C: ++ /*return c_get_tune_settings(fe, sets);*/ ++ default: ++ /* DVB-T: Use info.frequency_stepsize. */ ++ return -EINVAL; ++ } ++} ++ ++static int read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ u8 rdata; ++ ++ *status = 0; ++ switch (state->state) { ++ case ActiveC: ++ readregst(state, 0x40, 0x88, &rdata, 1); ++ if (rdata & 0x02) ++ break; ++ if (rdata & 0x01) { ++ *status |= 0x07; ++ readregst(state, 0x40, 0x10, &rdata, 1); ++ if (rdata & 0x20) ++ *status |= 0x1f; ++ } ++ break; ++ case ActiveT: ++ readregst(state, 0x10, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if ((rdata & 0x07) == 0x06) { ++ *status |= 0x07; ++ if (rdata & 0x20) ++ *status |= 0x1f; ++ } ++ break; ++ case ActiveT2: ++ readregst(state, 0x20, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if ((rdata & 0x07) == 0x06) { ++ *status |= 0x07; ++ if (rdata & 0x20) ++ *status |= 0x08; ++ } ++ if (*status & 0x08) { ++ readregst(state, 0x22, 0x12, &rdata, 1); ++ if (rdata & 0x01) ++ *status |= 0x10; ++ } ++ break; ++ case ActiveC2: ++ readregst(state, 0x20, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if ((rdata & 0x07) == 0x06) { ++ *status |= 0x07; ++ if (rdata & 0x20) ++ *status |= 0x18; ++ } ++ if ((*status & 0x10) && state->FirstTimeLock) { ++ u8 data; ++ ++ /* Change1stTrial */ ++ readregst(state, 0x28, 0xE6, &rdata, 1); ++ data = rdata & 1; ++ readregst(state, 0x50, 0x15, &rdata, 1); ++ data |= ((rdata & 0x18) >> 2); ++ /*writebitst(state, 0x50,0x6F,rdata,0x07);*/ ++ state->FirstTimeLock = 0; ++ } ++ break; ++ case ActiveIT: ++ readregst(state, 0x60, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if (rdata & 0x02) { ++ *status |= 0x07; ++ if (rdata & 0x01) ++ *status |= 0x18; ++ } ++ break; ++ default: ++ break; ++ } ++ state->last_status = *status; ++ return 0; ++} ++ ++static int get_ber_t(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ u8 BERRegs[3]; ++ u8 Scale; ++ ++ *n = 0; ++ *d = 1; ++ ++ readregst(state, 0x10, 0x62, BERRegs, 3); ++ readregst(state, 0x10, 0x60, &Scale, 1); ++ Scale &= 0x1F; ++ ++ if (BERRegs[0] & 0x80) { ++ state->LastBERNominator = (((u32) BERRegs[0] & 0x3F) << 16) | ++ (((u32) BERRegs[1]) << 8) | BERRegs[2]; ++ state->LastBERDenominator = 1632 << Scale; ++ if (state->LastBERNominator < 256 && ++ Scale < state->BERScaleMax) { ++ writebitst(state, 0x10, 0x60, Scale + 1, 0x1F); ++ } else if (state->LastBERNominator > 512 && Scale > 11) ++ writebitst(state, 0x10, 0x60, Scale - 1, 0x1F); ++ } ++ *n = state->LastBERNominator; ++ *d = state->LastBERDenominator; ++ ++ return 0; ++} ++ ++static int get_ber_t2(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ *n = 0; ++ *d = 1; ++ return 0; ++} ++ ++static int get_ber_c(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ u8 BERRegs[3]; ++ u8 Scale; ++ ++ *n = 0; ++ *d = 1; ++ ++ readregst(state, 0x40, 0x62, BERRegs, 3); ++ readregst(state, 0x40, 0x60, &Scale, 1); ++ Scale &= 0x1F; ++ ++ if (BERRegs[0] & 0x80) { ++ state->LastBERNominator = (((u32) BERRegs[0] & 0x3F) << 16) | ++ (((u32) BERRegs[1]) << 8) | BERRegs[2]; ++ state->LastBERDenominator = 1632 << Scale; ++ if (state->LastBERNominator < 256 && ++ Scale < state->BERScaleMax) { ++ writebitst(state, 0x40, 0x60, Scale + 1, 0x1F); ++ } else if (state->LastBERNominator > 512 && Scale > 11) ++ writebitst(state, 0x40, 0x60, Scale - 1, 0x1F); ++ } ++ *n = state->LastBERNominator; ++ *d = state->LastBERDenominator; ++ ++ return 0; ++} ++ ++static int get_ber_c2(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ *n = 0; ++ *d = 1; ++ return 0; ++} ++ ++static int get_ber_it(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ *n = 0; ++ *d = 1; ++ return 0; ++} ++ ++static int read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ u32 n, d; ++ int s = 0; ++ ++ *ber = 0; ++ switch (state->state) { ++ case ActiveT: ++ s = get_ber_t(state, &n, &d); ++ break; ++ case ActiveT2: ++ s = get_ber_t2(state, &n, &d); ++ break; ++ case ActiveC: ++ s = get_ber_c(state, &n, &d); ++ break; ++ case ActiveC2: ++ s = get_ber_c2(state, &n, &d); ++ break; ++ case ActiveIT: ++ s = get_ber_it(state, &n, &d); ++ break; ++ default: ++ break; ++ } ++ if (s) ++ return s; ++ ++ return 0; ++} ++ ++static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) ++{ ++ if (fe->ops.tuner_ops.get_rf_strength) ++ fe->ops.tuner_ops.get_rf_strength(fe, strength); ++ else ++ *strength = 0; ++ return 0; ++} ++ ++static s32 Log10x100(u32 x) ++{ ++ static u32 LookupTable[100] = { ++ 101157945, 103514217, 105925373, 108392691, 110917482, ++ 113501082, 116144861, 118850223, 121618600, 124451461, ++ 127350308, 130316678, 133352143, 136458314, 139636836, ++ 142889396, 146217717, 149623566, 153108746, 156675107, ++ 160324539, 164058977, 167880402, 171790839, 175792361, ++ 179887092, 184077200, 188364909, 192752491, 197242274, ++ 201836636, 206538016, 211348904, 216271852, 221309471, ++ 226464431, 231739465, 237137371, 242661010, 248313311, ++ 254097271, 260015956, 266072506, 272270131, 278612117, ++ 285101827, 291742701, 298538262, 305492111, 312607937, ++ 319889511, 327340695, 334965439, 342767787, 350751874, ++ 358921935, 367282300, 375837404, 384591782, 393550075, ++ 402717034, 412097519, 421696503, 431519077, 441570447, ++ 451855944, 462381021, 473151259, 484172368, 495450191, ++ 506990708, 518800039, 530884444, 543250331, 555904257, ++ 568852931, 582103218, 595662144, 609536897, 623734835, ++ 638263486, 653130553, 668343918, 683911647, 699841996, ++ 716143410, 732824533, 749894209, 767361489, 785235635, ++ 803526122, 822242650, 841395142, 860993752, 881048873, ++ 901571138, 922571427, 944060876, 966050879, 988553095, ++ }; ++ s32 y; ++ int i; ++ ++ if (x == 0) ++ return 0; ++ y = 800; ++ if (x >= 1000000000) { ++ x /= 10; ++ y += 100; ++ } ++ ++ while (x < 100000000) { ++ x *= 10; ++ y -= 100; ++ } ++ i = 0; ++ while (i < 100 && x > LookupTable[i]) ++ i += 1; ++ y += i; ++ return y; ++} ++ ++#if 0 ++static void GetPLPIds(struct cxd_state *state, u32 nValues, ++ u8 *Values, u32 *Returned) ++{ ++ u8 nPids = 0; ++ ++ *Returned = 0; ++ if (state->state != ActiveT2) ++ return; ++ if (state->last_status != 0x1f) ++ return; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x22, 0x7F, &nPids, 1); ++ ++ Values[0] = nPids; ++ if (nPids >= nValues) ++ nPids = nValues - 1; ++ ++ readregst_unlocked(state, 0x22, 0x80, &Values[1], ++ nPids > 128 ? 128 : nPids); ++ ++ if (nPids > 128) ++ readregst_unlocked(state, 0x23, 0x10, &Values[129], ++ nPids - 128); ++ ++ *Returned = nPids + 1; ++ ++ unfreeze_regst(state); ++} ++#endif ++ ++static void GetSignalToNoiseIT(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x60, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 51441) ++ reg = 51441; ++ ++ if (state->bw == 8) { ++ if (reg > 1143) ++ reg = 1143; ++ *SignalToNoise = (Log10x100(reg) - ++ Log10x100(1200 - reg)) + 220; ++ } else ++ *SignalToNoise = Log10x100(reg) - 90; ++} ++ ++static void GetSignalToNoiseC2(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 51441) ++ reg = 51441; ++ ++ *SignalToNoise = (Log10x100(reg) - Log10x100(55000 - reg)) + 384; ++} ++ ++ ++static void GetSignalToNoiseT2(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 10876) ++ reg = 10876; ++ ++ *SignalToNoise = (Log10x100(reg) - Log10x100(12600 - reg)) + 320; ++} ++ ++static void GetSignalToNoiseT(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x10, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 4996) ++ reg = 4996; ++ ++ *SignalToNoise = (Log10x100(reg) - Log10x100(5350 - reg)) + 285; ++} ++ ++static void GetSignalToNoiseC(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u8 Constellation = 0; ++ u32 reg; ++ ++ *SignalToNoise = 0; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x40, 0x19, &Constellation, 1); ++ readregst_unlocked(state, 0x40, 0x4C, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = ((u32)(Data[0] & 0x1F) << 8) | (Data[1]); ++ if (reg == 0) ++ return; ++ ++ switch (Constellation & 0x07) { ++ case 0: /* QAM 16 */ ++ case 2: /* QAM 64 */ ++ case 4: /* QAM 256 */ ++ if (reg < 126) ++ reg = 126; ++ *SignalToNoise = ((439 - Log10x100(reg)) * 2134 + 500) / 1000; ++ break; ++ case 1: /* QAM 32 */ ++ case 3: /* QAM 128 */ ++ if (reg < 69) ++ reg = 69; ++ *SignalToNoise = ((432 - Log10x100(reg)) * 2015 + 500) / 1000; ++ break; ++ } ++} ++ ++static int read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ u32 SNR = 0; ++ ++ *snr = 0; ++ if (state->last_status != 0x1f) ++ return 0; ++ ++ switch (state->state) { ++ case ActiveC: ++ GetSignalToNoiseC(state, &SNR); ++ break; ++ case ActiveC2: ++ GetSignalToNoiseC2(state, &SNR); ++ break; ++ case ActiveT: ++ GetSignalToNoiseT(state, &SNR); ++ break; ++ case ActiveT2: ++ GetSignalToNoiseT2(state, &SNR); ++ break; ++ case ActiveIT: ++ GetSignalToNoiseIT(state, &SNR); ++ break; ++ default: ++ break; ++ } ++ *snr = SNR; ++ return 0; ++} ++ ++static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ *ucblocks = 0; ++ return 0; ++} ++ ++static int tune(struct dvb_frontend *fe, bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, fe_status_t *status) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ int r; ++ ++ if (re_tune) { ++ r = set_parameters(fe); ++ if (r) ++ return r; ++ state->tune_time = jiffies; ++ ++ } ++ if (*status & FE_HAS_LOCK) ++ return 0; ++ /* *delay = 50; */ ++ r = read_status(fe, status); ++ if (r) ++ return r; ++ return 0; ++} ++ ++static enum dvbfe_search search(struct dvb_frontend *fe) ++{ ++ int r; ++ u32 loops = 20, i; ++ fe_status_t status; ++ ++ r = set_parameters(fe); ++ ++ for (i = 0; i < loops; i++) { ++ msleep(50); ++ r = read_status(fe, &status); ++ if (r) ++ return DVBFE_ALGO_SEARCH_ERROR; ++ if (status & FE_HAS_LOCK) ++ break; ++ } ++ ++ if (status & FE_HAS_LOCK) ++ return DVBFE_ALGO_SEARCH_SUCCESS; ++ else ++ return DVBFE_ALGO_SEARCH_AGAIN; ++} ++ ++static int get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ ++static int get_fe_t(struct cxd_state *state) ++{ ++ struct dvb_frontend *fe = &state->frontend; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ u8 tps[7]; ++ ++ read_tps(state, tps); ++ ++/* TPSData[0] [7:6] CNST[1:0] ++ TPSData[0] [5:3] HIER[2:0] ++ TPSData[0] [2:0] HRATE[2:0] ++*/ ++ switch ((tps[0] >> 6) & 0x03) { ++ case 0: ++ p->modulation = QPSK; ++ break; ++ case 1: ++ p->modulation = QAM_16; ++ break; ++ case 2: ++ p->modulation = QAM_64; ++ break; ++ } ++ switch ((tps[0] >> 3) & 0x07) { ++ case 0: ++ p->hierarchy = HIERARCHY_NONE; ++ break; ++ case 1: ++ p->hierarchy = HIERARCHY_1; ++ break; ++ case 2: ++ p->hierarchy = HIERARCHY_2; ++ break; ++ case 3: ++ p->hierarchy = HIERARCHY_4; ++ break; ++ } ++ switch ((tps[0] >> 0) & 0x07) { ++ case 0: ++ p->code_rate_HP = FEC_1_2; ++ break; ++ case 1: ++ p->code_rate_HP = FEC_2_3; ++ break; ++ case 2: ++ p->code_rate_HP = FEC_3_4; ++ break; ++ case 3: ++ p->code_rate_HP = FEC_5_6; ++ break; ++ case 4: ++ p->code_rate_HP = FEC_7_8; ++ break; ++ } ++ ++/* TPSData[1] [7:5] LRATE[2:0] ++ TPSData[1] [4:3] GI[1:0] ++ TPSData[1] [2:1] MODE[1:0] ++*/ ++ switch ((tps[1] >> 5) & 0x07) { ++ case 0: ++ p->code_rate_LP = FEC_1_2; ++ break; ++ case 1: ++ p->code_rate_LP = FEC_2_3; ++ break; ++ case 2: ++ p->code_rate_LP = FEC_3_4; ++ break; ++ case 3: ++ p->code_rate_LP = FEC_5_6; ++ break; ++ case 4: ++ p->code_rate_LP = FEC_7_8; ++ break; ++ } ++ switch ((tps[1] >> 3) & 0x03) { ++ case 0: ++ p->guard_interval = GUARD_INTERVAL_1_32; ++ break; ++ case 1: ++ p->guard_interval = GUARD_INTERVAL_1_16; ++ break; ++ case 2: ++ p->guard_interval = GUARD_INTERVAL_1_8; ++ break; ++ case 3: ++ p->guard_interval = GUARD_INTERVAL_1_4; ++ break; ++ } ++ switch ((tps[1] >> 1) & 0x03) { ++ case 0: ++ p->transmission_mode = TRANSMISSION_MODE_2K; ++ break; ++ case 1: ++ p->transmission_mode = TRANSMISSION_MODE_8K; ++ break; ++ } ++ ++ return 0; ++} ++ ++static int get_fe_c(struct cxd_state *state) ++{ ++ struct dvb_frontend *fe = &state->frontend; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ u8 qam; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x40, 0x19, &qam, 1); ++ unfreeze_regst(state); ++ p->modulation = qam & 0x07; ++ return 0; ++} ++ ++static int get_frontend(struct dvb_frontend *fe) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ ++ if (state->last_status != 0x1f) ++ return 0; ++ ++ switch (state->state) { ++ case ActiveT: ++ get_fe_t(state); ++ break; ++ case ActiveT2: ++ break; ++ case ActiveC: ++ get_fe_c(state); ++ break; ++ case ActiveC2: ++ break; ++ case ActiveIT: ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static struct dvb_frontend_ops common_ops_2843 = { ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2 }, ++ .info = { ++ .name = "CXD2843 DVB-C/C2 DVB-T/T2", ++ .frequency_stepsize = 166667, /* DVB-T only */ ++ .frequency_min = 47000000, /* DVB-T: 47125000 */ ++ .frequency_max = 865000000, /* DVB-C: 862000000 */ ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = /* DVB-C */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | ++ FE_CAN_FEC_AUTO | ++ /* DVB-T */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | ++ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .set_frontend = set_parameters, ++ ++ .get_tune_settings = get_tune_settings, ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++ .get_frontend = get_frontend, ++#ifdef USE_ALGO ++ .get_frontend_algo = get_algo, ++ .search = search, ++ .tune = tune, ++#endif ++}; ++ ++static struct dvb_frontend_ops common_ops_2837 = { ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2 }, ++ .info = { ++ .name = "CXD2837 DVB-C DVB-T/T2", ++ .frequency_stepsize = 166667, /* DVB-T only */ ++ .frequency_min = 47000000, /* DVB-T: 47125000 */ ++ .frequency_max = 865000000, /* DVB-C: 862000000 */ ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = /* DVB-C */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | ++ FE_CAN_FEC_AUTO | ++ /* DVB-T */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | ++ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .set_frontend = set_parameters, ++ ++ .get_tune_settings = get_tune_settings, ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++ .get_frontend = get_frontend, ++#ifdef USE_ALGO ++ .get_frontend_algo = get_algo, ++ .search = search, ++ .tune = tune, ++#endif ++}; ++ ++static struct dvb_frontend_ops common_ops_2838 = { ++ .delsys = { SYS_ISDBT }, ++ .info = { ++ .name = "CXD2838 ISDB-T", ++ .frequency_stepsize = 166667, ++ .frequency_min = 47000000, ++ .frequency_max = 865000000, ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | ++ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .set_frontend = set_parameters, ++ ++ .get_tune_settings = get_tune_settings, ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++#ifdef USE_ALGO ++ .get_frontend_algo = get_algo, ++ .search = search, ++ .tune = tune, ++#endif ++}; ++ ++static int probe(struct cxd_state *state) ++{ ++ u8 ChipID = 0x00; ++ int status; ++ ++ status = readregst(state, 0x00, 0xFD, &ChipID, 1); ++ ++ if (status) ++ status = readregsx(state, 0x00, 0xFD, &ChipID, 1); ++ if (status) ++ return status; ++ ++ /*printk("ChipID = %02X\n", ChipID);*/ ++ switch (ChipID) { ++ case 0xa4: ++ state->type = CXD2843; ++ memcpy(&state->frontend.ops, &common_ops_2843, ++ sizeof(struct dvb_frontend_ops)); ++ break; ++ case 0xb1: ++ state->type = CXD2837; ++ memcpy(&state->frontend.ops, &common_ops_2837, ++ sizeof(struct dvb_frontend_ops)); ++ break; ++ case 0xb0: ++ state->type = CXD2838; ++ memcpy(&state->frontend.ops, &common_ops_2838, ++ sizeof(struct dvb_frontend_ops)); ++ break; ++ default: ++ return -1; ++ } ++ state->frontend.demodulator_priv = state; ++ return 0; ++} ++ ++struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, ++ struct cxd2843_cfg *cfg) ++{ ++ struct cxd_state *state = NULL; ++ ++ state = kzalloc(sizeof(struct cxd_state), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ ++ state->i2c = i2c; ++ init_state(state, cfg); ++ if (probe(state) == 0) { ++ init(state); ++ return &state->frontend; ++ } ++ pr_err("cxd2843: not found\n"); ++ kfree(state); ++ return NULL; ++} ++EXPORT_SYMBOL(cxd2843_attach); ++ ++MODULE_DESCRIPTION("CXD2843/37/38 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb-frontends/cxd2843.h b/drivers/media/dvb-frontends/cxd2843.h +new file mode 100644 +index 0000000..f3e355b +--- /dev/null ++++ b/drivers/media/dvb-frontends/cxd2843.h +@@ -0,0 +1,30 @@ ++#ifndef _CXD2843_H_ ++#define _CXD2843_H_ ++ ++#include ++#include ++ ++struct cxd2843_cfg { ++ u8 adr; ++ u32 ts_clock; ++ u8 parallel; ++}; ++ ++#if defined(CONFIG_DVB_CXD2843) || \ ++ (defined(CONFIG_DVB_CXD2843_MODULE) && defined(MODULE)) ++ ++extern struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, ++ struct cxd2843_cfg *cfg); ++ ++#else ++ ++static inline struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, ++ struct cxd2843_cfg *cfg) ++{ ++ pr_warn("%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++ ++#endif ++ ++#endif +diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c +index d46cf5f..91a7f9f 100644 +--- a/drivers/media/dvb-frontends/drxk_hard.c ++++ b/drivers/media/dvb-frontends/drxk_hard.c +@@ -21,8 +21,6 @@ + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include +@@ -30,42 +28,50 @@ + #include + #include + #include +-#include + #include + + #include "dvb_frontend.h" + #include "drxk.h" + #include "drxk_hard.h" +-#include "dvb_math.h" +- +-static int power_down_dvbt(struct drxk_state *state, bool set_power_mode); +-static int power_down_qam(struct drxk_state *state); +-static int set_dvbt_standard(struct drxk_state *state, +- enum operation_mode o_mode); +-static int set_qam_standard(struct drxk_state *state, +- enum operation_mode o_mode); +-static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset); +-static int set_dvbt_standard(struct drxk_state *state, +- enum operation_mode o_mode); +-static int dvbt_start(struct drxk_state *state); +-static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset); +-static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status); +-static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status); +-static int switch_antenna_to_qam(struct drxk_state *state); +-static int switch_antenna_to_dvbt(struct drxk_state *state); +- +-static bool is_dvbt(struct drxk_state *state) ++ ++static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode); ++static int PowerDownQAM(struct drxk_state *state); ++static int SetDVBTStandard(struct drxk_state *state, ++ enum OperationMode oMode); ++static int SetQAMStandard(struct drxk_state *state, ++ enum OperationMode oMode); ++static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset); ++static int SetDVBTStandard(struct drxk_state *state, ++ enum OperationMode oMode); ++static int DVBTStart(struct drxk_state *state); ++static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset); ++static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus); ++static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus); ++static int SwitchAntennaToQAM(struct drxk_state *state); ++static int SwitchAntennaToDVBT(struct drxk_state *state); ++ ++static bool IsDVBT(struct drxk_state *state) ++{ ++ return state->m_OperationMode == OM_DVBT; ++} ++ ++static bool IsQAM(struct drxk_state *state) ++{ ++ return state->m_OperationMode == OM_QAM_ITU_A || ++ state->m_OperationMode == OM_QAM_ITU_B || ++ state->m_OperationMode == OM_QAM_ITU_C; ++} ++ ++bool IsA1WithPatchCode(struct drxk_state *state) + { +- return state->m_operation_mode == OM_DVBT; ++ return state->m_DRXK_A1_PATCH_CODE; + } + +-static bool is_qam(struct drxk_state *state) ++bool IsA1WithRomCode(struct drxk_state *state) + { +- return state->m_operation_mode == OM_QAM_ITU_A || +- state->m_operation_mode == OM_QAM_ITU_B || +- state->m_operation_mode == OM_QAM_ITU_C; ++ return state->m_DRXK_A1_ROM_CODE; + } + + #define NOA1ROM 0 +@@ -166,9 +172,9 @@ static unsigned int debug; + module_param(debug, int, 0644); + MODULE_PARM_DESC(debug, "enable debug messages"); + +-#define dprintk(level, fmt, arg...) do { \ +-if (debug >= level) \ +- printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \ ++#define dprintk(level, fmt, arg...) do { \ ++if (debug >= level) \ ++ printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \ + } while (0) + + +@@ -182,17 +188,15 @@ static inline u32 MulDiv32(u32 a, u32 b, u32 c) + return (u32) tmp64; + } + +-static inline u32 Frac28a(u32 a, u32 c) ++inline u32 Frac28a(u32 a, u32 c) + { + int i = 0; + u32 Q1 = 0; + u32 R0 = 0; + + R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */ +- Q1 = a / c; /* +- * integer part, only the 4 least significant +- * bits will be visible in the result +- */ ++ Q1 = a / c; /* integer part, only the 4 least significant bits ++ will be visible in the result */ + + /* division using radix 16, 7 nibbles in the result */ + for (i = 0; i < 7; i++) { +@@ -206,51 +210,114 @@ static inline u32 Frac28a(u32 a, u32 c) + return Q1; + } + +-static inline u32 log10times100(u32 value) ++static u32 Log10Times100(u32 x) + { +- return (100L * intlog10(value)) >> 24; +-} +- +-/****************************************************************************/ +-/* I2C **********************************************************************/ +-/****************************************************************************/ ++ static const u8 scale = 15; ++ static const u8 indexWidth = 5; ++ u8 i = 0; ++ u32 y = 0; ++ u32 d = 0; ++ u32 k = 0; ++ u32 r = 0; ++ /* ++ log2lut[n] = (1<i2c); +- state->drxk_i2c_exclusive_lock = true; ++ static const u32 log2lut[] = { ++ 0, /* 0.000000 */ ++ 290941, /* 290941.300628 */ ++ 573196, /* 573196.476418 */ ++ 847269, /* 847269.179851 */ ++ 1113620, /* 1113620.489452 */ ++ 1372674, /* 1372673.576986 */ ++ 1624818, /* 1624817.752104 */ ++ 1870412, /* 1870411.981536 */ ++ 2109788, /* 2109787.962654 */ ++ 2343253, /* 2343252.817465 */ ++ 2571091, /* 2571091.461923 */ ++ 2793569, /* 2793568.696416 */ ++ 3010931, /* 3010931.055901 */ ++ 3223408, /* 3223408.452106 */ ++ 3431216, /* 3431215.635215 */ ++ 3634553, /* 3634553.498355 */ ++ 3833610, /* 3833610.244726 */ ++ 4028562, /* 4028562.434393 */ ++ 4219576, /* 4219575.925308 */ ++ 4406807, /* 4406806.721144 */ ++ 4590402, /* 4590401.736809 */ ++ 4770499, /* 4770499.491025 */ ++ 4947231, /* 4947230.734179 */ ++ 5120719, /* 5120719.018555 */ ++ 5291081, /* 5291081.217197 */ ++ 5458428, /* 5458427.996830 */ ++ 5622864, /* 5622864.249668 */ ++ 5784489, /* 5784489.488298 */ ++ 5943398, /* 5943398.207380 */ ++ 6099680, /* 6099680.215452 */ ++ 6253421, /* 6253420.939751 */ ++ 6404702, /* 6404701.706649 */ ++ 6553600, /* 6553600.000000 */ ++ }; + +- return 0; +-} + +-static void drxk_i2c_unlock(struct drxk_state *state) +-{ +- if (!state->drxk_i2c_exclusive_lock) +- return; ++ if (x == 0) ++ return 0; + +- i2c_unlock_adapter(state->i2c); +- state->drxk_i2c_exclusive_lock = false; ++ /* Scale x (normalize) */ ++ /* computing y in log(x/y) = log(x) - log(y) */ ++ if ((x & ((0xffffffff) << (scale + 1))) == 0) { ++ for (k = scale; k > 0; k--) { ++ if (x & (((u32) 1) << scale)) ++ break; ++ x <<= 1; ++ } ++ } else { ++ for (k = scale; k < 31; k++) { ++ if ((x & (((u32) (-1)) << (scale + 1))) == 0) ++ break; ++ x >>= 1; ++ } ++ } ++ /* ++ Now x has binary point between bit[scale] and bit[scale-1] ++ and 1.0 <= x < 2.0 */ ++ ++ /* correction for divison: log(x) = log(x/y)+log(y) */ ++ y = k * ((((u32) 1) << scale) * 200); ++ ++ /* remove integer part */ ++ x &= ((((u32) 1) << scale) - 1); ++ /* get index */ ++ i = (u8) (x >> (scale - indexWidth)); ++ /* compute delta (x - a) */ ++ d = x & ((((u32) 1) << (scale - indexWidth)) - 1); ++ /* compute log, multiplication (d* (..)) must be within range ! */ ++ y += log2lut[i] + ++ ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth)); ++ /* Conver to log10() */ ++ y /= 108853; /* (log2(10) << scale) */ ++ r = (y >> 1); ++ /* rounding */ ++ if (y & ((u32) 1)) ++ r++; ++ return r; + } + +-static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, +- unsigned len) +-{ +- if (state->drxk_i2c_exclusive_lock) +- return __i2c_transfer(state->i2c, msgs, len); +- else +- return i2c_transfer(state->i2c, msgs, len); +-} ++/****************************************************************************/ ++/* I2C **********************************************************************/ ++/****************************************************************************/ + +-static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) ++static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val) + { + struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, + .buf = val, .len = 1} + }; + +- return drxk_i2c_transfer(state, msgs, 1); ++ return i2c_transfer(adapter, msgs, 1); + } + +-static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) + { + int status; + struct i2c_msg msg = { +@@ -260,20 +327,20 @@ static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) + if (debug > 2) { + int i; + for (i = 0; i < len; i++) +- pr_cont(" %02x", data[i]); +- pr_cont("\n"); ++ printk(KERN_CONT " %02x", data[i]); ++ printk(KERN_CONT "\n"); + } +- status = drxk_i2c_transfer(state, &msg, 1); ++ status = i2c_transfer(adap, &msg, 1); + if (status >= 0 && status != 1) + status = -EIO; + + if (status < 0) +- pr_err("i2c write error at addr 0x%02x\n", adr); ++ printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr); + + return status; + } + +-static int i2c_read(struct drxk_state *state, ++static int i2c_read(struct i2c_adapter *adap, + u8 adr, u8 *msg, int len, u8 *answ, int alen) + { + int status; +@@ -284,25 +351,25 @@ static int i2c_read(struct drxk_state *state, + .buf = answ, .len = alen} + }; + +- status = drxk_i2c_transfer(state, msgs, 2); ++ status = i2c_transfer(adap, msgs, 2); + if (status != 2) { + if (debug > 2) +- pr_cont(": ERROR!\n"); ++ printk(KERN_CONT ": ERROR!\n"); + if (status >= 0) + status = -EIO; + +- pr_err("i2c read error at addr 0x%02x\n", adr); ++ printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr); + return status; + } + if (debug > 2) { + int i; + dprintk(2, ": read from"); + for (i = 0; i < len; i++) +- pr_cont(" %02x", msg[i]); +- pr_cont(", value = "); ++ printk(KERN_CONT " %02x", msg[i]); ++ printk(KERN_CONT ", value = "); + for (i = 0; i < alen; i++) +- pr_cont(" %02x", answ[i]); +- pr_cont("\n"); ++ printk(KERN_CONT " %02x", answ[i]); ++ printk(KERN_CONT "\n"); + } + return 0; + } +@@ -327,7 +394,7 @@ static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) + len = 2; + } + dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); +- status = i2c_read(state, adr, mm1, len, mm2, 2); ++ status = i2c_read(state->i2c, adr, mm1, len, mm2, 2); + if (status < 0) + return status; + if (data) +@@ -361,7 +428,7 @@ static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) + len = 2; + } + dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); +- status = i2c_read(state, adr, mm1, len, mm2, 4); ++ status = i2c_read(state->i2c, adr, mm1, len, mm2, 4); + if (status < 0) + return status; + if (data) +@@ -397,7 +464,7 @@ static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) + mm[len + 1] = (data >> 8) & 0xff; + + dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); +- return i2c_write(state, adr, mm, len + 2); ++ return i2c_write(state->i2c, adr, mm, len + 2); + } + + static int write16(struct drxk_state *state, u32 reg, u16 data) +@@ -428,7 +495,7 @@ static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) + mm[len + 3] = (data >> 24) & 0xff; + dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); + +- return i2c_write(state, adr, mm, len + 4); ++ return i2c_write(state->i2c, adr, mm, len + 4); + } + + static int write32(struct drxk_state *state, u32 reg, u32 data) +@@ -436,55 +503,55 @@ static int write32(struct drxk_state *state, u32 reg, u32 data) + return write32_flags(state, reg, data, 0); + } + +-static int write_block(struct drxk_state *state, u32 address, +- const int block_size, const u8 p_block[]) ++static int write_block(struct drxk_state *state, u32 Address, ++ const int BlockSize, const u8 pBlock[]) + { +- int status = 0, blk_size = block_size; +- u8 flags = 0; ++ int status = 0, BlkSize = BlockSize; ++ u8 Flags = 0; + + if (state->single_master) +- flags |= 0xC0; +- +- while (blk_size > 0) { +- int chunk = blk_size > state->m_chunk_size ? +- state->m_chunk_size : blk_size; +- u8 *adr_buf = &state->chunk[0]; +- u32 adr_length = 0; +- +- if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) { +- adr_buf[0] = (((address << 1) & 0xFF) | 0x01); +- adr_buf[1] = ((address >> 16) & 0xFF); +- adr_buf[2] = ((address >> 24) & 0xFF); +- adr_buf[3] = ((address >> 7) & 0xFF); +- adr_buf[2] |= flags; +- adr_length = 4; +- if (chunk == state->m_chunk_size) +- chunk -= 2; ++ Flags |= 0xC0; ++ ++ while (BlkSize > 0) { ++ int Chunk = BlkSize > state->m_ChunkSize ? ++ state->m_ChunkSize : BlkSize; ++ u8 *AdrBuf = &state->Chunk[0]; ++ u32 AdrLength = 0; ++ ++ if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) { ++ AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01); ++ AdrBuf[1] = ((Address >> 16) & 0xFF); ++ AdrBuf[2] = ((Address >> 24) & 0xFF); ++ AdrBuf[3] = ((Address >> 7) & 0xFF); ++ AdrBuf[2] |= Flags; ++ AdrLength = 4; ++ if (Chunk == state->m_ChunkSize) ++ Chunk -= 2; + } else { +- adr_buf[0] = ((address << 1) & 0xFF); +- adr_buf[1] = (((address >> 16) & 0x0F) | +- ((address >> 18) & 0xF0)); +- adr_length = 2; ++ AdrBuf[0] = ((Address << 1) & 0xFF); ++ AdrBuf[1] = (((Address >> 16) & 0x0F) | ++ ((Address >> 18) & 0xF0)); ++ AdrLength = 2; + } +- memcpy(&state->chunk[adr_length], p_block, chunk); +- dprintk(2, "(0x%08x, 0x%02x)\n", address, flags); ++ memcpy(&state->Chunk[AdrLength], pBlock, Chunk); ++ dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags); + if (debug > 1) { + int i; +- if (p_block) +- for (i = 0; i < chunk; i++) +- pr_cont(" %02x", p_block[i]); +- pr_cont("\n"); ++ if (pBlock) ++ for (i = 0; i < Chunk; i++) ++ printk(KERN_CONT " %02x", pBlock[i]); ++ printk(KERN_CONT "\n"); + } +- status = i2c_write(state, state->demod_address, +- &state->chunk[0], chunk + adr_length); ++ status = i2c_write(state->i2c, state->demod_address, ++ &state->Chunk[0], Chunk + AdrLength); + if (status < 0) { +- pr_err("%s: i2c write error at addr 0x%02x\n", +- __func__, address); ++ printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n", ++ __func__, Address); + break; + } +- p_block += chunk; +- address += (chunk >> 1); +- blk_size -= chunk; ++ pBlock += Chunk; ++ Address += (Chunk >> 1); ++ BlkSize -= Chunk; + } + return status; + } +@@ -493,29 +560,29 @@ static int write_block(struct drxk_state *state, u32 address, + #define DRXK_MAX_RETRIES_POWERUP 20 + #endif + +-static int power_up_device(struct drxk_state *state) ++int PowerUpDevice(struct drxk_state *state) + { + int status; + u8 data = 0; +- u16 retry_count = 0; ++ u16 retryCount = 0; + + dprintk(1, "\n"); + +- status = i2c_read1(state, state->demod_address, &data); ++ status = i2c_read1(state->i2c, state->demod_address, &data); + if (status < 0) { + do { + data = 0; +- status = i2c_write(state, state->demod_address, ++ status = i2c_write(state->i2c, state->demod_address, + &data, 1); +- usleep_range(10000, 11000); +- retry_count++; ++ msleep(10); ++ retryCount++; + if (status < 0) + continue; +- status = i2c_read1(state, state->demod_address, ++ status = i2c_read1(state->i2c, state->demod_address, + &data); + } while (status < 0 && +- (retry_count < DRXK_MAX_RETRIES_POWERUP)); +- if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP) ++ (retryCount < DRXK_MAX_RETRIES_POWERUP)); ++ if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP) + goto error; + } + +@@ -531,11 +598,11 @@ static int power_up_device(struct drxk_state *state) + if (status < 0) + goto error; + +- state->m_current_power_mode = DRX_POWER_UP; ++ state->m_currentPowerMode = DRX_POWER_UP; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -547,106 +614,111 @@ static int init_state(struct drxk_state *state) + * FIXME: most (all?) of the values bellow should be moved into + * struct drxk_config, as they are probably board-specific + */ +- u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO; +- u32 ul_vsb_if_agc_output_level = 0; +- u32 ul_vsb_if_agc_min_level = 0; +- u32 ul_vsb_if_agc_max_level = 0x7FFF; +- u32 ul_vsb_if_agc_speed = 3; +- +- u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO; +- u32 ul_vsb_rf_agc_output_level = 0; +- u32 ul_vsb_rf_agc_min_level = 0; +- u32 ul_vsb_rf_agc_max_level = 0x7FFF; +- u32 ul_vsb_rf_agc_speed = 3; +- u32 ul_vsb_rf_agc_top = 9500; +- u32 ul_vsb_rf_agc_cut_off_current = 4000; +- +- u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO; +- u32 ul_atv_if_agc_output_level = 0; +- u32 ul_atv_if_agc_min_level = 0; +- u32 ul_atv_if_agc_max_level = 0; +- u32 ul_atv_if_agc_speed = 3; +- +- u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF; +- u32 ul_atv_rf_agc_output_level = 0; +- u32 ul_atv_rf_agc_min_level = 0; +- u32 ul_atv_rf_agc_max_level = 0; +- u32 ul_atv_rf_agc_top = 9500; +- u32 ul_atv_rf_agc_cut_off_current = 4000; +- u32 ul_atv_rf_agc_speed = 3; ++ u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO; ++ u32 ulVSBIfAgcOutputLevel = 0; ++ u32 ulVSBIfAgcMinLevel = 0; ++ u32 ulVSBIfAgcMaxLevel = 0x7FFF; ++ u32 ulVSBIfAgcSpeed = 3; ++ ++ u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO; ++ u32 ulVSBRfAgcOutputLevel = 0; ++ u32 ulVSBRfAgcMinLevel = 0; ++ u32 ulVSBRfAgcMaxLevel = 0x7FFF; ++ u32 ulVSBRfAgcSpeed = 3; ++ u32 ulVSBRfAgcTop = 9500; ++ u32 ulVSBRfAgcCutOffCurrent = 4000; ++ ++ u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO; ++ u32 ulATVIfAgcOutputLevel = 0; ++ u32 ulATVIfAgcMinLevel = 0; ++ u32 ulATVIfAgcMaxLevel = 0; ++ u32 ulATVIfAgcSpeed = 3; ++ ++ u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF; ++ u32 ulATVRfAgcOutputLevel = 0; ++ u32 ulATVRfAgcMinLevel = 0; ++ u32 ulATVRfAgcMaxLevel = 0; ++ u32 ulATVRfAgcTop = 9500; ++ u32 ulATVRfAgcCutOffCurrent = 4000; ++ u32 ulATVRfAgcSpeed = 3; + + u32 ulQual83 = DEFAULT_MER_83; + u32 ulQual93 = DEFAULT_MER_93; + +- u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; +- u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; ++ u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; ++ u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; + + /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ + /* io_pad_cfg_mode output mode is drive always */ + /* io_pad_cfg_drive is set to power 2 (23 mA) */ +- u32 ul_gpio_cfg = 0x0113; +- u32 ul_invert_ts_clock = 0; +- u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; +- u32 ul_dvbt_bitrate = 50000000; +- u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; ++ u32 ulGPIOCfg = 0x0113; ++ u32 ulInvertTSClock = 0; ++ u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; ++ u32 ulDVBTBitrate = 50000000; ++ u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; + +- u32 ul_insert_rs_byte = 0; ++ u32 ulInsertRSByte = 0; + +- u32 ul_rf_mirror = 1; +- u32 ul_power_down = 0; ++ u32 ulRfMirror = 1; ++ u32 ulPowerDown = 0; + + dprintk(1, "\n"); + +- state->m_has_lna = false; +- state->m_has_dvbt = false; +- state->m_has_dvbc = false; +- state->m_has_atv = false; +- state->m_has_oob = false; +- state->m_has_audio = false; ++ state->m_hasLNA = false; ++ state->m_hasDVBT = false; ++ state->m_hasDVBC = false; ++ state->m_hasATV = false; ++ state->m_hasOOB = false; ++ state->m_hasAudio = false; + +- if (!state->m_chunk_size) +- state->m_chunk_size = 124; ++ if (!state->m_ChunkSize) ++ state->m_ChunkSize = 124; + +- state->m_osc_clock_freq = 0; +- state->m_smart_ant_inverted = false; +- state->m_b_p_down_open_bridge = false; ++ state->m_oscClockFreq = 0; ++ state->m_smartAntInverted = false; ++ state->m_bPDownOpenBridge = false; + + /* real system clock frequency in kHz */ +- state->m_sys_clock_freq = 151875; ++ state->m_sysClockFreq = 151875; + /* Timing div, 250ns/Psys */ + /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */ +- state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) * ++ state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) * + HI_I2C_DELAY) / 1000; + /* Clipping */ +- if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) +- state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; +- state->m_hi_cfg_wake_up_key = (state->demod_address << 1); ++ if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) ++ state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; ++ state->m_HICfgWakeUpKey = (state->demod_address << 1); + /* port/bridge/power down ctrl */ +- state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; ++ state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; + +- state->m_b_power_down = (ul_power_down != 0); ++ state->m_bPowerDown = (ulPowerDown != 0); + +- state->m_drxk_a3_patch_code = false; ++ state->m_DRXK_A1_PATCH_CODE = false; ++ state->m_DRXK_A1_ROM_CODE = false; ++ state->m_DRXK_A2_ROM_CODE = false; ++ state->m_DRXK_A3_ROM_CODE = false; ++ state->m_DRXK_A2_PATCH_CODE = false; ++ state->m_DRXK_A3_PATCH_CODE = false; + + /* Init AGC and PGA parameters */ + /* VSB IF */ +- state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode; +- state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level; +- state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level; +- state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level; +- state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed; +- state->m_vsb_pga_cfg = 140; ++ state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode); ++ state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel); ++ state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel); ++ state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel); ++ state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed); ++ state->m_vsbPgaCfg = 140; + + /* VSB RF */ +- state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode; +- state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level; +- state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level; +- state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level; +- state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed; +- state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top; +- state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current; +- state->m_vsb_pre_saw_cfg.reference = 0x07; +- state->m_vsb_pre_saw_cfg.use_pre_saw = true; ++ state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode); ++ state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel); ++ state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel); ++ state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel); ++ state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed); ++ state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop); ++ state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent); ++ state->m_vsbPreSawCfg.reference = 0x07; ++ state->m_vsbPreSawCfg.usePreSaw = true; + + state->m_Quality83percent = DEFAULT_MER_83; + state->m_Quality93percent = DEFAULT_MER_93; +@@ -656,127 +728,127 @@ static int init_state(struct drxk_state *state) + } + + /* ATV IF */ +- state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode; +- state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level; +- state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level; +- state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level; +- state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed; ++ state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode); ++ state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel); ++ state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel); ++ state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel); ++ state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed); + + /* ATV RF */ +- state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode; +- state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level; +- state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level; +- state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level; +- state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed; +- state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top; +- state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current; +- state->m_atv_pre_saw_cfg.reference = 0x04; +- state->m_atv_pre_saw_cfg.use_pre_saw = true; ++ state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode); ++ state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel); ++ state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel); ++ state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel); ++ state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed); ++ state->m_atvRfAgcCfg.top = (ulATVRfAgcTop); ++ state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent); ++ state->m_atvPreSawCfg.reference = 0x04; ++ state->m_atvPreSawCfg.usePreSaw = true; + + + /* DVBT RF */ +- state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; +- state->m_dvbt_rf_agc_cfg.output_level = 0; +- state->m_dvbt_rf_agc_cfg.min_output_level = 0; +- state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF; +- state->m_dvbt_rf_agc_cfg.top = 0x2100; +- state->m_dvbt_rf_agc_cfg.cut_off_current = 4000; +- state->m_dvbt_rf_agc_cfg.speed = 1; ++ state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF; ++ state->m_dvbtRfAgcCfg.outputLevel = 0; ++ state->m_dvbtRfAgcCfg.minOutputLevel = 0; ++ state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF; ++ state->m_dvbtRfAgcCfg.top = 0x2100; ++ state->m_dvbtRfAgcCfg.cutOffCurrent = 4000; ++ state->m_dvbtRfAgcCfg.speed = 1; + + + /* DVBT IF */ +- state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; +- state->m_dvbt_if_agc_cfg.output_level = 0; +- state->m_dvbt_if_agc_cfg.min_output_level = 0; +- state->m_dvbt_if_agc_cfg.max_output_level = 9000; +- state->m_dvbt_if_agc_cfg.top = 13424; +- state->m_dvbt_if_agc_cfg.cut_off_current = 0; +- state->m_dvbt_if_agc_cfg.speed = 3; +- state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30; +- state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000; ++ state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO; ++ state->m_dvbtIfAgcCfg.outputLevel = 0; ++ state->m_dvbtIfAgcCfg.minOutputLevel = 0; ++ state->m_dvbtIfAgcCfg.maxOutputLevel = 9000; ++ state->m_dvbtIfAgcCfg.top = 13424; ++ state->m_dvbtIfAgcCfg.cutOffCurrent = 0; ++ state->m_dvbtIfAgcCfg.speed = 3; ++ state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30; ++ state->m_dvbtIfAgcCfg.IngainTgtMax = 30000; + /* state->m_dvbtPgaCfg = 140; */ + +- state->m_dvbt_pre_saw_cfg.reference = 4; +- state->m_dvbt_pre_saw_cfg.use_pre_saw = false; ++ state->m_dvbtPreSawCfg.reference = 4; ++ state->m_dvbtPreSawCfg.usePreSaw = false; + + /* QAM RF */ +- state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; +- state->m_qam_rf_agc_cfg.output_level = 0; +- state->m_qam_rf_agc_cfg.min_output_level = 6023; +- state->m_qam_rf_agc_cfg.max_output_level = 27000; +- state->m_qam_rf_agc_cfg.top = 0x2380; +- state->m_qam_rf_agc_cfg.cut_off_current = 4000; +- state->m_qam_rf_agc_cfg.speed = 3; ++ state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF; ++ state->m_qamRfAgcCfg.outputLevel = 0; ++ state->m_qamRfAgcCfg.minOutputLevel = 6023; ++ state->m_qamRfAgcCfg.maxOutputLevel = 27000; ++ state->m_qamRfAgcCfg.top = 0x2380; ++ state->m_qamRfAgcCfg.cutOffCurrent = 4000; ++ state->m_qamRfAgcCfg.speed = 3; + + /* QAM IF */ +- state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; +- state->m_qam_if_agc_cfg.output_level = 0; +- state->m_qam_if_agc_cfg.min_output_level = 0; +- state->m_qam_if_agc_cfg.max_output_level = 9000; +- state->m_qam_if_agc_cfg.top = 0x0511; +- state->m_qam_if_agc_cfg.cut_off_current = 0; +- state->m_qam_if_agc_cfg.speed = 3; +- state->m_qam_if_agc_cfg.ingain_tgt_max = 5119; +- state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50; +- +- state->m_qam_pga_cfg = 140; +- state->m_qam_pre_saw_cfg.reference = 4; +- state->m_qam_pre_saw_cfg.use_pre_saw = false; +- +- state->m_operation_mode = OM_NONE; +- state->m_drxk_state = DRXK_UNINITIALIZED; ++ state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO; ++ state->m_qamIfAgcCfg.outputLevel = 0; ++ state->m_qamIfAgcCfg.minOutputLevel = 0; ++ state->m_qamIfAgcCfg.maxOutputLevel = 9000; ++ state->m_qamIfAgcCfg.top = 0x0511; ++ state->m_qamIfAgcCfg.cutOffCurrent = 0; ++ state->m_qamIfAgcCfg.speed = 3; ++ state->m_qamIfAgcCfg.IngainTgtMax = 5119; ++ state->m_qamIfAgcCfg.FastClipCtrlDelay = 50; ++ ++ state->m_qamPgaCfg = 140; ++ state->m_qamPreSawCfg.reference = 4; ++ state->m_qamPreSawCfg.usePreSaw = false; ++ ++ state->m_OperationMode = OM_NONE; ++ state->m_DrxkState = DRXK_UNINITIALIZED; + + /* MPEG output configuration */ +- state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */ +- state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */ +- state->m_invert_data = false; /* If TRUE; invert DATA signals */ +- state->m_invert_err = false; /* If TRUE; invert ERR signal */ +- state->m_invert_str = false; /* If TRUE; invert STR signals */ +- state->m_invert_val = false; /* If TRUE; invert VAL signals */ +- state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */ ++ state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */ ++ state->m_insertRSByte = false; /* If TRUE; insert RS byte */ ++ state->m_invertDATA = false; /* If TRUE; invert DATA signals */ ++ state->m_invertERR = false; /* If TRUE; invert ERR signal */ ++ state->m_invertSTR = false; /* If TRUE; invert STR signals */ ++ state->m_invertVAL = false; /* If TRUE; invert VAL signals */ ++ state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ + + /* If TRUE; static MPEG clockrate will be used; + otherwise clockrate will adapt to the bitrate of the TS */ + +- state->m_dvbt_bitrate = ul_dvbt_bitrate; +- state->m_dvbc_bitrate = ul_dvbc_bitrate; ++ state->m_DVBTBitrate = ulDVBTBitrate; ++ state->m_DVBCBitrate = ulDVBCBitrate; + +- state->m_ts_data_strength = (ul_ts_data_strength & 0x07); ++ state->m_TSDataStrength = (ulTSDataStrength & 0x07); + + /* Maximum bitrate in b/s in case static clockrate is selected */ +- state->m_mpeg_ts_static_bitrate = 19392658; +- state->m_disable_te_ihandling = false; ++ state->m_mpegTsStaticBitrate = 19392658; ++ state->m_disableTEIhandling = false; + +- if (ul_insert_rs_byte) +- state->m_insert_rs_byte = true; ++ if (ulInsertRSByte) ++ state->m_insertRSByte = true; + +- state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; +- if (ul_mpeg_lock_time_out < 10000) +- state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out; +- state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; +- if (ul_demod_lock_time_out < 10000) +- state->m_demod_lock_time_out = ul_demod_lock_time_out; ++ state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; ++ if (ulMpegLockTimeOut < 10000) ++ state->m_MpegLockTimeOut = ulMpegLockTimeOut; ++ state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; ++ if (ulDemodLockTimeOut < 10000) ++ state->m_DemodLockTimeOut = ulDemodLockTimeOut; + + /* QAM defaults */ +- state->m_constellation = DRX_CONSTELLATION_AUTO; +- state->m_qam_interleave_mode = DRXK_QAM_I12_J17; +- state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */ +- state->m_fec_rs_prescale = 1; ++ state->m_Constellation = DRX_CONSTELLATION_AUTO; ++ state->m_qamInterleaveMode = DRXK_QAM_I12_J17; ++ state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */ ++ state->m_fecRsPrescale = 1; + +- state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM; +- state->m_agcfast_clip_ctrl_delay = 0; ++ state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM; ++ state->m_agcFastClipCtrlDelay = 0; + +- state->m_gpio_cfg = ul_gpio_cfg; ++ state->m_GPIOCfg = (ulGPIOCfg); + +- state->m_b_power_down = false; +- state->m_current_power_mode = DRX_POWER_DOWN; ++ state->m_bPowerDown = false; ++ state->m_currentPowerMode = DRX_POWER_DOWN; + +- state->m_rfmirror = (ul_rf_mirror == 0); +- state->m_if_agc_pol = false; ++ state->m_rfmirror = (ulRfMirror == 0); ++ state->m_IfAgcPol = false; + return 0; + } + +-static int drxx_open(struct drxk_state *state) ++static int DRXX_Open(struct drxk_state *state) + { + int status = 0; + u32 jtag = 0; +@@ -785,8 +857,7 @@ static int drxx_open(struct drxk_state *state) + + dprintk(1, "\n"); + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + /* Check device id */ +@@ -805,14 +876,14 @@ static int drxx_open(struct drxk_state *state) + status = write16(state, SIO_TOP_COMM_KEY__A, key); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int get_device_capabilities(struct drxk_state *state) ++static int GetDeviceCapabilities(struct drxk_state *state) + { +- u16 sio_pdr_ohw_cfg = 0; +- u32 sio_top_jtagid_lo = 0; ++ u16 sioPdrOhwCfg = 0; ++ u32 sioTopJtagidLo = 0; + int status; + const char *spin = ""; + +@@ -820,196 +891,197 @@ static int get_device_capabilities(struct drxk_state *state) + + /* driver 0.9.0 */ + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; +- status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); ++ status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA); + if (status < 0) + goto error; +- status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg); ++ status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg); + if (status < 0) + goto error; + status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); + if (status < 0) + goto error; + +- switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { ++ switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { + case 0: + /* ignore (bypass ?) */ + break; + case 1: + /* 27 MHz */ +- state->m_osc_clock_freq = 27000; ++ state->m_oscClockFreq = 27000; + break; + case 2: + /* 20.25 MHz */ +- state->m_osc_clock_freq = 20250; ++ state->m_oscClockFreq = 20250; + break; + case 3: + /* 4 MHz */ +- state->m_osc_clock_freq = 20250; ++ state->m_oscClockFreq = 20250; + break; + default: +- pr_err("Clock Frequency is unknown\n"); ++ printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n"); + return -EINVAL; + } + /* + Determine device capabilities + Based on pinning v14 + */ +- status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo); ++ status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo); + if (status < 0) + goto error; + +- pr_info("status = 0x%08x\n", sio_top_jtagid_lo); ++printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo); + + /* driver 0.9.0 */ +- switch ((sio_top_jtagid_lo >> 29) & 0xF) { ++ switch ((sioTopJtagidLo >> 29) & 0xF) { + case 0: +- state->m_device_spin = DRXK_SPIN_A1; ++ state->m_deviceSpin = DRXK_SPIN_A1; + spin = "A1"; + break; + case 2: +- state->m_device_spin = DRXK_SPIN_A2; ++ state->m_deviceSpin = DRXK_SPIN_A2; + spin = "A2"; + break; + case 3: +- state->m_device_spin = DRXK_SPIN_A3; ++ state->m_deviceSpin = DRXK_SPIN_A3; + spin = "A3"; + break; + default: +- state->m_device_spin = DRXK_SPIN_UNKNOWN; ++ state->m_deviceSpin = DRXK_SPIN_UNKNOWN; + status = -EINVAL; +- pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF); ++ printk(KERN_ERR "drxk: Spin %d unknown\n", ++ (sioTopJtagidLo >> 29) & 0xF); + goto error2; + } +- switch ((sio_top_jtagid_lo >> 12) & 0xFF) { ++ switch ((sioTopJtagidLo >> 12) & 0xFF) { + case 0x13: + /* typeId = DRX3913K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = false; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = false; +- state->m_has_gpio1 = false; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = false; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = false; ++ state->m_hasGPIO1 = false; ++ state->m_hasIRQN = false; + break; + case 0x15: + /* typeId = DRX3915K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = false; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = false; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x16: + /* typeId = DRX3916K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = false; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = false; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x18: + /* typeId = DRX3918K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = false; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = false; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x21: + /* typeId = DRX3921K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x23: + /* typeId = DRX3923K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x25: + /* typeId = DRX3925K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x26: + /* typeId = DRX3926K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + default: +- pr_err("DeviceID 0x%02x not supported\n", +- ((sio_top_jtagid_lo >> 12) & 0xFF)); ++ printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n", ++ ((sioTopJtagidLo >> 12) & 0xFF)); + status = -EINVAL; + goto error2; + } + +- pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", +- ((sio_top_jtagid_lo >> 12) & 0xFF), spin, +- state->m_osc_clock_freq / 1000, +- state->m_osc_clock_freq % 1000); ++ printk(KERN_INFO ++ "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", ++ ((sioTopJtagidLo >> 12) & 0xFF), spin, ++ state->m_oscClockFreq / 1000, ++ state->m_oscClockFreq % 1000); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + error2: + return status; + } + +-static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) ++static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult) + { + int status; + bool powerdown_cmd; +@@ -1021,37 +1093,37 @@ static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) + if (status < 0) + goto error; + if (cmd == SIO_HI_RA_RAM_CMD_RESET) +- usleep_range(1000, 2000); ++ msleep(1); + + powerdown_cmd = + (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) && +- ((state->m_hi_cfg_ctrl) & ++ ((state->m_HICfgCtrl) & + SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) == + SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ); +- if (!powerdown_cmd) { ++ if (powerdown_cmd == false) { + /* Wait until command rdy */ +- u32 retry_count = 0; +- u16 wait_cmd; ++ u32 retryCount = 0; ++ u16 waitCmd; + + do { +- usleep_range(1000, 2000); +- retry_count += 1; ++ msleep(1); ++ retryCount += 1; + status = read16(state, SIO_HI_RA_RAM_CMD__A, +- &wait_cmd); +- } while ((status < 0) && (retry_count < DRXK_MAX_RETRIES) +- && (wait_cmd != 0)); ++ &waitCmd); ++ } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES) ++ && (waitCmd != 0)); + if (status < 0) + goto error; +- status = read16(state, SIO_HI_RA_RAM_RES__A, p_result); ++ status = read16(state, SIO_HI_RA_RAM_RES__A, pResult); + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int hi_cfg_command(struct drxk_state *state) ++static int HI_CfgCommand(struct drxk_state *state) + { + int status; + +@@ -1059,77 +1131,70 @@ static int hi_cfg_command(struct drxk_state *state) + + mutex_lock(&state->mutex); + +- status = write16(state, SIO_HI_RA_RAM_PAR_6__A, +- state->m_hi_cfg_timeout); ++ status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_5__A, +- state->m_hi_cfg_ctrl); ++ status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_4__A, +- state->m_hi_cfg_wake_up_key); ++ status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_3__A, +- state->m_hi_cfg_bridge_delay); ++ status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, +- state->m_hi_cfg_timing_div); ++ status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_1__A, +- SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); ++ status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); + if (status < 0) + goto error; +- status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL); ++ status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0); + if (status < 0) + goto error; + +- state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; ++ state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; + error: + mutex_unlock(&state->mutex); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int init_hi(struct drxk_state *state) ++static int InitHI(struct drxk_state *state) + { + dprintk(1, "\n"); + +- state->m_hi_cfg_wake_up_key = (state->demod_address << 1); +- state->m_hi_cfg_timeout = 0x96FF; ++ state->m_HICfgWakeUpKey = (state->demod_address << 1); ++ state->m_HICfgTimeout = 0x96FF; + /* port/bridge/power down ctrl */ +- state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; ++ state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; + +- return hi_cfg_command(state); ++ return HI_CfgCommand(state); + } + +-static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) ++static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) + { + int status = -1; +- u16 sio_pdr_mclk_cfg = 0; +- u16 sio_pdr_mdx_cfg = 0; ++ u16 sioPdrMclkCfg = 0; ++ u16 sioPdrMdxCfg = 0; + u16 err_cfg = 0; + + dprintk(1, ": mpeg %s, %s mode\n", +- mpeg_enable ? "enable" : "disable", +- state->m_enable_parallel ? "parallel" : "serial"); ++ mpegEnable ? "enable" : "disable", ++ state->m_enableParallel ? "parallel" : "serial"); + + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + + /* MPEG TS pad configuration */ +- status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); ++ status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA); + if (status < 0) + goto error; + +- if (!mpeg_enable) { ++ if (mpegEnable == false) { + /* Set MPEG TS pads to inputmode */ + status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000); + if (status < 0) +@@ -1169,19 +1234,19 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + goto error; + } else { + /* Enable MPEG output */ +- sio_pdr_mdx_cfg = +- ((state->m_ts_data_strength << ++ sioPdrMdxCfg = ++ ((state->m_TSDataStrength << + SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003); +- sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength << ++ sioPdrMclkCfg = ((state->m_TSClockkStrength << + SIO_PDR_MCLK_CFG_DRIVE__B) | + 0x0003); + +- status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; + + if (state->enable_merr_cfg) +- err_cfg = sio_pdr_mdx_cfg; ++ err_cfg = sioPdrMdxCfg; + + status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); + if (status < 0) +@@ -1190,38 +1255,31 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + if (status < 0) + goto error; + +- if (state->m_enable_parallel) { +- /* parallel -> enable MD1 to MD7 */ +- status = write16(state, SIO_PDR_MD1_CFG__A, +- sio_pdr_mdx_cfg); ++ if (state->m_enableParallel == true) { ++ /* paralel -> enable MD1 to MD7 */ ++ status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD2_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD3_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD4_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD5_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD6_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD7_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; + } else { +- sio_pdr_mdx_cfg = ((state->m_ts_data_strength << ++ sioPdrMdxCfg = ((state->m_TSDataStrength << + SIO_PDR_MD0_CFG_DRIVE__B) + | 0x0003); + /* serial -> disable MD1 to MD7 */ +@@ -1247,10 +1305,10 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + if (status < 0) + goto error; + } +- status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg); ++ status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; + } +@@ -1262,21 +1320,21 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_disable(struct drxk_state *state) ++static int MPEGTSDisable(struct drxk_state *state) + { + dprintk(1, "\n"); + +- return mpegts_configure_pins(state, false); ++ return MPEGTSConfigurePins(state, false); + } + +-static int bl_chain_cmd(struct drxk_state *state, +- u16 rom_offset, u16 nr_of_elements, u32 time_out) ++static int BLChainCmd(struct drxk_state *state, ++ u16 romOffset, u16 nrOfElements, u32 timeOut) + { +- u16 bl_status = 0; ++ u16 blStatus = 0; + int status; + unsigned long end; + +@@ -1285,46 +1343,46 @@ static int bl_chain_cmd(struct drxk_state *state, + status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset); ++ status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements); ++ status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements); + if (status < 0) + goto error; + status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); + if (status < 0) + goto error; + +- end = jiffies + msecs_to_jiffies(time_out); ++ end = jiffies + msecs_to_jiffies(timeOut); + do { +- usleep_range(1000, 2000); +- status = read16(state, SIO_BL_STATUS__A, &bl_status); ++ msleep(1); ++ status = read16(state, SIO_BL_STATUS__A, &blStatus); + if (status < 0) + goto error; +- } while ((bl_status == 0x1) && ++ } while ((blStatus == 0x1) && + ((time_is_after_jiffies(end)))); + +- if (bl_status == 0x1) { +- pr_err("SIO not ready\n"); ++ if (blStatus == 0x1) { ++ printk(KERN_ERR "drxk: SIO not ready\n"); + status = -EINVAL; + goto error2; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + error2: + mutex_unlock(&state->mutex); + return status; + } + + +-static int download_microcode(struct drxk_state *state, +- const u8 p_mc_image[], u32 length) ++static int DownloadMicrocode(struct drxk_state *state, ++ const u8 pMCImage[], u32 Length) + { +- const u8 *p_src = p_mc_image; +- u32 address; +- u16 n_blocks; +- u16 block_size; ++ const u8 *pSrc = pMCImage; ++ u32 Address; ++ u16 nBlocks; ++ u16 BlockSize; + u32 offset = 0; + u32 i; + int status = 0; +@@ -1334,131 +1392,130 @@ static int download_microcode(struct drxk_state *state, + /* down the drain (we don't care about MAGIC_WORD) */ + #if 0 + /* For future reference */ +- drain = (p_src[0] << 8) | p_src[1]; ++ Drain = (pSrc[0] << 8) | pSrc[1]; + #endif +- p_src += sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); +- n_blocks = (p_src[0] << 8) | p_src[1]; +- p_src += sizeof(u16); ++ nBlocks = (pSrc[0] << 8) | pSrc[1]; ++ pSrc += sizeof(u16); + offset += sizeof(u16); + +- for (i = 0; i < n_blocks; i += 1) { +- address = (p_src[0] << 24) | (p_src[1] << 16) | +- (p_src[2] << 8) | p_src[3]; +- p_src += sizeof(u32); ++ for (i = 0; i < nBlocks; i += 1) { ++ Address = (pSrc[0] << 24) | (pSrc[1] << 16) | ++ (pSrc[2] << 8) | pSrc[3]; ++ pSrc += sizeof(u32); + offset += sizeof(u32); + +- block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16); +- p_src += sizeof(u16); ++ BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); + + #if 0 + /* For future reference */ +- flags = (p_src[0] << 8) | p_src[1]; ++ Flags = (pSrc[0] << 8) | pSrc[1]; + #endif +- p_src += sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); + + #if 0 + /* For future reference */ +- block_crc = (p_src[0] << 8) | p_src[1]; ++ BlockCRC = (pSrc[0] << 8) | pSrc[1]; + #endif +- p_src += sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); + +- if (offset + block_size > length) { +- pr_err("Firmware is corrupted.\n"); ++ if (offset + BlockSize > Length) { ++ printk(KERN_ERR "drxk: Firmware is corrupted.\n"); + return -EINVAL; + } + +- status = write_block(state, address, block_size, p_src); ++ status = write_block(state, Address, BlockSize, pSrc); + if (status < 0) { +- pr_err("Error %d while loading firmware\n", status); ++ printk(KERN_ERR "drxk: Error %d while loading firmware\n", status); + break; + } +- p_src += block_size; +- offset += block_size; ++ pSrc += BlockSize; ++ offset += BlockSize; + } + return status; + } + +-static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable) ++static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable) + { + int status; + u16 data = 0; +- u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; +- u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; ++ u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; ++ u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; + unsigned long end; + + dprintk(1, "\n"); + +- if (!enable) { +- desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; +- desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; ++ if (enable == false) { ++ desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; ++ desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; + } + + status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); +- if (status >= 0 && data == desired_status) { ++ if (status >= 0 && data == desiredStatus) { + /* tokenring already has correct status */ + return status; + } + /* Disable/enable dvbt tokenring bridge */ +- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl); ++ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl); + + end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT); + do { + status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); +- if ((status >= 0 && data == desired_status) +- || time_is_after_jiffies(end)) ++ if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end)) + break; +- usleep_range(1000, 2000); ++ msleep(1); + } while (1); +- if (data != desired_status) { +- pr_err("SIO not ready\n"); ++ if (data != desiredStatus) { ++ printk(KERN_ERR "drxk: SIO not ready\n"); + return -EINVAL; + } + return status; + } + +-static int mpegts_stop(struct drxk_state *state) ++static int MPEGTSStop(struct drxk_state *state) + { + int status = 0; +- u16 fec_oc_snc_mode = 0; +- u16 fec_oc_ipr_mode = 0; ++ u16 fecOcSncMode = 0; ++ u16 fecOcIprMode = 0; + + dprintk(1, "\n"); + +- /* Graceful shutdown (byte boundaries) */ +- status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); ++ /* Gracefull shutdown (byte boundaries) */ ++ status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode); + if (status < 0) + goto error; +- fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M; +- status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); ++ fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M; ++ status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode); + if (status < 0) + goto error; + + /* Suppress MCLK during absence of data */ +- status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode); ++ status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode); + if (status < 0) + goto error; +- fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; +- status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode); ++ fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; ++ status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + + static int scu_command(struct drxk_state *state, +- u16 cmd, u8 parameter_len, +- u16 *parameter, u8 result_len, u16 *result) ++ u16 cmd, u8 parameterLen, ++ u16 *parameter, u8 resultLen, u16 *result) + { + #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15 + #error DRXK register mapping no longer compatible with this routine! + #endif +- u16 cur_cmd = 0; ++ u16 curCmd = 0; + int status = -EINVAL; + unsigned long end; + u8 buffer[34]; +@@ -1468,9 +1525,9 @@ static int scu_command(struct drxk_state *state, + + dprintk(1, "\n"); + +- if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) || +- ((result_len > 0) && (result == NULL))) { +- pr_err("Error %d on %s\n", status, __func__); ++ if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || ++ ((resultLen > 0) && (result == NULL))) { ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -1478,7 +1535,7 @@ static int scu_command(struct drxk_state *state, + + /* assume that the command register is ready + since it is checked afterwards */ +- for (ii = parameter_len - 1; ii >= 0; ii -= 1) { ++ for (ii = parameterLen - 1; ii >= 0; ii -= 1) { + buffer[cnt++] = (parameter[ii] & 0xFF); + buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF); + } +@@ -1486,28 +1543,27 @@ static int scu_command(struct drxk_state *state, + buffer[cnt++] = ((cmd >> 8) & 0xFF); + + write_block(state, SCU_RAM_PARAM_0__A - +- (parameter_len - 1), cnt, buffer); ++ (parameterLen - 1), cnt, buffer); + /* Wait until SCU has processed command */ + end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME); + do { +- usleep_range(1000, 2000); +- status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd); ++ msleep(1); ++ status = read16(state, SCU_RAM_COMMAND__A, &curCmd); + if (status < 0) + goto error; +- } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); +- if (cur_cmd != DRX_SCU_READY) { +- pr_err("SCU not ready\n"); ++ } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); ++ if (curCmd != DRX_SCU_READY) { ++ printk(KERN_ERR "drxk: SCU not ready\n"); + status = -EIO; + goto error2; + } + /* read results */ +- if ((result_len > 0) && (result != NULL)) { ++ if ((resultLen > 0) && (result != NULL)) { + s16 err; + int ii; + +- for (ii = result_len - 1; ii >= 0; ii -= 1) { +- status = read16(state, SCU_RAM_PARAM_0__A - ii, +- &result[ii]); ++ for (ii = resultLen - 1; ii >= 0; ii -= 1) { ++ status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]); + if (status < 0) + goto error; + } +@@ -1535,7 +1591,7 @@ static int scu_command(struct drxk_state *state, + sprintf(errname, "ERROR: %d\n", err); + p = errname; + } +- pr_err("%s while sending cmd 0x%04x with params:", p, cmd); ++ printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd); + print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt); + status = -EINVAL; + goto error2; +@@ -1543,13 +1599,13 @@ static int scu_command(struct drxk_state *state, + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + error2: + mutex_unlock(&state->mutex); + return status; + } + +-static int set_iqm_af(struct drxk_state *state, bool active) ++static int SetIqmAf(struct drxk_state *state, bool active) + { + u16 data = 0; + int status; +@@ -1579,14 +1635,14 @@ static int set_iqm_af(struct drxk_state *state, bool active) + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) ++static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode) + { + int status = 0; +- u16 sio_cc_pwd_mode = 0; ++ u16 sioCcPwdMode = 0; + + dprintk(1, "\n"); + +@@ -1596,19 +1652,19 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + + switch (*mode) { + case DRX_POWER_UP: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE; + break; + case DRXK_POWER_DOWN_OFDM: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM; + break; + case DRXK_POWER_DOWN_CORE: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK; + break; + case DRXK_POWER_DOWN_PLL: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL; + break; + case DRX_POWER_DOWN: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC; + break; + default: + /* Unknow sleep mode */ +@@ -1616,15 +1672,15 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + } + + /* If already in requested power mode, do nothing */ +- if (state->m_current_power_mode == *mode) ++ if (state->m_currentPowerMode == *mode) + return 0; + + /* For next steps make sure to start from DRX_POWER_UP mode */ +- if (state->m_current_power_mode != DRX_POWER_UP) { +- status = power_up_device(state); ++ if (state->m_currentPowerMode != DRX_POWER_UP) { ++ status = PowerUpDevice(state); + if (status < 0) + goto error; +- status = dvbt_enable_ofdm_token_ring(state, true); ++ status = DVBTEnableOFDMTokenRing(state, true); + if (status < 0) + goto error; + } +@@ -1641,31 +1697,31 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + /* Power down device */ + /* stop all comm_exec */ + /* Stop and power down previous standard */ +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_DVBT: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_dvbt(state, false); ++ status = PowerDownDVBT(state, false); + if (status < 0) + goto error; + break; + case OM_QAM_ITU_A: + case OM_QAM_ITU_C: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_qam(state); ++ status = PowerDownQAM(state); + if (status < 0) + goto error; + break; + default: + break; + } +- status = dvbt_enable_ofdm_token_ring(state, false); ++ status = DVBTEnableOFDMTokenRing(state, false); + if (status < 0) + goto error; +- status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode); ++ status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode); + if (status < 0) + goto error; + status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); +@@ -1673,26 +1729,26 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + goto error; + + if (*mode != DRXK_POWER_DOWN_OFDM) { +- state->m_hi_cfg_ctrl |= ++ state->m_HICfgCtrl |= + SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; +- status = hi_cfg_command(state); ++ status = HI_CfgCommand(state); + if (status < 0) + goto error; + } + } +- state->m_current_power_mode = *mode; ++ state->m_currentPowerMode = *mode; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) ++static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode) + { +- enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; +- u16 cmd_result = 0; ++ enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; ++ u16 cmdResult = 0; + u16 data = 0; + int status; + +@@ -1703,17 +1759,11 @@ static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) + goto error; + if (data == SCU_COMM_EXEC_ACTIVE) { + /* Send OFDM stop command */ +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_STOP, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + /* Send OFDM reset command */ +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_RESET, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + } +@@ -1730,24 +1780,24 @@ static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) + goto error; + + /* powerdown AFE */ +- status = set_iqm_af(state, false); ++ status = SetIqmAf(state, false); + if (status < 0) + goto error; + + /* powerdown to OFDM mode */ +- if (set_power_mode) { +- status = ctrl_power_mode(state, &power_mode); ++ if (setPowerMode) { ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) + goto error; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int setoperation_mode(struct drxk_state *state, +- enum operation_mode o_mode) ++static int SetOperationMode(struct drxk_state *state, ++ enum OperationMode oMode) + { + int status = 0; + +@@ -1759,37 +1809,36 @@ static int setoperation_mode(struct drxk_state *state, + */ + + /* disable HW lock indicator */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + + /* Device is already at the required mode */ +- if (state->m_operation_mode == o_mode) ++ if (state->m_OperationMode == oMode) + return 0; + +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + /* OM_NONE was added for start up */ + case OM_NONE: + break; + case OM_DVBT: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_dvbt(state, true); ++ status = PowerDownDVBT(state, true); + if (status < 0) + goto error; +- state->m_operation_mode = OM_NONE; ++ state->m_OperationMode = OM_NONE; + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_qam(state); ++ status = PowerDownQAM(state); + if (status < 0) + goto error; +- state->m_operation_mode = OM_NONE; ++ state->m_OperationMode = OM_NONE; + break; + case OM_QAM_ITU_B: + default: +@@ -1800,20 +1849,20 @@ static int setoperation_mode(struct drxk_state *state, + /* + Power up new standard + */ +- switch (o_mode) { ++ switch (oMode) { + case OM_DVBT: + dprintk(1, ": DVB-T\n"); +- state->m_operation_mode = o_mode; +- status = set_dvbt_standard(state, o_mode); ++ state->m_OperationMode = oMode; ++ status = SetDVBTStandard(state, oMode); + if (status < 0) + goto error; + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: + dprintk(1, ": DVB-C Annex %c\n", +- (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C'); +- state->m_operation_mode = o_mode; +- status = set_qam_standard(state, o_mode); ++ (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C'); ++ state->m_OperationMode = oMode; ++ status = SetQAMStandard(state, oMode); + if (status < 0) + goto error; + break; +@@ -1823,121 +1872,123 @@ static int setoperation_mode(struct drxk_state *state, + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int start(struct drxk_state *state, s32 offset_freq, +- s32 intermediate_frequency) ++static int Start(struct drxk_state *state, s32 offsetFreq, ++ s32 IntermediateFrequency) + { + int status = -EINVAL; + +- u16 i_freqk_hz; +- s32 offsetk_hz = offset_freq / 1000; ++ u16 IFreqkHz; ++ s32 OffsetkHz = offsetFreq / 1000; + + dprintk(1, "\n"); +- if (state->m_drxk_state != DRXK_STOPPED && +- state->m_drxk_state != DRXK_DTV_STARTED) ++ if (state->m_DrxkState != DRXK_STOPPED && ++ state->m_DrxkState != DRXK_DTV_STARTED) + goto error; + +- state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON); ++ state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON); + +- if (intermediate_frequency < 0) { +- state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect; +- intermediate_frequency = -intermediate_frequency; ++ if (IntermediateFrequency < 0) { ++ state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect; ++ IntermediateFrequency = -IntermediateFrequency; + } + +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_QAM_ITU_A: + case OM_QAM_ITU_C: +- i_freqk_hz = (intermediate_frequency / 1000); +- status = set_qam(state, i_freqk_hz, offsetk_hz); ++ IFreqkHz = (IntermediateFrequency / 1000); ++ status = SetQAM(state, IFreqkHz, OffsetkHz); + if (status < 0) + goto error; +- state->m_drxk_state = DRXK_DTV_STARTED; ++ state->m_DrxkState = DRXK_DTV_STARTED; + break; + case OM_DVBT: +- i_freqk_hz = (intermediate_frequency / 1000); +- status = mpegts_stop(state); ++ IFreqkHz = (IntermediateFrequency / 1000); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = set_dvbt(state, i_freqk_hz, offsetk_hz); ++ status = SetDVBT(state, IFreqkHz, OffsetkHz); + if (status < 0) + goto error; +- status = dvbt_start(state); ++ status = DVBTStart(state); + if (status < 0) + goto error; +- state->m_drxk_state = DRXK_DTV_STARTED; ++ state->m_DrxkState = DRXK_DTV_STARTED; + break; + default: + break; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int shut_down(struct drxk_state *state) ++static int ShutDown(struct drxk_state *state) + { + dprintk(1, "\n"); + +- mpegts_stop(state); ++ MPEGTSStop(state); + return 0; + } + +-static int get_lock_status(struct drxk_state *state, u32 *p_lock_status) ++static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus, ++ u32 Time) + { + int status = -EINVAL; + + dprintk(1, "\n"); + +- if (p_lock_status == NULL) ++ if (pLockStatus == NULL) + goto error; + +- *p_lock_status = NOT_LOCKED; ++ *pLockStatus = NOT_LOCKED; + + /* define the SCU command code */ +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_QAM_ITU_A: + case OM_QAM_ITU_B: + case OM_QAM_ITU_C: +- status = get_qam_lock_status(state, p_lock_status); ++ status = GetQAMLockStatus(state, pLockStatus); + break; + case OM_DVBT: +- status = get_dvbt_lock_status(state, p_lock_status); ++ status = GetDVBTLockStatus(state, pLockStatus); + break; + default: ++ status = 0; + break; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_start(struct drxk_state *state) ++static int MPEGTSStart(struct drxk_state *state) + { + int status; + +- u16 fec_oc_snc_mode = 0; ++ u16 fecOcSncMode = 0; + + /* Allow OC to sync again */ +- status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); ++ status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode); + if (status < 0) + goto error; +- fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; +- status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); ++ fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; ++ status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode); + if (status < 0) + goto error; + status = write16(state, FEC_OC_SNC_UNLOCK__A, 1); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_dto_init(struct drxk_state *state) ++static int MPEGTSDtoInit(struct drxk_state *state) + { + int status; + +@@ -1979,68 +2030,68 @@ static int mpegts_dto_init(struct drxk_state *state) + status = write16(state, FEC_OC_SNC_HWM__A, 12); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int mpegts_dto_setup(struct drxk_state *state, +- enum operation_mode o_mode) ++static int MPEGTSDtoSetup(struct drxk_state *state, ++ enum OperationMode oMode) + { + int status; + +- u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */ +- u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */ +- u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */ +- u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_tmd_mode = 0; +- u16 fec_oc_tmd_int_upd_rate = 0; +- u32 max_bit_rate = 0; +- bool static_clk = false; ++ u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */ ++ u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */ ++ u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */ ++ u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcTmdMode = 0; ++ u16 fecOcTmdIntUpdRate = 0; ++ u32 maxBitRate = 0; ++ bool staticCLK = false; + + dprintk(1, "\n"); + + /* Check insertion of the Reed-Solomon parity bytes */ +- status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode); ++ status = read16(state, FEC_OC_MODE__A, &fecOcRegMode); + if (status < 0) + goto error; +- status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode); ++ status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode); + if (status < 0) + goto error; +- fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M); +- fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); +- if (state->m_insert_rs_byte) { ++ fecOcRegMode &= (~FEC_OC_MODE_PARITY__M); ++ fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); ++ if (state->m_insertRSByte == true) { + /* enable parity symbol forward */ +- fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M; ++ fecOcRegMode |= FEC_OC_MODE_PARITY__M; + /* MVAL disable during parity bytes */ +- fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; ++ fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; + /* TS burst length to 204 */ +- fec_oc_dto_burst_len = 204; ++ fecOcDtoBurstLen = 204; + } + +- /* Check serial or parallel output */ +- fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); +- if (!state->m_enable_parallel) { ++ /* Check serial or parrallel output */ ++ fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); ++ if (state->m_enableParallel == false) { + /* MPEG data output is serial -> set ipr_mode[0] */ +- fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M; ++ fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M; + } + +- switch (o_mode) { ++ switch (oMode) { + case OM_DVBT: +- max_bit_rate = state->m_dvbt_bitrate; +- fec_oc_tmd_mode = 3; +- fec_oc_rcn_ctl_rate = 0xC00000; +- static_clk = state->m_dvbt_static_clk; ++ maxBitRate = state->m_DVBTBitrate; ++ fecOcTmdMode = 3; ++ fecOcRcnCtlRate = 0xC00000; ++ staticCLK = state->m_DVBTStaticCLK; + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: +- fec_oc_tmd_mode = 0x0004; +- fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */ +- max_bit_rate = state->m_dvbc_bitrate; +- static_clk = state->m_dvbc_static_clk; ++ fecOcTmdMode = 0x0004; ++ fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */ ++ maxBitRate = state->m_DVBCBitrate; ++ staticCLK = state->m_DVBCStaticCLK; + break; + default: + status = -EINVAL; +@@ -2049,84 +2100,83 @@ static int mpegts_dto_setup(struct drxk_state *state, + goto error; + + /* Configure DTO's */ +- if (static_clk) { +- u32 bit_rate = 0; ++ if (staticCLK) { ++ u32 bitRate = 0; + + /* Rational DTO for MCLK source (static MCLK rate), + Dynamic DTO for optimal grouping + (avoid intra-packet gaps), + DTO offset enable to sync TS burst with MSTRT */ +- fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M | ++ fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M | + FEC_OC_DTO_MODE_OFFSET_ENABLE__M); +- fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M | ++ fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M | + FEC_OC_FCT_MODE_VIRT_ENA__M); + + /* Check user defined bitrate */ +- bit_rate = max_bit_rate; +- if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */ +- bit_rate = 75900000UL; ++ bitRate = maxBitRate; ++ if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */ ++ bitRate = 75900000UL; + } + /* Rational DTO period: + dto_period = (Fsys / bitrate) - 2 + +- result should be floored, ++ Result should be floored, + to make sure >= requested bitrate + */ +- fec_oc_dto_period = (u16) (((state->m_sys_clock_freq) +- * 1000) / bit_rate); +- if (fec_oc_dto_period <= 2) +- fec_oc_dto_period = 0; ++ fecOcDtoPeriod = (u16) (((state->m_sysClockFreq) ++ * 1000) / bitRate); ++ if (fecOcDtoPeriod <= 2) ++ fecOcDtoPeriod = 0; + else +- fec_oc_dto_period -= 2; +- fec_oc_tmd_int_upd_rate = 8; ++ fecOcDtoPeriod -= 2; ++ fecOcTmdIntUpdRate = 8; + } else { +- /* (commonAttr->static_clk == false) => dynamic mode */ +- fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M; +- fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE; +- fec_oc_tmd_int_upd_rate = 5; ++ /* (commonAttr->staticCLK == false) => dynamic mode */ ++ fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M; ++ fecOcFctMode = FEC_OC_FCT_MODE__PRE; ++ fecOcTmdIntUpdRate = 5; + } + + /* Write appropriate registers with requested configuration */ +- status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len); ++ status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period); ++ status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode); ++ status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode); ++ status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode); ++ status = write16(state, FEC_OC_MODE__A, fecOcRegMode); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode); ++ status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode); + if (status < 0) + goto error; + + /* Rate integration settings */ +- status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate); ++ status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, +- fec_oc_tmd_int_upd_rate); ++ status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode); ++ status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_configure_polarity(struct drxk_state *state) ++static int MPEGTSConfigurePolarity(struct drxk_state *state) + { +- u16 fec_oc_reg_ipr_invert = 0; ++ u16 fecOcRegIprInvert = 0; + + /* Data mask for the output data byte */ +- u16 invert_data_mask = ++ u16 InvertDataMask = + FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M | + FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M | + FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M | +@@ -2135,40 +2185,40 @@ static int mpegts_configure_polarity(struct drxk_state *state) + dprintk(1, "\n"); + + /* Control selective inversion of output bits */ +- fec_oc_reg_ipr_invert &= (~(invert_data_mask)); +- if (state->m_invert_data) +- fec_oc_reg_ipr_invert |= invert_data_mask; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M)); +- if (state->m_invert_err) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); +- if (state->m_invert_str) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); +- if (state->m_invert_val) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); +- if (state->m_invert_clk) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M; +- +- return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert); ++ fecOcRegIprInvert &= (~(InvertDataMask)); ++ if (state->m_invertDATA == true) ++ fecOcRegIprInvert |= InvertDataMask; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M)); ++ if (state->m_invertERR == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); ++ if (state->m_invertSTR == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); ++ if (state->m_invertVAL == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); ++ if (state->m_invertCLK == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M; ++ ++ return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert); + } + + #define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000 + +-static int set_agc_rf(struct drxk_state *state, +- struct s_cfg_agc *p_agc_cfg, bool is_dtv) ++static int SetAgcRf(struct drxk_state *state, ++ struct SCfgAgc *pAgcCfg, bool isDTV) + { + int status = -EINVAL; + u16 data = 0; +- struct s_cfg_agc *p_if_agc_settings; ++ struct SCfgAgc *pIfAgcSettings; + + dprintk(1, "\n"); + +- if (p_agc_cfg == NULL) ++ if (pAgcCfg == NULL) + goto error; + +- switch (p_agc_cfg->ctrl_mode) { ++ switch (pAgcCfg->ctrlMode) { + case DRXK_AGC_CTRL_AUTO: + /* Enable RF AGC DAC */ + status = read16(state, IQM_AF_STDBY__A, &data); +@@ -2186,7 +2236,7 @@ static int set_agc_rf(struct drxk_state *state, + data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; + + /* Polarity */ +- if (state->m_rf_agc_pol) ++ if (state->m_RfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; +@@ -2200,7 +2250,7 @@ static int set_agc_rf(struct drxk_state *state, + goto error; + + data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M; +- data |= (~(p_agc_cfg->speed << ++ data |= (~(pAgcCfg->speed << + SCU_RAM_AGC_KI_RED_RAGC_RED__B) + & SCU_RAM_AGC_KI_RED_RAGC_RED__M); + +@@ -2208,35 +2258,30 @@ static int set_agc_rf(struct drxk_state *state, + if (status < 0) + goto error; + +- if (is_dvbt(state)) +- p_if_agc_settings = &state->m_dvbt_if_agc_cfg; +- else if (is_qam(state)) +- p_if_agc_settings = &state->m_qam_if_agc_cfg; ++ if (IsDVBT(state)) ++ pIfAgcSettings = &state->m_dvbtIfAgcCfg; ++ else if (IsQAM(state)) ++ pIfAgcSettings = &state->m_qamIfAgcCfg; + else +- p_if_agc_settings = &state->m_atv_if_agc_cfg; +- if (p_if_agc_settings == NULL) { ++ pIfAgcSettings = &state->m_atvIfAgcCfg; ++ if (pIfAgcSettings == NULL) { + status = -EINVAL; + goto error; + } + + /* Set TOP, only if IF-AGC is in AUTO mode */ +- if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) { +- status = write16(state, +- SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- p_agc_cfg->top); ++ if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO) ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top); + if (status < 0) + goto error; +- } + + /* Cut-Off current */ +- status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, +- p_agc_cfg->cut_off_current); ++ status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent); + if (status < 0) + goto error; + + /* Max. output level */ +- status = write16(state, SCU_RAM_AGC_RF_MAX__A, +- p_agc_cfg->max_output_level); ++ status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel); + if (status < 0) + goto error; + +@@ -2257,7 +2302,7 @@ static int set_agc_rf(struct drxk_state *state, + if (status < 0) + goto error; + data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; +- if (state->m_rf_agc_pol) ++ if (state->m_RfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; +@@ -2271,8 +2316,7 @@ static int set_agc_rf(struct drxk_state *state, + goto error; + + /* Write value to output pin */ +- status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, +- p_agc_cfg->output_level); ++ status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel); + if (status < 0) + goto error; + break; +@@ -2303,22 +2347,22 @@ static int set_agc_rf(struct drxk_state *state, + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000 + +-static int set_agc_if(struct drxk_state *state, +- struct s_cfg_agc *p_agc_cfg, bool is_dtv) ++static int SetAgcIf(struct drxk_state *state, ++ struct SCfgAgc *pAgcCfg, bool isDTV) + { + u16 data = 0; + int status = 0; +- struct s_cfg_agc *p_rf_agc_settings; ++ struct SCfgAgc *pRfAgcSettings; + + dprintk(1, "\n"); + +- switch (p_agc_cfg->ctrl_mode) { ++ switch (pAgcCfg->ctrlMode) { + case DRXK_AGC_CTRL_AUTO: + + /* Enable IF AGC DAC */ +@@ -2338,7 +2382,7 @@ static int set_agc_if(struct drxk_state *state, + data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; + + /* Polarity */ +- if (state->m_if_agc_pol) ++ if (state->m_IfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; +@@ -2351,7 +2395,7 @@ static int set_agc_if(struct drxk_state *state, + if (status < 0) + goto error; + data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M; +- data |= (~(p_agc_cfg->speed << ++ data |= (~(pAgcCfg->speed << + SCU_RAM_AGC_KI_RED_IAGC_RED__B) + & SCU_RAM_AGC_KI_RED_IAGC_RED__M); + +@@ -2359,15 +2403,14 @@ static int set_agc_if(struct drxk_state *state, + if (status < 0) + goto error; + +- if (is_qam(state)) +- p_rf_agc_settings = &state->m_qam_rf_agc_cfg; ++ if (IsQAM(state)) ++ pRfAgcSettings = &state->m_qamRfAgcCfg; + else +- p_rf_agc_settings = &state->m_atv_rf_agc_cfg; +- if (p_rf_agc_settings == NULL) ++ pRfAgcSettings = &state->m_atvRfAgcCfg; ++ if (pRfAgcSettings == NULL) + return -1; + /* Restore TOP */ +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- p_rf_agc_settings->top); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top); + if (status < 0) + goto error; + break; +@@ -2391,7 +2434,7 @@ static int set_agc_if(struct drxk_state *state, + data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; + + /* Polarity */ +- if (state->m_if_agc_pol) ++ if (state->m_IfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; +@@ -2400,8 +2443,7 @@ static int set_agc_if(struct drxk_state *state, + goto error; + + /* Write value to output pin */ +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- p_agc_cfg->output_level); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel); + if (status < 0) + goto error; + break; +@@ -2426,181 +2468,207 @@ static int set_agc_if(struct drxk_state *state, + if (status < 0) + goto error; + break; +- } /* switch (agcSettingsIf->ctrl_mode) */ ++ } /* switch (agcSettingsIf->ctrlMode) */ + + /* always set the top to support + configurations without if-loop */ +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int get_qam_signal_to_noise(struct drxk_state *state, +- s32 *p_signal_to_noise) ++static int ReadIFAgc(struct drxk_state *state, u32 *pValue) ++{ ++ u16 agcDacLvl; ++ int status; ++ u16 Level = 0; ++ ++ dprintk(1, "\n"); ++ ++ status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl); ++ if (status < 0) { ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); ++ return status; ++ } ++ ++ *pValue = 0; ++ ++ if (agcDacLvl > DRXK_AGC_DAC_OFFSET) ++ Level = agcDacLvl - DRXK_AGC_DAC_OFFSET; ++ if (Level < 14000) ++ *pValue = (14000 - Level) / 4; ++ else ++ *pValue = 0; ++ ++ return status; ++} ++ ++static int GetQAMSignalToNoise(struct drxk_state *state, ++ s32 *pSignalToNoise) + { + int status = 0; +- u16 qam_sl_err_power = 0; /* accum. error between ++ u16 qamSlErrPower = 0; /* accum. error between + raw and sliced symbols */ +- u32 qam_sl_sig_power = 0; /* used for MER, depends of ++ u32 qamSlSigPower = 0; /* used for MER, depends of + QAM modulation */ +- u32 qam_sl_mer = 0; /* QAM MER */ ++ u32 qamSlMer = 0; /* QAM MER */ + + dprintk(1, "\n"); + + /* MER calculation */ + + /* get the register value needed for MER */ +- status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power); ++ status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower); + if (status < 0) { +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return -EINVAL; + } + + switch (state->props.modulation) { + case QAM_16: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; + break; + case QAM_32: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; + break; + case QAM_64: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; + break; + case QAM_128: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; + break; + default: + case QAM_256: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; + break; + } + +- if (qam_sl_err_power > 0) { +- qam_sl_mer = log10times100(qam_sl_sig_power) - +- log10times100((u32) qam_sl_err_power); ++ if (qamSlErrPower > 0) { ++ qamSlMer = Log10Times100(qamSlSigPower) - ++ Log10Times100((u32) qamSlErrPower); + } +- *p_signal_to_noise = qam_sl_mer; ++ *pSignalToNoise = qamSlMer; + + return status; + } + +-static int get_dvbt_signal_to_noise(struct drxk_state *state, +- s32 *p_signal_to_noise) ++static int GetDVBTSignalToNoise(struct drxk_state *state, ++ s32 *pSignalToNoise) + { + int status; +- u16 reg_data = 0; +- u32 eq_reg_td_sqr_err_i = 0; +- u32 eq_reg_td_sqr_err_q = 0; +- u16 eq_reg_td_sqr_err_exp = 0; +- u16 eq_reg_td_tps_pwr_ofs = 0; +- u16 eq_reg_td_req_smb_cnt = 0; +- u32 tps_cnt = 0; +- u32 sqr_err_iq = 0; ++ u16 regData = 0; ++ u32 EqRegTdSqrErrI = 0; ++ u32 EqRegTdSqrErrQ = 0; ++ u16 EqRegTdSqrErrExp = 0; ++ u16 EqRegTdTpsPwrOfs = 0; ++ u16 EqRegTdReqSmbCnt = 0; ++ u32 tpsCnt = 0; ++ u32 SqrErrIQ = 0; + u32 a = 0; + u32 b = 0; + u32 c = 0; +- u32 i_mer = 0; +- u16 transmission_params = 0; ++ u32 iMER = 0; ++ u16 transmissionParams = 0; + + dprintk(1, "\n"); + +- status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, +- &eq_reg_td_tps_pwr_ofs); ++ status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs); + if (status < 0) + goto error; +- status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, +- &eq_reg_td_req_smb_cnt); ++ status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt); + if (status < 0) + goto error; +- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, +- &eq_reg_td_sqr_err_exp); ++ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp); + if (status < 0) + goto error; +- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, +- ®_data); ++ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, ®Data); + if (status < 0) + goto error; + /* Extend SQR_ERR_I operational range */ +- eq_reg_td_sqr_err_i = (u32) reg_data; +- if ((eq_reg_td_sqr_err_exp > 11) && +- (eq_reg_td_sqr_err_i < 0x00000FFFUL)) { +- eq_reg_td_sqr_err_i += 0x00010000UL; ++ EqRegTdSqrErrI = (u32) regData; ++ if ((EqRegTdSqrErrExp > 11) && ++ (EqRegTdSqrErrI < 0x00000FFFUL)) { ++ EqRegTdSqrErrI += 0x00010000UL; + } +- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data); ++ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®Data); + if (status < 0) + goto error; + /* Extend SQR_ERR_Q operational range */ +- eq_reg_td_sqr_err_q = (u32) reg_data; +- if ((eq_reg_td_sqr_err_exp > 11) && +- (eq_reg_td_sqr_err_q < 0x00000FFFUL)) +- eq_reg_td_sqr_err_q += 0x00010000UL; ++ EqRegTdSqrErrQ = (u32) regData; ++ if ((EqRegTdSqrErrExp > 11) && ++ (EqRegTdSqrErrQ < 0x00000FFFUL)) ++ EqRegTdSqrErrQ += 0x00010000UL; + +- status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, +- &transmission_params); ++ status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams); + if (status < 0) + goto error; + + /* Check input data for MER */ + + /* MER calculation (in 0.1 dB) without math.h */ +- if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0)) +- i_mer = 0; +- else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) { ++ if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0)) ++ iMER = 0; ++ else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) { + /* No error at all, this must be the HW reset value + * Apparently no first measurement yet + * Set MER to 0.0 */ +- i_mer = 0; ++ iMER = 0; + } else { +- sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) << +- eq_reg_td_sqr_err_exp; +- if ((transmission_params & ++ SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) << ++ EqRegTdSqrErrExp; ++ if ((transmissionParams & + OFDM_SC_RA_RAM_OP_PARAM_MODE__M) + == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K) +- tps_cnt = 17; ++ tpsCnt = 17; + else +- tps_cnt = 68; ++ tpsCnt = 68; + + /* IMER = 100 * log10 (x) +- where x = (eq_reg_td_tps_pwr_ofs^2 * +- eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq ++ where x = (EqRegTdTpsPwrOfs^2 * ++ EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ + + => IMER = a + b -c +- where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2) +- b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt) +- c = 100 * log10 (sqr_err_iq) ++ where a = 100 * log10 (EqRegTdTpsPwrOfs^2) ++ b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt) ++ c = 100 * log10 (SqrErrIQ) + */ + + /* log(x) x = 9bits * 9bits->18 bits */ +- a = log10times100(eq_reg_td_tps_pwr_ofs * +- eq_reg_td_tps_pwr_ofs); ++ a = Log10Times100(EqRegTdTpsPwrOfs * ++ EqRegTdTpsPwrOfs); + /* log(x) x = 16bits * 7bits->23 bits */ +- b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt); ++ b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt); + /* log(x) x = (16bits + 16bits) << 15 ->32 bits */ +- c = log10times100(sqr_err_iq); ++ c = Log10Times100(SqrErrIQ); + +- i_mer = a + b - c; ++ iMER = a + b; ++ /* No negative MER, clip to zero */ ++ if (iMER > c) ++ iMER -= c; ++ else ++ iMER = 0; + } +- *p_signal_to_noise = i_mer; ++ *pSignalToNoise = iMER; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) ++static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise) + { + dprintk(1, "\n"); + +- *p_signal_to_noise = 0; +- switch (state->m_operation_mode) { ++ *pSignalToNoise = 0; ++ switch (state->m_OperationMode) { + case OM_DVBT: +- return get_dvbt_signal_to_noise(state, p_signal_to_noise); ++ return GetDVBTSignalToNoise(state, pSignalToNoise); + case OM_QAM_ITU_A: + case OM_QAM_ITU_C: +- return get_qam_signal_to_noise(state, p_signal_to_noise); ++ return GetQAMSignalToNoise(state, pSignalToNoise); + default: + break; + } +@@ -2608,7 +2676,7 @@ static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) + } + + #if 0 +-static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) ++static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality) + { + /* SNR Values for quasi errorfree reception rom Nordig 2.2 */ + int status = 0; +@@ -2633,104 +2701,102 @@ static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) + 225, /* 64-QAM 7/8 */ + }; + +- *p_quality = 0; ++ *pQuality = 0; + + do { +- s32 signal_to_noise = 0; +- u16 constellation = 0; +- u16 code_rate = 0; +- u32 signal_to_noise_rel; +- u32 ber_quality; ++ s32 SignalToNoise = 0; ++ u16 Constellation = 0; ++ u16 CodeRate = 0; ++ u32 SignalToNoiseRel; ++ u32 BERQuality; + +- status = get_dvbt_signal_to_noise(state, &signal_to_noise); ++ status = GetDVBTSignalToNoise(state, &SignalToNoise); + if (status < 0) + break; +- status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, +- &constellation); ++ status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation); + if (status < 0) + break; +- constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; ++ Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; + +- status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, +- &code_rate); ++ status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate); + if (status < 0) + break; +- code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; ++ CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; + +- if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || +- code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) ++ if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || ++ CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) + break; +- signal_to_noise_rel = signal_to_noise - +- QE_SN[constellation * 5 + code_rate]; +- ber_quality = 100; +- +- if (signal_to_noise_rel < -70) +- *p_quality = 0; +- else if (signal_to_noise_rel < 30) +- *p_quality = ((signal_to_noise_rel + 70) * +- ber_quality) / 100; ++ SignalToNoiseRel = SignalToNoise - ++ QE_SN[Constellation * 5 + CodeRate]; ++ BERQuality = 100; ++ ++ if (SignalToNoiseRel < -70) ++ *pQuality = 0; ++ else if (SignalToNoiseRel < 30) ++ *pQuality = ((SignalToNoiseRel + 70) * ++ BERQuality) / 100; + else +- *p_quality = ber_quality; ++ *pQuality = BERQuality; + } while (0); + return 0; + }; + +-static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality) ++static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality) + { + int status = 0; +- *p_quality = 0; ++ *pQuality = 0; + + dprintk(1, "\n"); + + do { +- u32 signal_to_noise = 0; +- u32 ber_quality = 100; +- u32 signal_to_noise_rel = 0; ++ u32 SignalToNoise = 0; ++ u32 BERQuality = 100; ++ u32 SignalToNoiseRel = 0; + +- status = get_qam_signal_to_noise(state, &signal_to_noise); ++ status = GetQAMSignalToNoise(state, &SignalToNoise); + if (status < 0) + break; + + switch (state->props.modulation) { + case QAM_16: +- signal_to_noise_rel = signal_to_noise - 200; ++ SignalToNoiseRel = SignalToNoise - 200; + break; + case QAM_32: +- signal_to_noise_rel = signal_to_noise - 230; ++ SignalToNoiseRel = SignalToNoise - 230; + break; /* Not in NorDig */ + case QAM_64: +- signal_to_noise_rel = signal_to_noise - 260; ++ SignalToNoiseRel = SignalToNoise - 260; + break; + case QAM_128: +- signal_to_noise_rel = signal_to_noise - 290; ++ SignalToNoiseRel = SignalToNoise - 290; + break; + default: + case QAM_256: +- signal_to_noise_rel = signal_to_noise - 320; ++ SignalToNoiseRel = SignalToNoise - 320; + break; + } + +- if (signal_to_noise_rel < -70) +- *p_quality = 0; +- else if (signal_to_noise_rel < 30) +- *p_quality = ((signal_to_noise_rel + 70) * +- ber_quality) / 100; ++ if (SignalToNoiseRel < -70) ++ *pQuality = 0; ++ else if (SignalToNoiseRel < 30) ++ *pQuality = ((SignalToNoiseRel + 70) * ++ BERQuality) / 100; + else +- *p_quality = ber_quality; ++ *pQuality = BERQuality; + } while (0); + + return status; + } + +-static int get_quality(struct drxk_state *state, s32 *p_quality) ++static int GetQuality(struct drxk_state *state, s32 *pQuality) + { + dprintk(1, "\n"); + +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_DVBT: +- return get_dvbt_quality(state, p_quality); ++ return GetDVBTQuality(state, pQuality); + case OM_QAM_ITU_A: +- return get_dvbc_quality(state, p_quality); ++ return GetDVBCQuality(state, pQuality); + default: + break; + } +@@ -2752,68 +2818,65 @@ static int get_quality(struct drxk_state *state, s32 *p_quality) + #define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F) + #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF) + +-static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge) ++static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge) + { + int status = -EINVAL; + + dprintk(1, "\n"); + +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return 0; +- if (state->m_drxk_state == DRXK_POWERED_DOWN) ++ if (state->m_DrxkState == DRXK_UNINITIALIZED) ++ goto error; ++ if (state->m_DrxkState == DRXK_POWERED_DOWN) + goto error; + + if (state->no_i2c_bridge) + return 0; + +- status = write16(state, SIO_HI_RA_RAM_PAR_1__A, +- SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); ++ status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); + if (status < 0) + goto error; +- if (b_enable_bridge) { +- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, +- SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); ++ if (bEnableBridge) { ++ status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); + if (status < 0) + goto error; + } else { +- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, +- SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); ++ status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); + if (status < 0) + goto error; + } + +- status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL); ++ status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_pre_saw(struct drxk_state *state, +- struct s_cfg_pre_saw *p_pre_saw_cfg) ++static int SetPreSaw(struct drxk_state *state, ++ struct SCfgPreSaw *pPreSawCfg) + { + int status = -EINVAL; + + dprintk(1, "\n"); + +- if ((p_pre_saw_cfg == NULL) +- || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M)) ++ if ((pPreSawCfg == NULL) ++ || (pPreSawCfg->reference > IQM_AF_PDREF__M)) + goto error; + +- status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference); ++ status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int bl_direct_cmd(struct drxk_state *state, u32 target_addr, +- u16 rom_offset, u16 nr_of_elements, u32 time_out) ++static int BLDirectCmd(struct drxk_state *state, u32 targetAddr, ++ u16 romOffset, u16 nrOfElements, u32 timeOut) + { +- u16 bl_status = 0; +- u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF); +- u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF); ++ u16 blStatus = 0; ++ u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF); ++ u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF); + int status; + unsigned long end; + +@@ -2829,44 +2892,44 @@ static int bl_direct_cmd(struct drxk_state *state, u32 target_addr, + status = write16(state, SIO_BL_TGT_ADDR__A, offset); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset); ++ status = write16(state, SIO_BL_SRC_ADDR__A, romOffset); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements); ++ status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements); + if (status < 0) + goto error; + status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); + if (status < 0) + goto error; + +- end = jiffies + msecs_to_jiffies(time_out); ++ end = jiffies + msecs_to_jiffies(timeOut); + do { +- status = read16(state, SIO_BL_STATUS__A, &bl_status); ++ status = read16(state, SIO_BL_STATUS__A, &blStatus); + if (status < 0) + goto error; +- } while ((bl_status == 0x1) && time_is_after_jiffies(end)); +- if (bl_status == 0x1) { +- pr_err("SIO not ready\n"); ++ } while ((blStatus == 0x1) && time_is_after_jiffies(end)); ++ if (blStatus == 0x1) { ++ printk(KERN_ERR "drxk: SIO not ready\n"); + status = -EINVAL; + goto error2; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + error2: + mutex_unlock(&state->mutex); + return status; + + } + +-static int adc_sync_measurement(struct drxk_state *state, u16 *count) ++static int ADCSyncMeasurement(struct drxk_state *state, u16 *count) + { + u16 data = 0; + int status; + + dprintk(1, "\n"); + +- /* start measurement */ ++ /* Start measurement */ + status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE); + if (status < 0) + goto error; +@@ -2893,42 +2956,42 @@ static int adc_sync_measurement(struct drxk_state *state, u16 *count) + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int adc_synchronization(struct drxk_state *state) ++static int ADCSynchronization(struct drxk_state *state) + { + u16 count = 0; + int status; + + dprintk(1, "\n"); + +- status = adc_sync_measurement(state, &count); ++ status = ADCSyncMeasurement(state, &count); + if (status < 0) + goto error; + + if (count == 1) { +- /* Try sampling on a different edge */ +- u16 clk_neg = 0; ++ /* Try sampling on a diffrent edge */ ++ u16 clkNeg = 0; + +- status = read16(state, IQM_AF_CLKNEG__A, &clk_neg); ++ status = read16(state, IQM_AF_CLKNEG__A, &clkNeg); + if (status < 0) + goto error; +- if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) == ++ if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) == + IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) { +- clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); +- clk_neg |= ++ clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); ++ clkNeg |= + IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG; + } else { +- clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); +- clk_neg |= ++ clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); ++ clkNeg |= + IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS; + } +- status = write16(state, IQM_AF_CLKNEG__A, clk_neg); ++ status = write16(state, IQM_AF_CLKNEG__A, clkNeg); + if (status < 0) + goto error; +- status = adc_sync_measurement(state, &count); ++ status = ADCSyncMeasurement(state, &count); + if (status < 0) + goto error; + } +@@ -2937,25 +3000,25 @@ static int adc_synchronization(struct drxk_state *state) + status = -EINVAL; + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_frequency_shifter(struct drxk_state *state, +- u16 intermediate_freqk_hz, +- s32 tuner_freq_offset, bool is_dtv) ++static int SetFrequencyShifter(struct drxk_state *state, ++ u16 intermediateFreqkHz, ++ s32 tunerFreqOffset, bool isDTV) + { +- bool select_pos_image = false; +- u32 rf_freq_residual = tuner_freq_offset; +- u32 fm_frequency_shift = 0; +- bool tuner_mirror = !state->m_b_mirror_freq_spect; +- u32 adc_freq; +- bool adc_flip; ++ bool selectPosImage = false; ++ u32 rfFreqResidual = tunerFreqOffset; ++ u32 fmFrequencyShift = 0; ++ bool tunerMirror = !state->m_bMirrorFreqSpect; ++ u32 adcFreq; ++ bool adcFlip; + int status; +- u32 if_freq_actual; +- u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3); +- u32 frequency_shift; +- bool image_to_select; ++ u32 ifFreqActual; ++ u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3); ++ u32 frequencyShift; ++ bool imageToSelect; + + dprintk(1, "\n"); + +@@ -2963,125 +3026,121 @@ static int set_frequency_shifter(struct drxk_state *state, + Program frequency shifter + No need to account for mirroring on RF + */ +- if (is_dtv) { +- if ((state->m_operation_mode == OM_QAM_ITU_A) || +- (state->m_operation_mode == OM_QAM_ITU_C) || +- (state->m_operation_mode == OM_DVBT)) +- select_pos_image = true; ++ if (isDTV) { ++ if ((state->m_OperationMode == OM_QAM_ITU_A) || ++ (state->m_OperationMode == OM_QAM_ITU_C) || ++ (state->m_OperationMode == OM_DVBT)) ++ selectPosImage = true; + else +- select_pos_image = false; ++ selectPosImage = false; + } +- if (tuner_mirror) ++ if (tunerMirror) + /* tuner doesn't mirror */ +- if_freq_actual = intermediate_freqk_hz + +- rf_freq_residual + fm_frequency_shift; ++ ifFreqActual = intermediateFreqkHz + ++ rfFreqResidual + fmFrequencyShift; + else + /* tuner mirrors */ +- if_freq_actual = intermediate_freqk_hz - +- rf_freq_residual - fm_frequency_shift; +- if (if_freq_actual > sampling_frequency / 2) { ++ ifFreqActual = intermediateFreqkHz - ++ rfFreqResidual - fmFrequencyShift; ++ if (ifFreqActual > samplingFrequency / 2) { + /* adc mirrors */ +- adc_freq = sampling_frequency - if_freq_actual; +- adc_flip = true; ++ adcFreq = samplingFrequency - ifFreqActual; ++ adcFlip = true; + } else { + /* adc doesn't mirror */ +- adc_freq = if_freq_actual; +- adc_flip = false; ++ adcFreq = ifFreqActual; ++ adcFlip = false; + } + +- frequency_shift = adc_freq; +- image_to_select = state->m_rfmirror ^ tuner_mirror ^ +- adc_flip ^ select_pos_image; +- state->m_iqm_fs_rate_ofs = +- Frac28a((frequency_shift), sampling_frequency); ++ frequencyShift = adcFreq; ++ imageToSelect = state->m_rfmirror ^ tunerMirror ^ ++ adcFlip ^ selectPosImage; ++ state->m_IqmFsRateOfs = ++ Frac28a((frequencyShift), samplingFrequency); + +- if (image_to_select) +- state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1; ++ if (imageToSelect) ++ state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1; + + /* Program frequency shifter with tuner offset compensation */ +- /* frequency_shift += tuner_freq_offset; TODO */ ++ /* frequencyShift += tunerFreqOffset; TODO */ + status = write32(state, IQM_FS_RATE_OFS_LO__A, +- state->m_iqm_fs_rate_ofs); ++ state->m_IqmFsRateOfs); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int init_agc(struct drxk_state *state, bool is_dtv) ++static int InitAGC(struct drxk_state *state, bool isDTV) + { +- u16 ingain_tgt = 0; +- u16 ingain_tgt_min = 0; +- u16 ingain_tgt_max = 0; +- u16 clp_cyclen = 0; +- u16 clp_sum_min = 0; +- u16 clp_dir_to = 0; +- u16 sns_sum_min = 0; +- u16 sns_sum_max = 0; +- u16 clp_sum_max = 0; +- u16 sns_dir_to = 0; +- u16 ki_innergain_min = 0; +- u16 if_iaccu_hi_tgt = 0; +- u16 if_iaccu_hi_tgt_min = 0; +- u16 if_iaccu_hi_tgt_max = 0; ++ u16 ingainTgt = 0; ++ u16 ingainTgtMin = 0; ++ u16 ingainTgtMax = 0; ++ u16 clpCyclen = 0; ++ u16 clpSumMin = 0; ++ u16 clpDirTo = 0; ++ u16 snsSumMin = 0; ++ u16 snsSumMax = 0; ++ u16 clpSumMax = 0; ++ u16 snsDirTo = 0; ++ u16 kiInnergainMin = 0; ++ u16 ifIaccuHiTgt = 0; ++ u16 ifIaccuHiTgtMin = 0; ++ u16 ifIaccuHiTgtMax = 0; + u16 data = 0; +- u16 fast_clp_ctrl_delay = 0; +- u16 clp_ctrl_mode = 0; ++ u16 fastClpCtrlDelay = 0; ++ u16 clpCtrlMode = 0; + int status = 0; + + dprintk(1, "\n"); + + /* Common settings */ +- sns_sum_max = 1023; +- if_iaccu_hi_tgt_min = 2047; +- clp_cyclen = 500; +- clp_sum_max = 1023; ++ snsSumMax = 1023; ++ ifIaccuHiTgtMin = 2047; ++ clpCyclen = 500; ++ clpSumMax = 1023; + + /* AGCInit() not available for DVBT; init done in microcode */ +- if (!is_qam(state)) { +- pr_err("%s: mode %d is not DVB-C\n", +- __func__, state->m_operation_mode); ++ if (!IsQAM(state)) { ++ printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode); + return -EINVAL; + } + + /* FIXME: Analog TV AGC require different settings */ + + /* Standard specific settings */ +- clp_sum_min = 8; +- clp_dir_to = (u16) -9; +- clp_ctrl_mode = 0; +- sns_sum_min = 8; +- sns_dir_to = (u16) -9; +- ki_innergain_min = (u16) -1030; +- if_iaccu_hi_tgt_max = 0x2380; +- if_iaccu_hi_tgt = 0x2380; +- ingain_tgt_min = 0x0511; +- ingain_tgt = 0x0511; +- ingain_tgt_max = 5119; +- fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay; ++ clpSumMin = 8; ++ clpDirTo = (u16) -9; ++ clpCtrlMode = 0; ++ snsSumMin = 8; ++ snsDirTo = (u16) -9; ++ kiInnergainMin = (u16) -1030; ++ ifIaccuHiTgtMax = 0x2380; ++ ifIaccuHiTgt = 0x2380; ++ ingainTgtMin = 0x0511; ++ ingainTgt = 0x0511; ++ ingainTgtMax = 5119; ++ fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay; + +- status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, +- fast_clp_ctrl_delay); ++ status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay); + if (status < 0) + goto error; + +- status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode); ++ status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, +- if_iaccu_hi_tgt_min); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- if_iaccu_hi_tgt_max); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax); + if (status < 0) + goto error; + status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0); +@@ -3096,22 +3155,20 @@ static int init_agc(struct drxk_state *state, bool is_dtv) + status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max); ++ status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max); ++ status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax); + if (status < 0) + goto error; + +- status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, +- ki_innergain_min); ++ status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, +- if_iaccu_hi_tgt); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen); ++ status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen); + if (status < 0) + goto error; + +@@ -3128,16 +3185,16 @@ static int init_agc(struct drxk_state *state, bool is_dtv) + status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min); ++ status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min); ++ status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to); ++ status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to); ++ status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo); + if (status < 0) + goto error; + status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff); +@@ -3197,39 +3254,38 @@ static int init_agc(struct drxk_state *state, bool is_dtv) + status = write16(state, SCU_RAM_AGC_KI__A, data); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err) ++static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr) + { + int status; + + dprintk(1, "\n"); +- if (packet_err == NULL) ++ if (packetErr == NULL) + status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); + else +- status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, +- packet_err); ++ status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbt_sc_command(struct drxk_state *state, ++static int DVBTScCommand(struct drxk_state *state, + u16 cmd, u16 subcmd, + u16 param0, u16 param1, u16 param2, + u16 param3, u16 param4) + { +- u16 cur_cmd = 0; +- u16 err_code = 0; +- u16 retry_cnt = 0; +- u16 sc_exec = 0; ++ u16 curCmd = 0; ++ u16 errCode = 0; ++ u16 retryCnt = 0; ++ u16 scExec = 0; + int status; + + dprintk(1, "\n"); +- status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec); +- if (sc_exec != 1) { ++ status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec); ++ if (scExec != 1) { + /* SC is not running */ + status = -EINVAL; + } +@@ -3237,13 +3293,13 @@ static int dvbt_sc_command(struct drxk_state *state, + goto error; + + /* Wait until sc is ready to receive command */ +- retry_cnt = 0; ++ retryCnt = 0; + do { +- usleep_range(1000, 2000); +- status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); +- retry_cnt++; +- } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); +- if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) ++ msleep(1); ++ status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd); ++ retryCnt++; ++ } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES)); ++ if (retryCnt >= DRXK_MAX_RETRIES && (status < 0)) + goto error; + + /* Write sub-command */ +@@ -3289,25 +3345,25 @@ static int dvbt_sc_command(struct drxk_state *state, + goto error; + + /* Wait until sc is ready processing command */ +- retry_cnt = 0; ++ retryCnt = 0; + do { +- usleep_range(1000, 2000); +- status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); +- retry_cnt++; +- } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); +- if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) ++ msleep(1); ++ status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd); ++ retryCnt++; ++ } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES)); ++ if (retryCnt >= DRXK_MAX_RETRIES && (status < 0)) + goto error; + + /* Check for illegal cmd */ +- status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code); +- if (err_code == 0xFFFF) { ++ status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode); ++ if (errCode == 0xFFFF) { + /* illegal command */ + status = -EINVAL; + } + if (status < 0) + goto error; + +- /* Retrieve results parameters from SC */ ++ /* Retreive results parameters from SC */ + switch (cmd) { + /* All commands yielding 5 results */ + /* All commands yielding 4 results */ +@@ -3332,44 +3388,44 @@ static int dvbt_sc_command(struct drxk_state *state, + } /* switch (cmd->cmd) */ + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int power_up_dvbt(struct drxk_state *state) ++static int PowerUpDVBT(struct drxk_state *state) + { +- enum drx_power_mode power_mode = DRX_POWER_UP; ++ enum DRXPowerMode powerMode = DRX_POWER_UP; + int status; + + dprintk(1, "\n"); +- status = ctrl_power_mode(state, &power_mode); ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled) ++static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled) + { + int status; + + dprintk(1, "\n"); +- if (*enabled) ++ if (*enabled == true) + status = write16(state, IQM_CF_BYPASSDET__A, 0); + else + status = write16(state, IQM_CF_BYPASSDET__A, 1); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + #define DEFAULT_FR_THRES_8K 4000 +-static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) ++static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled) + { + + int status; + + dprintk(1, "\n"); +- if (*enabled) { ++ if (*enabled == true) { + /* write mask to 1 */ + status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, + DEFAULT_FR_THRES_8K); +@@ -3378,13 +3434,13 @@ static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) + status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0); + } + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, +- struct drxk_cfg_dvbt_echo_thres_t *echo_thres) ++static int DVBTCtrlSetEchoThreshold(struct drxk_state *state, ++ struct DRXKCfgDvbtEchoThres_t *echoThres) + { + u16 data = 0; + int status; +@@ -3394,16 +3450,16 @@ static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, + if (status < 0) + goto error; + +- switch (echo_thres->fft_mode) { ++ switch (echoThres->fftMode) { + case DRX_FFTMODE_2K: + data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M; +- data |= ((echo_thres->threshold << ++ data |= ((echoThres->threshold << + OFDM_SC_RA_RAM_ECHO_THRES_2K__B) + & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M)); + break; + case DRX_FFTMODE_8K: + data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M; +- data |= ((echo_thres->threshold << ++ data |= ((echoThres->threshold << + OFDM_SC_RA_RAM_ECHO_THRES_8K__B) + & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M)); + break; +@@ -3414,12 +3470,12 @@ static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, + status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, +- enum drxk_cfg_dvbt_sqi_speed *speed) ++static int DVBTCtrlSetSqiSpeed(struct drxk_state *state, ++ enum DRXKCfgDvbtSqiSpeed *speed) + { + int status = -EINVAL; + +@@ -3437,7 +3493,7 @@ static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, + (u16) *speed); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -3451,33 +3507,32 @@ error: + * Called in DVBTSetStandard + * + */ +-static int dvbt_activate_presets(struct drxk_state *state) ++static int DVBTActivatePresets(struct drxk_state *state) + { + int status; + bool setincenable = false; + bool setfrenable = true; + +- struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K }; +- struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K }; ++ struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K }; ++ struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K }; + + dprintk(1, "\n"); +- status = dvbt_ctrl_set_inc_enable(state, &setincenable); ++ status = DVBTCtrlSetIncEnable(state, &setincenable); + if (status < 0) + goto error; +- status = dvbt_ctrl_set_fr_enable(state, &setfrenable); ++ status = DVBTCtrlSetFrEnable(state, &setfrenable); + if (status < 0) + goto error; +- status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k); ++ status = DVBTCtrlSetEchoThreshold(state, &echoThres2k); + if (status < 0) + goto error; +- status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k); ++ status = DVBTCtrlSetEchoThreshold(state, &echoThres8k); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, +- state->m_dvbt_if_agc_cfg.ingain_tgt_max); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -3491,30 +3546,25 @@ error: + * For ROM code channel filter taps are loaded from the bootloader. For microcode + * the DVB-T taps from the drxk_filters.h are used. + */ +-static int set_dvbt_standard(struct drxk_state *state, +- enum operation_mode o_mode) ++static int SetDVBTStandard(struct drxk_state *state, ++ enum OperationMode oMode) + { +- u16 cmd_result = 0; ++ u16 cmdResult = 0; + u16 data = 0; + int status; + + dprintk(1, "\n"); + +- power_up_dvbt(state); ++ PowerUpDVBT(state); + /* added antenna switch */ +- switch_antenna_to_dvbt(state); ++ SwitchAntennaToDVBT(state); + /* send OFDM reset command */ +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_RESET, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + + /* send OFDM setenv command */ +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -3546,7 +3596,7 @@ static int set_dvbt_standard(struct drxk_state *state, + status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); + if (status < 0) + goto error; +- status = set_iqm_af(state, true); ++ status = SetIqmAf(state, true); + if (status < 0) + goto error; + +@@ -3568,7 +3618,7 @@ static int set_dvbt_standard(struct drxk_state *state, + status = write16(state, IQM_RC_STRETCH__A, 16); + if (status < 0) + goto error; +- status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ ++ status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ + if (status < 0) + goto error; + status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */ +@@ -3589,8 +3639,7 @@ static int set_dvbt_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, +- DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); ++ status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + if (status < 0) + goto error; + +@@ -3609,10 +3658,10 @@ static int set_dvbt_standard(struct drxk_state *state, + goto error; + + /* IQM will not be reset from here, sync ADC and update/init AGC */ +- status = adc_synchronization(state); ++ status = ADCSynchronization(state); + if (status < 0) + goto error; +- status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg); ++ status = SetPreSaw(state, &state->m_dvbtPreSawCfg); + if (status < 0) + goto error; + +@@ -3621,10 +3670,10 @@ static int set_dvbt_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true); ++ status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true); + if (status < 0) + goto error; +- status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true); ++ status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true); + if (status < 0) + goto error; + +@@ -3642,10 +3691,9 @@ static int set_dvbt_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- if (!state->m_drxk_a3_rom_code) { +- /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */ +- status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, +- state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay); ++ if (!state->m_DRXK_A3_ROM_CODE) { ++ /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */ ++ status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay); + if (status < 0) + goto error; + } +@@ -3680,43 +3728,41 @@ static int set_dvbt_standard(struct drxk_state *state, + goto error; + + /* Setup MPEG bus */ +- status = mpegts_dto_setup(state, OM_DVBT); ++ status = MPEGTSDtoSetup(state, OM_DVBT); + if (status < 0) + goto error; + /* Set DVBT Presets */ +- status = dvbt_activate_presets(state); ++ status = DVBTActivatePresets(state); + if (status < 0) + goto error; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + /*============================================================================*/ + /** +-* \brief start dvbt demodulating for channel. ++* \brief Start dvbt demodulating for channel. + * \param demod instance of demodulator. + * \return DRXStatus_t. + */ +-static int dvbt_start(struct drxk_state *state) ++static int DVBTStart(struct drxk_state *state) + { + u16 param1; + int status; +- /* drxk_ofdm_sc_cmd_t scCmd; */ ++ /* DRXKOfdmScCmd_t scCmd; */ + + dprintk(1, "\n"); +- /* start correct processes to get in lock */ ++ /* Start correct processes to get in lock */ + /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */ + param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN; +- status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, +- OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, +- 0, 0, 0); ++ status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0); + if (status < 0) + goto error; +- /* start FEC OC */ +- status = mpegts_start(state); ++ /* Start FEC OC */ ++ status = MPEGTSStart(state); + if (status < 0) + goto error; + status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); +@@ -3724,7 +3770,7 @@ static int dvbt_start(struct drxk_state *state) + goto error; + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -3737,23 +3783,20 @@ error: + * \return DRXStatus_t. + * // original DVBTSetChannel() + */ +-static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset) ++static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset) + { +- u16 cmd_result = 0; +- u16 transmission_params = 0; +- u16 operation_mode = 0; +- u32 iqm_rc_rate_ofs = 0; ++ u16 cmdResult = 0; ++ u16 transmissionParams = 0; ++ u16 operationMode = 0; ++ u32 iqmRcRateOfs = 0; + u32 bandwidth = 0; + u16 param1; + int status; + +- dprintk(1, "IF =%d, TFO = %d\n", +- intermediate_freqk_hz, tuner_freq_offset); ++ dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset); + +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_STOP, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -3776,19 +3819,19 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + if (status < 0) + goto error; + +- /*== Write channel settings to device ================================*/ ++ /*== Write channel settings to device =====================================*/ + + /* mode */ + switch (state->props.transmission_mode) { + case TRANSMISSION_MODE_AUTO: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; + /* fall through , try first guess DRX_FFTMODE_8K */ + case TRANSMISSION_MODE_8K: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; + break; + case TRANSMISSION_MODE_2K: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; + break; + } + +@@ -3796,19 +3839,19 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + switch (state->props.guard_interval) { + default: + case GUARD_INTERVAL_AUTO: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; + /* fall through , try first guess DRX_GUARD_1DIV4 */ + case GUARD_INTERVAL_1_4: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; + break; + case GUARD_INTERVAL_1_32: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; + break; + case GUARD_INTERVAL_1_16: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; + break; + case GUARD_INTERVAL_1_8: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; + break; + } + +@@ -3817,18 +3860,18 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M; + /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */ +- /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */ ++ /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */ + /* break; */ + case HIERARCHY_1: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; + break; + case HIERARCHY_2: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; + break; + case HIERARCHY_4: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; + break; + } + +@@ -3837,30 +3880,30 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + switch (state->props.modulation) { + case QAM_AUTO: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; + /* fall through , try first guess DRX_CONSTELLATION_QAM64 */ + case QAM_64: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; + break; + case QPSK: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; + break; + case QAM_16: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; + break; + } + #if 0 +- /* No hierarchical channels support in BDA */ ++ /* No hierachical channels support in BDA */ + /* Priority (only for hierarchical channels) */ + switch (channel->priority) { + case DRX_PRIORITY_LOW: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; +- WR16(dev_addr, OFDM_EC_SB_PRIOR__A, ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; ++ WR16(devAddr, OFDM_EC_SB_PRIOR__A, + OFDM_EC_SB_PRIOR_LO); + break; + case DRX_PRIORITY_HIGH: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; +- WR16(dev_addr, OFDM_EC_SB_PRIOR__A, ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; ++ WR16(devAddr, OFDM_EC_SB_PRIOR__A, + OFDM_EC_SB_PRIOR_HI)); + break; + case DRX_PRIORITY_UNKNOWN: /* fall through */ +@@ -3870,7 +3913,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + } + #else + /* Set Priorty high */ +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; + status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI); + if (status < 0) + goto error; +@@ -3880,111 +3923,90 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + switch (state->props.code_rate_HP) { + case FEC_AUTO: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; + /* fall through , try first guess DRX_CODERATE_2DIV3 */ + case FEC_2_3: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; + break; + case FEC_1_2: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; + break; + case FEC_3_4: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; + break; + case FEC_5_6: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; + break; + case FEC_7_8: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; + break; + } + +- /* +- * SAW filter selection: normaly not necesarry, but if wanted +- * the application can select a SAW filter via the driver by +- * using UIOs +- */ +- ++ /* SAW filter selection: normaly not necesarry, but if wanted ++ the application can select a SAW filter via the driver by using UIOs */ + /* First determine real bandwidth (Hz) */ + /* Also set delay for impulse noise cruncher */ +- /* +- * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is +- * changed by SC for fix for some 8K,1/8 guard but is restored by +- * InitEC and ResetEC functions +- */ ++ /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed ++ by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC ++ functions */ + switch (state->props.bandwidth_hz) { + case 0: + state->props.bandwidth_hz = 8000000; + /* fall though */ + case 8000000: + bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ; +- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, +- 3052); ++ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052); + if (status < 0) + goto error; + /* cochannel protection for PAL 8 MHz */ +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, +- 7); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, +- 7); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, +- 7); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, +- 1); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1); + if (status < 0) + goto error; + break; + case 7000000: + bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ; +- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, +- 3491); ++ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491); + if (status < 0) + goto error; + /* cochannel protection for PAL 7 MHz */ +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, +- 8); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, +- 8); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, +- 4); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, +- 1); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1); + if (status < 0) + goto error; + break; + case 6000000: + bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ; +- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, +- 4073); ++ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073); + if (status < 0) + goto error; + /* cochannel protection for NTSC 6 MHz */ +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, +- 19); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, +- 19); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, +- 14); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, +- 1); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1); + if (status < 0) + goto error; + break; +@@ -3993,50 +4015,46 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + } + +- if (iqm_rc_rate_ofs == 0) { ++ if (iqmRcRateOfs == 0) { + /* Now compute IQM_RC_RATE_OFS + (((SysFreq/BandWidth)/2)/2) -1) * 2^23) + => + ((SysFreq / BandWidth) * (2^21)) - (2^23) + */ + /* (SysFreq / BandWidth) * (2^28) */ +- /* +- * assert (MAX(sysClk)/MIN(bandwidth) < 16) +- * => assert(MAX(sysClk) < 16*MIN(bandwidth)) +- * => assert(109714272 > 48000000) = true +- * so Frac 28 can be used +- */ +- iqm_rc_rate_ofs = Frac28a((u32) +- ((state->m_sys_clock_freq * ++ /* assert (MAX(sysClk)/MIN(bandwidth) < 16) ++ => assert(MAX(sysClk) < 16*MIN(bandwidth)) ++ => assert(109714272 > 48000000) = true so Frac 28 can be used */ ++ iqmRcRateOfs = Frac28a((u32) ++ ((state->m_sysClockFreq * + 1000) / 3), bandwidth); +- /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ +- if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40) +- iqm_rc_rate_ofs += 0x80L; +- iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7; ++ /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ ++ if ((iqmRcRateOfs & 0x7fL) >= 0x40) ++ iqmRcRateOfs += 0x80L; ++ iqmRcRateOfs = iqmRcRateOfs >> 7; + /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */ +- iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23); ++ iqmRcRateOfs = iqmRcRateOfs - (1 << 23); + } + +- iqm_rc_rate_ofs &= ++ iqmRcRateOfs &= + ((((u32) IQM_RC_RATE_OFS_HI__M) << + IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M); +- status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs); ++ status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs); + if (status < 0) + goto error; + + /* Bandwidth setting done */ + + #if 0 +- status = dvbt_set_frequency_shift(demod, channel, tuner_offset); ++ status = DVBTSetFrequencyShift(demod, channel, tunerOffset); + if (status < 0) + goto error; + #endif +- status = set_frequency_shifter(state, intermediate_freqk_hz, +- tuner_freq_offset, true); ++ status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true); + if (status < 0) + goto error; + +- /*== start SC, write channel settings to SC ==========================*/ ++ /*== Start SC, write channel settings to SC ===============================*/ + + /* Activate SCU to enable SCU commands */ + status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); +@@ -4052,9 +4070,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + + +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_START, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -4064,16 +4080,16 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + OFDM_SC_RA_RAM_OP_AUTO_CONST__M | + OFDM_SC_RA_RAM_OP_AUTO_HIER__M | + OFDM_SC_RA_RAM_OP_AUTO_RATE__M); +- status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, +- 0, transmission_params, param1, 0, 0, 0); ++ status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, ++ 0, transmissionParams, param1, 0, 0, 0); + if (status < 0) + goto error; + +- if (!state->m_drxk_a3_rom_code) +- status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed); ++ if (!state->m_DRXK_A3_ROM_CODE) ++ status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -4082,13 +4098,13 @@ error: + /*============================================================================*/ + + /** +-* \brief Retrieve lock status . ++* \brief Retreive lock status . + * \param demod Pointer to demodulator instance. + * \param lockStat Pointer to lock status structure. + * \return DRXStatus_t. + * + */ +-static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) ++static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus) + { + int status; + const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M | +@@ -4096,58 +4112,58 @@ static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) + const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M); + const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M; + +- u16 sc_ra_ram_lock = 0; +- u16 sc_comm_exec = 0; ++ u16 ScRaRamLock = 0; ++ u16 ScCommExec = 0; + + dprintk(1, "\n"); + +- *p_lock_status = NOT_LOCKED; ++ *pLockStatus = NOT_LOCKED; + /* driver 0.9.0 */ + /* Check if SC is running */ +- status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec); ++ status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec); + if (status < 0) + goto end; +- if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP) ++ if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) + goto end; + +- status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock); ++ status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock); + if (status < 0) + goto end; + +- if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask) +- *p_lock_status = MPEG_LOCK; +- else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask) +- *p_lock_status = FEC_LOCK; +- else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask) +- *p_lock_status = DEMOD_LOCK; +- else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) +- *p_lock_status = NEVER_LOCK; ++ if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) ++ *pLockStatus = MPEG_LOCK; ++ else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask) ++ *pLockStatus = FEC_LOCK; ++ else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask) ++ *pLockStatus = DEMOD_LOCK; ++ else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) ++ *pLockStatus = NEVER_LOCK; + end: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int power_up_qam(struct drxk_state *state) ++static int PowerUpQAM(struct drxk_state *state) + { +- enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; ++ enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; + int status; + + dprintk(1, "\n"); +- status = ctrl_power_mode(state, &power_mode); ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + + + /** Power Down QAM */ +-static int power_down_qam(struct drxk_state *state) ++static int PowerDownQAM(struct drxk_state *state) + { + u16 data = 0; +- u16 cmd_result; ++ u16 cmdResult; + int status = 0; + + dprintk(1, "\n"); +@@ -4163,18 +4179,16 @@ static int power_down_qam(struct drxk_state *state) + status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); + if (status < 0) + goto error; +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_STOP, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + } + /* powerdown AFE */ +- status = set_iqm_af(state, false); ++ status = SetIqmAf(state, false); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -4192,20 +4206,20 @@ error: + * The implementation does not check this. + * + */ +-static int set_qam_measurement(struct drxk_state *state, +- enum e_drxk_constellation modulation, +- u32 symbol_rate) ++static int SetQAMMeasurement(struct drxk_state *state, ++ enum EDrxkConstellation modulation, ++ u32 symbolRate) + { +- u32 fec_bits_desired = 0; /* BER accounting period */ +- u32 fec_rs_period_total = 0; /* Total period */ +- u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */ +- u16 fec_rs_period = 0; /* Value for corresponding I2C register */ ++ u32 fecBitsDesired = 0; /* BER accounting period */ ++ u32 fecRsPeriodTotal = 0; /* Total period */ ++ u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */ ++ u16 fecRsPeriod = 0; /* Value for corresponding I2C register */ + int status = 0; + + dprintk(1, "\n"); + +- fec_rs_prescale = 1; +- /* fec_bits_desired = symbol_rate [kHz] * ++ fecRsPrescale = 1; ++ /* fecBitsDesired = symbolRate [kHz] * + FrameLenght [ms] * + (modulation + 1) * + SyncLoss (== 1) * +@@ -4213,19 +4227,19 @@ static int set_qam_measurement(struct drxk_state *state, + */ + switch (modulation) { + case DRX_CONSTELLATION_QAM16: +- fec_bits_desired = 4 * symbol_rate; ++ fecBitsDesired = 4 * symbolRate; + break; + case DRX_CONSTELLATION_QAM32: +- fec_bits_desired = 5 * symbol_rate; ++ fecBitsDesired = 5 * symbolRate; + break; + case DRX_CONSTELLATION_QAM64: +- fec_bits_desired = 6 * symbol_rate; ++ fecBitsDesired = 6 * symbolRate; + break; + case DRX_CONSTELLATION_QAM128: +- fec_bits_desired = 7 * symbol_rate; ++ fecBitsDesired = 7 * symbolRate; + break; + case DRX_CONSTELLATION_QAM256: +- fec_bits_desired = 8 * symbol_rate; ++ fecBitsDesired = 8 * symbolRate; + break; + default: + status = -EINVAL; +@@ -4233,41 +4247,40 @@ static int set_qam_measurement(struct drxk_state *state, + if (status < 0) + goto error; + +- fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */ +- fec_bits_desired *= 500; /* meas. period [ms] */ ++ fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */ ++ fecBitsDesired *= 500; /* meas. period [ms] */ + + /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */ +- /* fec_rs_period_total = fec_bits_desired / 1632 */ +- fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */ ++ /* fecRsPeriodTotal = fecBitsDesired / 1632 */ ++ fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */ + +- /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */ +- fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16); +- if (fec_rs_prescale == 0) { ++ /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */ ++ fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16); ++ if (fecRsPrescale == 0) { + /* Divide by zero (though impossible) */ + status = -EINVAL; + if (status < 0) + goto error; + } +- fec_rs_period = +- ((u16) fec_rs_period_total + +- (fec_rs_prescale >> 1)) / fec_rs_prescale; ++ fecRsPeriod = ++ ((u16) fecRsPeriodTotal + ++ (fecRsPrescale >> 1)) / fecRsPrescale; + + /* write corresponding registers */ +- status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period); ++ status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod); + if (status < 0) + goto error; +- status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, +- fec_rs_prescale); ++ status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period); ++ status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_qam16(struct drxk_state *state) ++static int SetQAM16(struct drxk_state *state) + { + int status = 0; + +@@ -4323,8 +4336,7 @@ static int set_qam16(struct drxk_state *state) + goto error; + + /* QAM Slicer Settings */ +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM16); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16); + if (status < 0) + goto error; + +@@ -4450,7 +4462,7 @@ static int set_qam16(struct drxk_state *state) + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -4461,7 +4473,7 @@ error: + * \param demod instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam32(struct drxk_state *state) ++static int SetQAM32(struct drxk_state *state) + { + int status = 0; + +@@ -4520,8 +4532,7 @@ static int set_qam32(struct drxk_state *state) + + /* QAM Slicer Settings */ + +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM32); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32); + if (status < 0) + goto error; + +@@ -4646,7 +4657,7 @@ static int set_qam32(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -4657,7 +4668,7 @@ error: + * \param demod instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam64(struct drxk_state *state) ++static int SetQAM64(struct drxk_state *state) + { + int status = 0; + +@@ -4714,8 +4725,7 @@ static int set_qam64(struct drxk_state *state) + goto error; + + /* QAM Slicer Settings */ +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM64); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64); + if (status < 0) + goto error; + +@@ -4840,7 +4850,7 @@ static int set_qam64(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -4852,7 +4862,7 @@ error: + * \param demod: instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam128(struct drxk_state *state) ++static int SetQAM128(struct drxk_state *state) + { + int status = 0; + +@@ -4911,8 +4921,7 @@ static int set_qam128(struct drxk_state *state) + + /* QAM Slicer Settings */ + +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM128); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128); + if (status < 0) + goto error; + +@@ -5037,7 +5046,7 @@ static int set_qam128(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -5049,7 +5058,7 @@ error: + * \param demod: instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam256(struct drxk_state *state) ++static int SetQAM256(struct drxk_state *state) + { + int status = 0; + +@@ -5107,8 +5116,7 @@ static int set_qam256(struct drxk_state *state) + + /* QAM Slicer Settings */ + +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM256); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256); + if (status < 0) + goto error; + +@@ -5233,7 +5241,7 @@ static int set_qam256(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -5245,10 +5253,10 @@ error: + * \param channel: pointer to channel data. + * \return DRXStatus_t. + */ +-static int qam_reset_qam(struct drxk_state *state) ++static int QAMResetQAM(struct drxk_state *state) + { + int status; +- u16 cmd_result; ++ u16 cmdResult; + + dprintk(1, "\n"); + /* Stop QAM comstate->m_exec */ +@@ -5256,12 +5264,10 @@ static int qam_reset_qam(struct drxk_state *state) + if (status < 0) + goto error; + +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_RESET, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -5273,18 +5279,18 @@ error: + * \param channel: pointer to channel data. + * \return DRXStatus_t. + */ +-static int qam_set_symbolrate(struct drxk_state *state) ++static int QAMSetSymbolrate(struct drxk_state *state) + { +- u32 adc_frequency = 0; +- u32 symb_freq = 0; +- u32 iqm_rc_rate = 0; ++ u32 adcFrequency = 0; ++ u32 symbFreq = 0; ++ u32 iqmRcRate = 0; + u16 ratesel = 0; +- u32 lc_symb_rate = 0; ++ u32 lcSymbRate = 0; + int status; + + dprintk(1, "\n"); + /* Select & calculate correct IQM rate */ +- adc_frequency = (state->m_sys_clock_freq * 1000) / 3; ++ adcFrequency = (state->m_sysClockFreq * 1000) / 3; + ratesel = 0; + /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */ + if (state->props.symbol_rate <= 1188750) +@@ -5300,38 +5306,38 @@ static int qam_set_symbolrate(struct drxk_state *state) + /* + IqmRcRate = ((Fadc / (symbolrate * (4<props.symbol_rate * (1 << ratesel); +- if (symb_freq == 0) { ++ symbFreq = state->props.symbol_rate * (1 << ratesel); ++ if (symbFreq == 0) { + /* Divide by zero */ + status = -EINVAL; + goto error; + } +- iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) + +- (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) - ++ iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) + ++ (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) - + (1 << 23); +- status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate); ++ status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate); + if (status < 0) + goto error; +- state->m_iqm_rc_rate = iqm_rc_rate; ++ state->m_iqmRcRate = iqmRcRate; + /* +- LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15)) ++ LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15)) + */ +- symb_freq = state->props.symbol_rate; +- if (adc_frequency == 0) { ++ symbFreq = state->props.symbol_rate; ++ if (adcFrequency == 0) { + /* Divide by zero */ + status = -EINVAL; + goto error; + } +- lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) + +- (Frac28a((symb_freq % adc_frequency), adc_frequency) >> ++ lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) + ++ (Frac28a((symbFreq % adcFrequency), adcFrequency) >> + 16); +- if (lc_symb_rate > 511) +- lc_symb_rate = 511; +- status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate); ++ if (lcSymbRate > 511) ++ lcSymbRate = 511; ++ status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -5344,36 +5350,34 @@ error: + * \return DRXStatus_t. + */ + +-static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) ++static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus) + { + int status; +- u16 result[2] = { 0, 0 }; ++ u16 Result[2] = { 0, 0 }; + + dprintk(1, "\n"); +- *p_lock_status = NOT_LOCKED; ++ *pLockStatus = NOT_LOCKED; + status = scu_command(state, + SCU_RAM_COMMAND_STANDARD_QAM | + SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, +- result); ++ Result); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status); + +- if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { ++ if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { + /* 0x0000 NOT LOCKED */ +- } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { ++ } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { + /* 0x4000 DEMOD LOCKED */ +- *p_lock_status = DEMOD_LOCK; +- } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { ++ *pLockStatus = DEMOD_LOCK; ++ } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { + /* 0x8000 DEMOD + FEC LOCKED (system lock) */ +- *p_lock_status = MPEG_LOCK; ++ *pLockStatus = MPEG_LOCK; + } else { + /* 0xC000 NEVER LOCKED */ + /* (system will never be able to lock to the signal) */ +- /* +- * TODO: check this, intermediate & standard specific lock +- * states are not taken into account here +- */ +- *p_lock_status = NEVER_LOCK; ++ /* TODO: check this, intermediate & standard specific lock states are not ++ taken into account here */ ++ *pLockStatus = NEVER_LOCK; + } + return status; + } +@@ -5385,70 +5389,12 @@ static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) + #define QAM_LOCKRANGE__M 0x10 + #define QAM_LOCKRANGE_NORMAL 0x10 + +-static int qam_demodulator_command(struct drxk_state *state, +- int number_of_parameters) ++static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset) + { + int status; +- u16 cmd_result; +- u16 set_param_parameters[4] = { 0, 0, 0, 0 }; +- +- set_param_parameters[0] = state->m_constellation; /* modulation */ +- set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ +- +- if (number_of_parameters == 2) { +- u16 set_env_parameters[1] = { 0 }; +- +- if (state->m_operation_mode == OM_QAM_ITU_C) +- set_env_parameters[0] = QAM_TOP_ANNEX_C; +- else +- set_env_parameters[0] = QAM_TOP_ANNEX_A; +- +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, +- 1, set_env_parameters, 1, &cmd_result); +- if (status < 0) +- goto error; +- +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, +- number_of_parameters, set_param_parameters, +- 1, &cmd_result); +- } else if (number_of_parameters == 4) { +- if (state->m_operation_mode == OM_QAM_ITU_C) +- set_param_parameters[2] = QAM_TOP_ANNEX_C; +- else +- set_param_parameters[2] = QAM_TOP_ANNEX_A; +- +- set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON); +- /* Env parameters */ +- /* check for LOCKRANGE Extented */ +- /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */ +- +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, +- number_of_parameters, set_param_parameters, +- 1, &cmd_result); +- } else { +- pr_warn("Unknown QAM demodulator parameter count %d\n", +- number_of_parameters); +- status = -EINVAL; +- } +- +-error: +- if (status < 0) +- pr_warn("Warning %d on %s\n", status, __func__); +- return status; +-} +- +-static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset) +-{ +- int status; +- u16 cmd_result; +- int qam_demod_param_count = state->qam_demod_parameter_count; ++ u16 setParamParameters[4] = { 0, 0, 0, 0 }; ++ u16 cmdResult; + + dprintk(1, "\n"); + /* +@@ -5463,7 +5409,7 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP); + if (status < 0) + goto error; +- status = qam_reset_qam(state); ++ status = QAMResetQAM(state); + if (status < 0) + goto error; + +@@ -5472,27 +5418,27 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + * -set params; resets IQM,QAM,FEC HW; initializes some + * SCU variables + */ +- status = qam_set_symbolrate(state); ++ status = QAMSetSymbolrate(state); + if (status < 0) + goto error; + + /* Set params */ + switch (state->props.modulation) { + case QAM_256: +- state->m_constellation = DRX_CONSTELLATION_QAM256; ++ state->m_Constellation = DRX_CONSTELLATION_QAM256; + break; + case QAM_AUTO: + case QAM_64: +- state->m_constellation = DRX_CONSTELLATION_QAM64; ++ state->m_Constellation = DRX_CONSTELLATION_QAM64; + break; + case QAM_16: +- state->m_constellation = DRX_CONSTELLATION_QAM16; ++ state->m_Constellation = DRX_CONSTELLATION_QAM16; + break; + case QAM_32: +- state->m_constellation = DRX_CONSTELLATION_QAM32; ++ state->m_Constellation = DRX_CONSTELLATION_QAM32; + break; + case QAM_128: +- state->m_constellation = DRX_CONSTELLATION_QAM128; ++ state->m_Constellation = DRX_CONSTELLATION_QAM128; + break; + default: + status = -EINVAL; +@@ -5500,60 +5446,50 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + } + if (status < 0) + goto error; ++ setParamParameters[0] = state->m_Constellation; /* modulation */ ++ setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ ++ if (state->m_OperationMode == OM_QAM_ITU_C) ++ setParamParameters[2] = QAM_TOP_ANNEX_C; ++ else ++ setParamParameters[2] = QAM_TOP_ANNEX_A; ++ setParamParameters[3] |= (QAM_MIRROR_AUTO_ON); ++ /* Env parameters */ ++ /* check for LOCKRANGE Extented */ ++ /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */ + +- /* Use the 4-parameter if it's requested or we're probing for +- * the correct command. */ +- if (state->qam_demod_parameter_count == 4 +- || !state->qam_demod_parameter_count) { +- qam_demod_param_count = 4; +- status = qam_demodulator_command(state, qam_demod_param_count); +- } +- +- /* Use the 2-parameter command if it was requested or if we're +- * probing for the correct command and the 4-parameter command +- * failed. */ +- if (state->qam_demod_parameter_count == 2 +- || (!state->qam_demod_parameter_count && status < 0)) { +- qam_demod_param_count = 2; +- status = qam_demodulator_command(state, qam_demod_param_count); +- } +- ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult); + if (status < 0) { +- dprintk(1, "Could not set demodulator parameters.\n"); +- dprintk(1, +- "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n", +- state->qam_demod_parameter_count, +- state->microcode_name); +- goto error; +- } else if (!state->qam_demod_parameter_count) { +- dprintk(1, +- "Auto-probing the QAM command parameters was successful - using %d parameters.\n", +- qam_demod_param_count); ++ /* Fall-back to the simpler call */ ++ if (state->m_OperationMode == OM_QAM_ITU_C) ++ setParamParameters[0] = QAM_TOP_ANNEX_C; ++ else ++ setParamParameters[0] = QAM_TOP_ANNEX_A; ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult); ++ if (status < 0) ++ goto error; + +- /* +- * One of our commands was successful. We don't need to +- * auto-probe anymore, now that we got the correct command. +- */ +- state->qam_demod_parameter_count = qam_demod_param_count; ++ setParamParameters[0] = state->m_Constellation; /* modulation */ ++ setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult); + } ++ if (status < 0) ++ goto error; + + /* + * STEP 3: enable the system in a mode where the ADC provides valid + * signal setup modulation independent registers + */ + #if 0 +- status = set_frequency(channel, tuner_freq_offset)); ++ status = SetFrequency(channel, tunerFreqOffset)); + if (status < 0) + goto error; + #endif +- status = set_frequency_shifter(state, intermediate_freqk_hz, +- tuner_freq_offset, true); ++ status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true); + if (status < 0) + goto error; + + /* Setup BER measurement */ +- status = set_qam_measurement(state, state->m_constellation, +- state->props.symbol_rate); ++ status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate); + if (status < 0) + goto error; + +@@ -5626,8 +5562,7 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + + /* Mirroring, QAM-block starting point not inverted */ +- status = write16(state, QAM_SY_SP_INV__A, +- QAM_SY_SP_INV_SPECTRUM_INV_DIS); ++ status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS); + if (status < 0) + goto error; + +@@ -5639,20 +5574,20 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + /* STEP 4: modulation specific setup */ + switch (state->props.modulation) { + case QAM_16: +- status = set_qam16(state); ++ status = SetQAM16(state); + break; + case QAM_32: +- status = set_qam32(state); ++ status = SetQAM32(state); + break; + case QAM_AUTO: + case QAM_64: +- status = set_qam64(state); ++ status = SetQAM64(state); + break; + case QAM_128: +- status = set_qam128(state); ++ status = SetQAM128(state); + break; + case QAM_256: +- status = set_qam256(state); ++ status = SetQAM256(state); + break; + default: + status = -EINVAL; +@@ -5669,12 +5604,12 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + /* Re-configure MPEG output, requires knowledge of channel bitrate */ + /* extAttr->currentChannel.modulation = channel->modulation; */ + /* extAttr->currentChannel.symbolrate = channel->symbolrate; */ +- status = mpegts_dto_setup(state, state->m_operation_mode); ++ status = MPEGTSDtoSetup(state, state->m_OperationMode); + if (status < 0) + goto error; + +- /* start processes */ +- status = mpegts_start(state); ++ /* Start processes */ ++ status = MPEGTSStart(state); + if (status < 0) + goto error; + status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); +@@ -5688,9 +5623,7 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + + /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */ +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_START, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -5699,12 +5632,12 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_qam_standard(struct drxk_state *state, +- enum operation_mode o_mode) ++static int SetQAMStandard(struct drxk_state *state, ++ enum OperationMode oMode) + { + int status; + #ifdef DRXK_QAM_TAPS +@@ -5716,14 +5649,14 @@ static int set_qam_standard(struct drxk_state *state, + dprintk(1, "\n"); + + /* added antenna switch */ +- switch_antenna_to_qam(state); ++ SwitchAntennaToQAM(state); + + /* Ensure correct power-up mode */ +- status = power_up_qam(state); ++ status = PowerUpQAM(state); + if (status < 0) + goto error; + /* Reset QAM block */ +- status = qam_reset_qam(state); ++ status = QAMResetQAM(state); + if (status < 0) + goto error; + +@@ -5738,24 +5671,15 @@ static int set_qam_standard(struct drxk_state *state, + + /* Upload IQM Channel Filter settings by + boot loader from ROM table */ +- switch (o_mode) { ++ switch (oMode) { + case OM_QAM_ITU_A: +- status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, +- DRXK_BLCC_NR_ELEMENTS_TAPS, +- DRXK_BLC_TIMEOUT); ++ status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + break; + case OM_QAM_ITU_C: +- status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A, +- DRXK_BL_ROM_OFFSET_TAPS_ITU_C, +- DRXK_BLDC_NR_ELEMENTS_TAPS, +- DRXK_BLC_TIMEOUT); ++ status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + if (status < 0) + goto error; +- status = bl_direct_cmd(state, +- IQM_CF_TAP_IM0__A, +- DRXK_BL_ROM_OFFSET_TAPS_ITU_C, +- DRXK_BLDC_NR_ELEMENTS_TAPS, +- DRXK_BLC_TIMEOUT); ++ status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + break; + default: + status = -EINVAL; +@@ -5763,14 +5687,13 @@ static int set_qam_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B); ++ status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B)); + if (status < 0) + goto error; + status = write16(state, IQM_CF_SYMMETRIC__A, 0); + if (status < 0) + goto error; +- status = write16(state, IQM_CF_MIDTAP__A, +- ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); ++ status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); + if (status < 0) + goto error; + +@@ -5827,7 +5750,7 @@ static int set_qam_standard(struct drxk_state *state, + goto error; + + /* turn on IQMAF. Must be done before setAgc**() */ +- status = set_iqm_af(state, true); ++ status = SetIqmAf(state, true); + if (status < 0) + goto error; + status = write16(state, IQM_AF_START_LOCK__A, 0x01); +@@ -5835,7 +5758,7 @@ static int set_qam_standard(struct drxk_state *state, + goto error; + + /* IQM will not be reset from here, sync ADC and update/init AGC */ +- status = adc_synchronization(state); ++ status = ADCSynchronization(state); + if (status < 0) + goto error; + +@@ -5852,18 +5775,18 @@ static int set_qam_standard(struct drxk_state *state, + /* No more resets of the IQM, current standard correctly set => + now AGCs can be configured. */ + +- status = init_agc(state, true); ++ status = InitAGC(state, true); + if (status < 0) + goto error; +- status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg)); ++ status = SetPreSaw(state, &(state->m_qamPreSawCfg)); + if (status < 0) + goto error; + + /* Configure AGC's */ +- status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true); ++ status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true); + if (status < 0) + goto error; +- status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true); ++ status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true); + if (status < 0) + goto error; + +@@ -5871,19 +5794,18 @@ static int set_qam_standard(struct drxk_state *state, + status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int write_gpio(struct drxk_state *state) ++static int WriteGPIO(struct drxk_state *state) + { + int status; + u16 value = 0; + + dprintk(1, "\n"); + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + +@@ -5892,11 +5814,10 @@ static int write_gpio(struct drxk_state *state) + if (status < 0) + goto error; + +- if (state->m_has_sawsw) { +- if (state->uio_mask & 0x0001) { /* UIO-1 */ ++ if (state->m_hasSAWSW) { ++ if (state->UIO_mask & 0x0001) { /* UIO-1 */ + /* write to io pad configuration register - output mode */ +- status = write16(state, SIO_PDR_SMA_TX_CFG__A, +- state->m_gpio_cfg); ++ status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + +@@ -5904,7 +5825,7 @@ static int write_gpio(struct drxk_state *state) + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; +- if ((state->m_gpio & 0x0001) == 0) ++ if ((state->m_GPIO & 0x0001) == 0) + value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ + else + value |= 0x8000; /* write one to 15th bit - 1st UIO */ +@@ -5913,10 +5834,9 @@ static int write_gpio(struct drxk_state *state) + if (status < 0) + goto error; + } +- if (state->uio_mask & 0x0002) { /* UIO-2 */ ++ if (state->UIO_mask & 0x0002) { /* UIO-2 */ + /* write to io pad configuration register - output mode */ +- status = write16(state, SIO_PDR_SMA_RX_CFG__A, +- state->m_gpio_cfg); ++ status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + +@@ -5924,7 +5844,7 @@ static int write_gpio(struct drxk_state *state) + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; +- if ((state->m_gpio & 0x0002) == 0) ++ if ((state->m_GPIO & 0x0002) == 0) + value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */ + else + value |= 0x4000; /* write one to 14th bit - 2st UIO */ +@@ -5933,10 +5853,9 @@ static int write_gpio(struct drxk_state *state) + if (status < 0) + goto error; + } +- if (state->uio_mask & 0x0004) { /* UIO-3 */ ++ if (state->UIO_mask & 0x0004) { /* UIO-3 */ + /* write to io pad configuration register - output mode */ +- status = write16(state, SIO_PDR_GPIO_CFG__A, +- state->m_gpio_cfg); ++ status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + +@@ -5944,7 +5863,7 @@ static int write_gpio(struct drxk_state *state) + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; +- if ((state->m_gpio & 0x0004) == 0) ++ if ((state->m_GPIO & 0x0004) == 0) + value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */ + else + value |= 0x0004; /* write one to 2nd bit - 3rd UIO */ +@@ -5958,11 +5877,11 @@ static int write_gpio(struct drxk_state *state) + status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int switch_antenna_to_qam(struct drxk_state *state) ++static int SwitchAntennaToQAM(struct drxk_state *state) + { + int status = 0; + bool gpio_state; +@@ -5972,22 +5891,22 @@ static int switch_antenna_to_qam(struct drxk_state *state) + if (!state->antenna_gpio) + return 0; + +- gpio_state = state->m_gpio & state->antenna_gpio; ++ gpio_state = state->m_GPIO & state->antenna_gpio; + + if (state->antenna_dvbt ^ gpio_state) { + /* Antenna is on DVB-T mode. Switch */ + if (state->antenna_dvbt) +- state->m_gpio &= ~state->antenna_gpio; ++ state->m_GPIO &= ~state->antenna_gpio; + else +- state->m_gpio |= state->antenna_gpio; +- status = write_gpio(state); ++ state->m_GPIO |= state->antenna_gpio; ++ status = WriteGPIO(state); + } + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int switch_antenna_to_dvbt(struct drxk_state *state) ++static int SwitchAntennaToDVBT(struct drxk_state *state) + { + int status = 0; + bool gpio_state; +@@ -5997,23 +5916,23 @@ static int switch_antenna_to_dvbt(struct drxk_state *state) + if (!state->antenna_gpio) + return 0; + +- gpio_state = state->m_gpio & state->antenna_gpio; ++ gpio_state = state->m_GPIO & state->antenna_gpio; + + if (!(state->antenna_dvbt ^ gpio_state)) { + /* Antenna is on DVB-C mode. Switch */ + if (state->antenna_dvbt) +- state->m_gpio |= state->antenna_gpio; ++ state->m_GPIO |= state->antenna_gpio; + else +- state->m_gpio &= ~state->antenna_gpio; +- status = write_gpio(state); ++ state->m_GPIO &= ~state->antenna_gpio; ++ status = WriteGPIO(state); + } + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + +-static int power_down_device(struct drxk_state *state) ++static int PowerDownDevice(struct drxk_state *state) + { + /* Power down to requested mode */ + /* Backup some register settings */ +@@ -6024,86 +5943,98 @@ static int power_down_device(struct drxk_state *state) + int status; + + dprintk(1, "\n"); +- if (state->m_b_p_down_open_bridge) { ++ if (state->m_bPDownOpenBridge) { + /* Open I2C bridge before power down of DRXK */ + status = ConfigureI2CBridge(state, true); + if (status < 0) + goto error; + } + /* driver 0.9.0 */ +- status = dvbt_enable_ofdm_token_ring(state, false); ++ status = DVBTEnableOFDMTokenRing(state, false); + if (status < 0) + goto error; + +- status = write16(state, SIO_CC_PWD_MODE__A, +- SIO_CC_PWD_MODE_LEVEL_CLOCK); ++ status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK); + if (status < 0) + goto error; + status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); + if (status < 0) + goto error; +- state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; +- status = hi_cfg_command(state); ++ state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; ++ status = HI_CfgCommand(state); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + ++static int load_microcode(struct drxk_state *state, const char *mc_name) ++{ ++ const struct firmware *fw = NULL; ++ int err = 0; ++ ++ dprintk(1, "\n"); ++ ++ err = request_firmware(&fw, mc_name, state->i2c->dev.parent); ++ if (err < 0) { ++ printk(KERN_ERR ++ "drxk: Could not load firmware file %s.\n", mc_name); ++ printk(KERN_INFO ++ "drxk: Copy %s to your hotplug directory!\n", mc_name); ++ return err; ++ } ++ err = DownloadMicrocode(state, fw->data, fw->size); ++ release_firmware(fw); ++ return err; ++} ++ + static int init_drxk(struct drxk_state *state) + { +- int status = 0, n = 0; +- enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; +- u16 driver_version; ++ int status = 0; ++ enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; ++ u16 driverVersion; + + dprintk(1, "\n"); +- if ((state->m_drxk_state == DRXK_UNINITIALIZED)) { +- drxk_i2c_lock(state); +- status = power_up_device(state); ++ if ((state->m_DrxkState == DRXK_UNINITIALIZED)) { ++ status = PowerUpDevice(state); + if (status < 0) + goto error; +- status = drxx_open(state); ++ status = DRXX_Open(state); + if (status < 0) + goto error; + /* Soft reset of OFDM-, sys- and osc-clockdomain */ +- status = write16(state, SIO_CC_SOFT_RST__A, +- SIO_CC_SOFT_RST_OFDM__M +- | SIO_CC_SOFT_RST_SYS__M +- | SIO_CC_SOFT_RST_OSC__M); ++ status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M); + if (status < 0) + goto error; + status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); + if (status < 0) + goto error; +- /* +- * TODO is this needed? If yes, how much delay in +- * worst case scenario +- */ +- usleep_range(1000, 2000); +- state->m_drxk_a3_patch_code = true; +- status = get_device_capabilities(state); ++ /* TODO is this needed, if yes how much delay in worst case scenario */ ++ msleep(1); ++ state->m_DRXK_A3_PATCH_CODE = true; ++ status = GetDeviceCapabilities(state); + if (status < 0) + goto error; + + /* Bridge delay, uses oscilator clock */ + /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */ + /* SDA brdige delay */ +- state->m_hi_cfg_bridge_delay = +- (u16) ((state->m_osc_clock_freq / 1000) * ++ state->m_HICfgBridgeDelay = ++ (u16) ((state->m_oscClockFreq / 1000) * + HI_I2C_BRIDGE_DELAY) / 1000; + /* Clipping */ +- if (state->m_hi_cfg_bridge_delay > ++ if (state->m_HICfgBridgeDelay > + SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) { +- state->m_hi_cfg_bridge_delay = ++ state->m_HICfgBridgeDelay = + SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M; + } + /* SCL bridge delay, same as SDA for now */ +- state->m_hi_cfg_bridge_delay += +- state->m_hi_cfg_bridge_delay << ++ state->m_HICfgBridgeDelay += ++ state->m_HICfgBridgeDelay << + SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B; + +- status = init_hi(state); ++ status = InitHI(state); + if (status < 0) + goto error; + /* disable various processes */ +@@ -6112,14 +6043,13 @@ static int init_drxk(struct drxk_state *state) + && !(state->m_DRXK_A2_ROM_CODE)) + #endif + { +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + } + + /* disable MPEG port */ +- status = mpegts_disable(state); ++ status = MPEGTSDisable(state); + if (status < 0) + goto error; + +@@ -6132,30 +6062,23 @@ static int init_drxk(struct drxk_state *state) + goto error; + + /* enable token-ring bus through OFDM block for possible ucode upload */ +- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, +- SIO_OFDM_SH_OFDM_RING_ENABLE_ON); ++ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON); + if (status < 0) + goto error; + + /* include boot loader section */ +- status = write16(state, SIO_BL_COMM_EXEC__A, +- SIO_BL_COMM_EXEC_ACTIVE); ++ status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE); + if (status < 0) + goto error; +- status = bl_chain_cmd(state, 0, 6, 100); ++ status = BLChainCmd(state, 0, 6, 100); + if (status < 0) + goto error; + +- if (state->fw) { +- status = download_microcode(state, state->fw->data, +- state->fw->size); +- if (status < 0) +- goto error; +- } ++ if (state->microcode_name) ++ load_microcode(state, state->microcode_name); + + /* disable token-ring bus through OFDM block for possible ucode upload */ +- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, +- SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); ++ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); + if (status < 0) + goto error; + +@@ -6163,55 +6086,50 @@ static int init_drxk(struct drxk_state *state) + status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); + if (status < 0) + goto error; +- status = drxx_open(state); ++ status = DRXX_Open(state); + if (status < 0) + goto error; + /* added for test */ + msleep(30); + +- power_mode = DRXK_POWER_DOWN_OFDM; +- status = ctrl_power_mode(state, &power_mode); ++ powerMode = DRXK_POWER_DOWN_OFDM; ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) + goto error; + + /* Stamp driver version number in SCU data RAM in BCD code +- Done to enable field application engineers to retrieve drxdriver version ++ Done to enable field application engineers to retreive drxdriver version + via I2C from SCU RAM. + Not using SCU command interface for SCU register access since no + microcode may be present. + */ +- driver_version = ++ driverVersion = + (((DRXK_VERSION_MAJOR / 100) % 10) << 12) + + (((DRXK_VERSION_MAJOR / 10) % 10) << 8) + + ((DRXK_VERSION_MAJOR % 10) << 4) + + (DRXK_VERSION_MINOR % 10); +- status = write16(state, SCU_RAM_DRIVER_VER_HI__A, +- driver_version); ++ status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion); + if (status < 0) + goto error; +- driver_version = ++ driverVersion = + (((DRXK_VERSION_PATCH / 1000) % 10) << 12) + + (((DRXK_VERSION_PATCH / 100) % 10) << 8) + + (((DRXK_VERSION_PATCH / 10) % 10) << 4) + + (DRXK_VERSION_PATCH % 10); +- status = write16(state, SCU_RAM_DRIVER_VER_LO__A, +- driver_version); ++ status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion); + if (status < 0) + goto error; + +- pr_info("DRXK driver version %d.%d.%d\n", ++ printk(KERN_INFO "DRXK driver version %d.%d.%d\n", + DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR, + DRXK_VERSION_PATCH); + +- /* +- * Dirty fix of default values for ROM/PATCH microcode +- * Dirty because this fix makes it impossible to setup +- * suitable values before calling DRX_Open. This solution +- * requires changes to RF AGC speed to be done via the CTRL +- * function after calling DRX_Open +- */ ++ /* Dirty fix of default values for ROM/PATCH microcode ++ Dirty because this fix makes it impossible to setup suitable values ++ before calling DRX_Open. This solution requires changes to RF AGC speed ++ to be done via the CTRL function after calling DRX_Open */ + +- /* m_dvbt_rf_agc_cfg.speed = 3; */ ++ /* m_dvbtRfAgcCfg.speed = 3; */ + + /* Reset driver debug flags to 0 */ + status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0); +@@ -6224,94 +6142,45 @@ static int init_drxk(struct drxk_state *state) + if (status < 0) + goto error; + /* MPEGTS functions are still the same */ +- status = mpegts_dto_init(state); ++ status = MPEGTSDtoInit(state); + if (status < 0) + goto error; +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = mpegts_configure_polarity(state); ++ status = MPEGTSConfigurePolarity(state); + if (status < 0) + goto error; +- status = mpegts_configure_pins(state, state->m_enable_mpeg_output); ++ status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput); + if (status < 0) + goto error; + /* added: configure GPIO */ +- status = write_gpio(state); ++ status = WriteGPIO(state); + if (status < 0) + goto error; + +- state->m_drxk_state = DRXK_STOPPED; ++ state->m_DrxkState = DRXK_STOPPED; + +- if (state->m_b_power_down) { +- status = power_down_device(state); ++ if (state->m_bPowerDown) { ++ status = PowerDownDevice(state); + if (status < 0) + goto error; +- state->m_drxk_state = DRXK_POWERED_DOWN; ++ state->m_DrxkState = DRXK_POWERED_DOWN; + } else +- state->m_drxk_state = DRXK_STOPPED; +- +- /* Initialize the supported delivery systems */ +- n = 0; +- if (state->m_has_dvbc) { +- state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; +- state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; +- strlcat(state->frontend.ops.info.name, " DVB-C", +- sizeof(state->frontend.ops.info.name)); +- } +- if (state->m_has_dvbt) { +- state->frontend.ops.delsys[n++] = SYS_DVBT; +- strlcat(state->frontend.ops.info.name, " DVB-T", +- sizeof(state->frontend.ops.info.name)); +- } +- drxk_i2c_unlock(state); ++ state->m_DrxkState = DRXK_STOPPED; + } + error: +- if (status < 0) { +- state->m_drxk_state = DRXK_NO_DEV; +- drxk_i2c_unlock(state); +- pr_err("Error %d on %s\n", status, __func__); +- } ++ if (status < 0) ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static void load_firmware_cb(const struct firmware *fw, +- void *context) +-{ +- struct drxk_state *state = context; +- +- dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); +- if (!fw) { +- pr_err("Could not load firmware file %s.\n", +- state->microcode_name); +- pr_info("Copy %s to your hotplug directory!\n", +- state->microcode_name); +- state->microcode_name = NULL; +- +- /* +- * As firmware is now load asynchronous, it is not possible +- * anymore to fail at frontend attach. We might silently +- * return here, and hope that the driver won't crash. +- * We might also change all DVB callbacks to return -ENODEV +- * if the device is not initialized. +- * As the DRX-K devices have their own internal firmware, +- * let's just hope that it will match a firmware revision +- * compatible with this driver and proceed. +- */ +- } +- state->fw = fw; +- +- init_drxk(state); +-} +- + static void drxk_release(struct dvb_frontend *fe) + { + struct drxk_state *state = fe->demodulator_priv; + + dprintk(1, "\n"); +- release_firmware(state->fw); +- + kfree(state); + } + +@@ -6320,13 +6189,7 @@ static int drxk_sleep(struct dvb_frontend *fe) + struct drxk_state *state = fe->demodulator_priv; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return 0; +- +- shut_down(state); ++ ShutDown(state); + return 0; + } + +@@ -6334,11 +6197,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) + { + struct drxk_state *state = fe->demodulator_priv; + +- dprintk(1, ": %s\n", enable ? "enable" : "disable"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- ++ dprintk(1, "%s\n", enable ? "enable" : "disable"); + return ConfigureI2CBridge(state, enable ? true : false); + } + +@@ -6351,14 +6210,9 @@ static int drxk_set_parameters(struct dvb_frontend *fe) + + dprintk(1, "\n"); + +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- + if (!fe->ops.tuner_ops.get_if_frequency) { +- pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); ++ printk(KERN_ERR ++ "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); + return -EINVAL; + } + +@@ -6373,23 +6227,22 @@ static int drxk_set_parameters(struct dvb_frontend *fe) + state->props = *p; + + if (old_delsys != delsys) { +- shut_down(state); ++ ShutDown(state); + switch (delsys) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: +- if (!state->m_has_dvbc) ++ if (!state->m_hasDVBC) + return -EINVAL; +- state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? +- true : false; ++ state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false; + if (state->m_itut_annex_c) +- setoperation_mode(state, OM_QAM_ITU_C); ++ SetOperationMode(state, OM_QAM_ITU_C); + else +- setoperation_mode(state, OM_QAM_ITU_A); ++ SetOperationMode(state, OM_QAM_ITU_A); + break; + case SYS_DVBT: +- if (!state->m_has_dvbt) ++ if (!state->m_hasDVBT) + return -EINVAL; +- setoperation_mode(state, OM_DVBT); ++ SetOperationMode(state, OM_DVBT); + break; + default: + return -EINVAL; +@@ -6397,261 +6250,35 @@ static int drxk_set_parameters(struct dvb_frontend *fe) + } + + fe->ops.tuner_ops.get_if_frequency(fe, &IF); +- start(state, 0, IF); +- +- /* After set_frontend, stats aren't available */ +- p->strength.stat[0].scale = FE_SCALE_RELATIVE; +- p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ Start(state, 0, IF); + + /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */ + + return 0; + } + +-static int get_strength(struct drxk_state *state, u64 *strength) +-{ +- int status; +- struct s_cfg_agc rf_agc, if_agc; +- u32 total_gain = 0; +- u32 atten = 0; +- u32 agc_range = 0; +- u16 scu_lvl = 0; +- u16 scu_coc = 0; +- /* FIXME: those are part of the tuner presets */ +- u16 tuner_rf_gain = 50; /* Default value on az6007 driver */ +- u16 tuner_if_gain = 40; /* Default value on az6007 driver */ +- +- *strength = 0; +- +- if (is_dvbt(state)) { +- rf_agc = state->m_dvbt_rf_agc_cfg; +- if_agc = state->m_dvbt_if_agc_cfg; +- } else if (is_qam(state)) { +- rf_agc = state->m_qam_rf_agc_cfg; +- if_agc = state->m_qam_if_agc_cfg; +- } else { +- rf_agc = state->m_atv_rf_agc_cfg; +- if_agc = state->m_atv_if_agc_cfg; +- } +- +- if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { +- /* SCU output_level */ +- status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl); +- if (status < 0) +- return status; +- +- /* SCU c.o.c. */ +- read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); +- if (status < 0) +- return status; +- +- if (((u32) scu_lvl + (u32) scu_coc) < 0xffff) +- rf_agc.output_level = scu_lvl + scu_coc; +- else +- rf_agc.output_level = 0xffff; +- +- /* Take RF gain into account */ +- total_gain += tuner_rf_gain; +- +- /* clip output value */ +- if (rf_agc.output_level < rf_agc.min_output_level) +- rf_agc.output_level = rf_agc.min_output_level; +- if (rf_agc.output_level > rf_agc.max_output_level) +- rf_agc.output_level = rf_agc.max_output_level; +- +- agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level); +- if (agc_range > 0) { +- atten += 100UL * +- ((u32)(tuner_rf_gain)) * +- ((u32)(rf_agc.output_level - rf_agc.min_output_level)) +- / agc_range; +- } +- } +- +- if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { +- status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A, +- &if_agc.output_level); +- if (status < 0) +- return status; +- +- status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, +- &if_agc.top); +- if (status < 0) +- return status; +- +- /* Take IF gain into account */ +- total_gain += (u32) tuner_if_gain; +- +- /* clip output value */ +- if (if_agc.output_level < if_agc.min_output_level) +- if_agc.output_level = if_agc.min_output_level; +- if (if_agc.output_level > if_agc.max_output_level) +- if_agc.output_level = if_agc.max_output_level; +- +- agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level); +- if (agc_range > 0) { +- atten += 100UL * +- ((u32)(tuner_if_gain)) * +- ((u32)(if_agc.output_level - if_agc.min_output_level)) +- / agc_range; +- } +- } +- +- /* +- * Convert to 0..65535 scale. +- * If it can't be measured (AGC is disabled), just show 100%. +- */ +- if (total_gain > 0) +- *strength = (65535UL * atten / total_gain / 100); +- else +- *strength = 65535; +- +- return 0; +-} +- +-static int drxk_get_stats(struct dvb_frontend *fe) ++static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) + { +- struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct drxk_state *state = fe->demodulator_priv; +- int status; + u32 stat; +- u16 reg16; +- u32 post_bit_count; +- u32 post_bit_err_count; +- u32 post_bit_error_scale; +- u32 pre_bit_err_count; +- u32 pre_bit_count; +- u32 pkt_count; +- u32 pkt_error_count; +- s32 cnr; +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- /* get status */ +- state->fe_status = 0; +- get_lock_status(state, &stat); ++ ++ dprintk(1, "\n"); ++ *status = 0; ++ GetLockStatus(state, &stat, 0); + if (stat == MPEG_LOCK) +- state->fe_status |= 0x1f; ++ *status |= 0x1f; + if (stat == FEC_LOCK) +- state->fe_status |= 0x0f; ++ *status |= 0x0f; + if (stat == DEMOD_LOCK) +- state->fe_status |= 0x07; +- +- /* +- * Estimate signal strength from AGC +- */ +- get_strength(state, &c->strength.stat[0].uvalue); +- c->strength.stat[0].scale = FE_SCALE_RELATIVE; +- +- +- if (stat >= DEMOD_LOCK) { +- get_signal_to_noise(state, &cnr); +- c->cnr.stat[0].svalue = cnr * 100; +- c->cnr.stat[0].scale = FE_SCALE_DECIBEL; +- } else { +- c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- } +- +- if (stat < FEC_LOCK) { +- c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- return 0; +- } +- +- /* Get post BER */ +- +- /* BER measurement is valid if at least FEC lock is achieved */ +- +- /* +- * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be +- * written to set nr of symbols or bits over which to measure +- * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). +- */ +- +- /* Read registers for post/preViterbi BER calculation */ +- status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16); +- if (status < 0) +- goto error; +- pre_bit_err_count = reg16; +- +- status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16); +- if (status < 0) +- goto error; +- pre_bit_count = reg16; +- +- /* Number of bit-errors */ +- status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16); +- if (status < 0) +- goto error; +- post_bit_err_count = reg16; +- +- status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16); +- if (status < 0) +- goto error; +- post_bit_error_scale = reg16; +- +- status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16); +- if (status < 0) +- goto error; +- pkt_count = reg16; +- +- status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16); +- if (status < 0) +- goto error; +- pkt_error_count = reg16; +- write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); +- +- post_bit_err_count *= post_bit_error_scale; +- +- post_bit_count = pkt_count * 204 * 8; +- +- /* Store the results */ +- c->block_error.stat[0].scale = FE_SCALE_COUNTER; +- c->block_error.stat[0].uvalue += pkt_error_count; +- c->block_count.stat[0].scale = FE_SCALE_COUNTER; +- c->block_count.stat[0].uvalue += pkt_count; +- +- c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; +- c->pre_bit_error.stat[0].uvalue += pre_bit_err_count; +- c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; +- c->pre_bit_count.stat[0].uvalue += pre_bit_count; +- +- c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; +- c->post_bit_error.stat[0].uvalue += post_bit_err_count; +- c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; +- c->post_bit_count.stat[0].uvalue += post_bit_count; +- +-error: +- return status; ++ *status |= 0x07; ++ return 0; + } + +- +-static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) ++static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber) + { +- struct drxk_state *state = fe->demodulator_priv; +- int rc; +- + dprintk(1, "\n"); + +- rc = drxk_get_stats(fe); +- if (rc < 0) +- return rc; +- +- *status = state->fe_status; +- ++ *ber = 0; + return 0; + } + +@@ -6659,16 +6286,11 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) + { + struct drxk_state *state = fe->demodulator_priv; +- struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u32 val = 0; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- *strength = c->strength.stat[0].uvalue; ++ ReadIFAgc(state, &val); ++ *strength = val & 0xffff; + return 0; + } + +@@ -6678,17 +6300,7 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr) + s32 snr2; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- get_signal_to_noise(state, &snr2); +- +- /* No negative SNR, clip to zero */ +- if (snr2 < 0) +- snr2 = 0; ++ GetSignalToNoise(state, &snr2); + *snr = snr2 & 0xffff; + return 0; + } +@@ -6699,30 +6311,17 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) + u16 err; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- dvbtqam_get_acc_pkt_err(state, &err); ++ DVBTQAMGetAccPktErr(state, &err); + *ucblocks = (u32) err; + return 0; + } + +-static int drxk_get_tune_settings(struct dvb_frontend *fe, +- struct dvb_frontend_tune_settings *sets) ++static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings ++ *sets) + { +- struct drxk_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- + switch (p->delivery_system) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: +@@ -6764,6 +6363,7 @@ static struct dvb_frontend_ops drxk_ops = { + .get_tune_settings = drxk_get_tune_settings, + + .read_status = drxk_read_status, ++ .read_ber = drxk_read_ber, + .read_signal_strength = drxk_read_signal_strength, + .read_snr = drxk_read_snr, + .read_ucblocks = drxk_read_ucblocks, +@@ -6772,10 +6372,10 @@ static struct dvb_frontend_ops drxk_ops = { + struct dvb_frontend *drxk_attach(const struct drxk_config *config, + struct i2c_adapter *i2c) + { +- struct dtv_frontend_properties *p; ++ int n; ++ + struct drxk_state *state = NULL; + u8 adr = config->adr; +- int status; + + dprintk(1, "\n"); + state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); +@@ -6786,40 +6386,39 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, + state->demod_address = adr; + state->single_master = config->single_master; + state->microcode_name = config->microcode_name; +- state->qam_demod_parameter_count = config->qam_demod_parameter_count; + state->no_i2c_bridge = config->no_i2c_bridge; + state->antenna_gpio = config->antenna_gpio; + state->antenna_dvbt = config->antenna_dvbt; +- state->m_chunk_size = config->chunk_size; ++ state->m_ChunkSize = config->chunk_size; + state->enable_merr_cfg = config->enable_merr_cfg; + + if (config->dynamic_clk) { +- state->m_dvbt_static_clk = false; +- state->m_dvbc_static_clk = false; ++ state->m_DVBTStaticCLK = 0; ++ state->m_DVBCStaticCLK = 0; + } else { +- state->m_dvbt_static_clk = true; +- state->m_dvbc_static_clk = true; ++ state->m_DVBTStaticCLK = 1; ++ state->m_DVBCStaticCLK = 1; + } + + + if (config->mpeg_out_clk_strength) +- state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07; ++ state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07; + else +- state->m_ts_clockk_strength = 0x06; ++ state->m_TSClockkStrength = 0x06; + + if (config->parallel_ts) +- state->m_enable_parallel = true; ++ state->m_enableParallel = true; + else +- state->m_enable_parallel = false; ++ state->m_enableParallel = false; + + /* NOTE: as more UIO bits will be used, add them to the mask */ +- state->uio_mask = config->antenna_gpio; ++ state->UIO_mask = config->antenna_gpio; + + /* Default gpio to DVB-C */ + if (!state->antenna_dvbt && state->antenna_gpio) +- state->m_gpio |= state->antenna_gpio; ++ state->m_GPIO |= state->antenna_gpio; + else +- state->m_gpio &= ~state->antenna_gpio; ++ state->m_GPIO &= ~state->antenna_gpio; + + mutex_init(&state->mutex); + +@@ -6827,45 +6426,28 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, + state->frontend.demodulator_priv = state; + + init_state(state); +- +- /* Load firmware and initialize DRX-K */ +- if (state->microcode_name) { +- const struct firmware *fw = NULL; +- +- status = request_firmware(&fw, state->microcode_name, +- state->i2c->dev.parent); +- if (status < 0) +- fw = NULL; +- load_firmware_cb(fw, state); +- } else if (init_drxk(state) < 0) ++ if (init_drxk(state) < 0) + goto error; + ++ /* Initialize the supported delivery systems */ ++ n = 0; ++ if (state->m_hasDVBC) { ++ state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; ++ state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; ++ strlcat(state->frontend.ops.info.name, " DVB-C", ++ sizeof(state->frontend.ops.info.name)); ++ } ++ if (state->m_hasDVBT) { ++ state->frontend.ops.delsys[n++] = SYS_DVBT; ++ strlcat(state->frontend.ops.info.name, " DVB-T", ++ sizeof(state->frontend.ops.info.name)); ++ } + +- /* Initialize stats */ +- p = &state->frontend.dtv_property_cache; +- p->strength.len = 1; +- p->cnr.len = 1; +- p->block_error.len = 1; +- p->block_count.len = 1; +- p->pre_bit_error.len = 1; +- p->pre_bit_count.len = 1; +- p->post_bit_error.len = 1; +- p->post_bit_count.len = 1; +- +- p->strength.stat[0].scale = FE_SCALE_RELATIVE; +- p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- +- pr_info("frontend initialized.\n"); ++ printk(KERN_INFO "drxk: frontend initialized.\n"); + return &state->frontend; + + error: +- pr_err("not found\n"); ++ printk(KERN_ERR "drxk: not found\n"); + kfree(state); + return NULL; + } +diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h +index bae9c71..4bbf841 100644 +--- a/drivers/media/dvb-frontends/drxk_hard.h ++++ b/drivers/media/dvb-frontends/drxk_hard.h +@@ -46,7 +46,7 @@ + #define IQM_RC_ADJ_SEL_B_QAM 0x1 + #define IQM_RC_ADJ_SEL_B_VSB 0x2 + +-enum operation_mode { ++enum OperationMode { + OM_NONE, + OM_QAM_ITU_A, + OM_QAM_ITU_B, +@@ -54,7 +54,7 @@ enum operation_mode { + OM_DVBT + }; + +-enum drx_power_mode { ++enum DRXPowerMode { + DRX_POWER_UP = 0, + DRX_POWER_MODE_1, + DRX_POWER_MODE_2, +@@ -77,38 +77,25 @@ enum drx_power_mode { + }; + + +-/* Intermediate power mode for DRXK, power down OFDM clock domain */ ++/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */ + #ifndef DRXK_POWER_DOWN_OFDM + #define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1 + #endif + +-/* Intermediate power mode for DRXK, power down core (sysclk) */ ++/** /brief Intermediate power mode for DRXK, power down core (sysclk) */ + #ifndef DRXK_POWER_DOWN_CORE + #define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9 + #endif + +-/* Intermediate power mode for DRXK, power down pll (only osc runs) */ ++/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */ + #ifndef DRXK_POWER_DOWN_PLL + #define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10 + #endif + + +-enum agc_ctrl_mode { +- DRXK_AGC_CTRL_AUTO = 0, +- DRXK_AGC_CTRL_USER, +- DRXK_AGC_CTRL_OFF +-}; +- +-enum e_drxk_state { +- DRXK_UNINITIALIZED = 0, +- DRXK_STOPPED, +- DRXK_DTV_STARTED, +- DRXK_ATV_STARTED, +- DRXK_POWERED_DOWN, +- DRXK_NO_DEV /* If drxk init failed */ +-}; +- +-enum e_drxk_coef_array_index { ++enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF }; ++enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN }; ++enum EDrxkCoefArrayIndex { + DRXK_COEF_IDX_MN = 0, + DRXK_COEF_IDX_FM , + DRXK_COEF_IDX_L , +@@ -118,13 +105,13 @@ enum e_drxk_coef_array_index { + DRXK_COEF_IDX_I , + DRXK_COEF_IDX_MAX + }; +-enum e_drxk_sif_attenuation { ++enum EDrxkSifAttenuation { + DRXK_SIF_ATTENUATION_0DB, + DRXK_SIF_ATTENUATION_3DB, + DRXK_SIF_ATTENUATION_6DB, + DRXK_SIF_ATTENUATION_9DB + }; +-enum e_drxk_constellation { ++enum EDrxkConstellation { + DRX_CONSTELLATION_BPSK = 0, + DRX_CONSTELLATION_QPSK, + DRX_CONSTELLATION_PSK8, +@@ -138,7 +125,7 @@ enum e_drxk_constellation { + DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN, + DRX_CONSTELLATION_AUTO = DRX_AUTO + }; +-enum e_drxk_interleave_mode { ++enum EDrxkInterleaveMode { + DRXK_QAM_I12_J17 = 16, + DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN + }; +@@ -149,14 +136,14 @@ enum { + DRXK_SPIN_UNKNOWN + }; + +-enum drxk_cfg_dvbt_sqi_speed { ++enum DRXKCfgDvbtSqiSpeed { + DRXK_DVBT_SQI_SPEED_FAST = 0, + DRXK_DVBT_SQI_SPEED_MEDIUM, + DRXK_DVBT_SQI_SPEED_SLOW, + DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN + } ; + +-enum drx_fftmode_t { ++enum DRXFftmode_t { + DRX_FFTMODE_2K = 0, + DRX_FFTMODE_4K, + DRX_FFTMODE_8K, +@@ -164,47 +151,47 @@ enum drx_fftmode_t { + DRX_FFTMODE_AUTO = DRX_AUTO + }; + +-enum drxmpeg_str_width_t { ++enum DRXMPEGStrWidth_t { + DRX_MPEG_STR_WIDTH_1, + DRX_MPEG_STR_WIDTH_8 + }; + +-enum drx_qam_lock_range_t { ++enum DRXQamLockRange_t { + DRX_QAM_LOCKRANGE_NORMAL, + DRX_QAM_LOCKRANGE_EXTENDED + }; + +-struct drxk_cfg_dvbt_echo_thres_t { ++struct DRXKCfgDvbtEchoThres_t { + u16 threshold; +- enum drx_fftmode_t fft_mode; ++ enum DRXFftmode_t fftMode; + } ; + +-struct s_cfg_agc { +- enum agc_ctrl_mode ctrl_mode; /* off, user, auto */ +- u16 output_level; /* range dependent on AGC */ +- u16 min_output_level; /* range dependent on AGC */ +- u16 max_output_level; /* range dependent on AGC */ ++struct SCfgAgc { ++ enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */ ++ u16 outputLevel; /* range dependent on AGC */ ++ u16 minOutputLevel; /* range dependent on AGC */ ++ u16 maxOutputLevel; /* range dependent on AGC */ + u16 speed; /* range dependent on AGC */ + u16 top; /* rf-agc take over point */ +- u16 cut_off_current; /* rf-agc is accelerated if output current ++ u16 cutOffCurrent; /* rf-agc is accelerated if output current + is below cut-off current */ +- u16 ingain_tgt_max; +- u16 fast_clip_ctrl_delay; ++ u16 IngainTgtMax; ++ u16 FastClipCtrlDelay; + }; + +-struct s_cfg_pre_saw { ++struct SCfgPreSaw { + u16 reference; /* pre SAW reference value, range 0 .. 31 */ +- bool use_pre_saw; /* TRUE algorithms must use pre SAW sense */ ++ bool usePreSaw; /* TRUE algorithms must use pre SAW sense */ + }; + +-struct drxk_ofdm_sc_cmd_t { +- u16 cmd; /* Command number */ +- u16 subcmd; /* Sub-command parameter*/ +- u16 param0; /* General purpous param */ +- u16 param1; /* General purpous param */ +- u16 param2; /* General purpous param */ +- u16 param3; /* General purpous param */ +- u16 param4; /* General purpous param */ ++struct DRXKOfdmScCmd_t { ++ u16 cmd; /**< Command number */ ++ u16 subcmd; /**< Sub-command parameter*/ ++ u16 param0; /**< General purpous param */ ++ u16 param1; /**< General purpous param */ ++ u16 param2; /**< General purpous param */ ++ u16 param3; /**< General purpous param */ ++ u16 param4; /**< General purpous param */ + }; + + struct drxk_state { +@@ -218,131 +205,132 @@ struct drxk_state { + + struct mutex mutex; + +- u32 m_instance; /* Channel 1,2,3 or 4 */ +- +- int m_chunk_size; +- u8 chunk[256]; +- +- bool m_has_lna; +- bool m_has_dvbt; +- bool m_has_dvbc; +- bool m_has_audio; +- bool m_has_atv; +- bool m_has_oob; +- bool m_has_sawsw; /* TRUE if mat_tx is available */ +- bool m_has_gpio1; /* TRUE if mat_rx is available */ +- bool m_has_gpio2; /* TRUE if GPIO is available */ +- bool m_has_irqn; /* TRUE if IRQN is available */ +- u16 m_osc_clock_freq; +- u16 m_hi_cfg_timing_div; +- u16 m_hi_cfg_bridge_delay; +- u16 m_hi_cfg_wake_up_key; +- u16 m_hi_cfg_timeout; +- u16 m_hi_cfg_ctrl; +- s32 m_sys_clock_freq; /* system clock frequency in kHz */ +- +- enum e_drxk_state m_drxk_state; /* State of Drxk (init,stopped,started) */ +- enum operation_mode m_operation_mode; /* digital standards */ +- struct s_cfg_agc m_vsb_rf_agc_cfg; /* settings for VSB RF-AGC */ +- struct s_cfg_agc m_vsb_if_agc_cfg; /* settings for VSB IF-AGC */ +- u16 m_vsb_pga_cfg; /* settings for VSB PGA */ +- struct s_cfg_pre_saw m_vsb_pre_saw_cfg; /* settings for pre SAW sense */ +- s32 m_Quality83percent; /* MER level (*0.1 dB) for 83% quality indication */ +- s32 m_Quality93percent; /* MER level (*0.1 dB) for 93% quality indication */ +- bool m_smart_ant_inverted; +- bool m_b_debug_enable_bridge; +- bool m_b_p_down_open_bridge; /* only open DRXK bridge before power-down once it has been accessed */ +- bool m_b_power_down; /* Power down when not used */ +- +- u32 m_iqm_fs_rate_ofs; /* frequency shift as written to DRXK register (28bit fixpoint) */ +- +- bool m_enable_mpeg_output; /* If TRUE, enable MPEG output */ +- bool m_insert_rs_byte; /* If TRUE, insert RS byte */ +- bool m_enable_parallel; /* If TRUE, parallel out otherwise serial */ +- bool m_invert_data; /* If TRUE, invert DATA signals */ +- bool m_invert_err; /* If TRUE, invert ERR signal */ +- bool m_invert_str; /* If TRUE, invert STR signals */ +- bool m_invert_val; /* If TRUE, invert VAL signals */ +- bool m_invert_clk; /* If TRUE, invert CLK signals */ +- bool m_dvbc_static_clk; +- bool m_dvbt_static_clk; /* If TRUE, static MPEG clockrate will ++ u32 m_Instance; /**< Channel 1,2,3 or 4 */ ++ ++ int m_ChunkSize; ++ u8 Chunk[256]; ++ ++ bool m_hasLNA; ++ bool m_hasDVBT; ++ bool m_hasDVBC; ++ bool m_hasAudio; ++ bool m_hasATV; ++ bool m_hasOOB; ++ bool m_hasSAWSW; /**< TRUE if mat_tx is available */ ++ bool m_hasGPIO1; /**< TRUE if mat_rx is available */ ++ bool m_hasGPIO2; /**< TRUE if GPIO is available */ ++ bool m_hasIRQN; /**< TRUE if IRQN is available */ ++ u16 m_oscClockFreq; ++ u16 m_HICfgTimingDiv; ++ u16 m_HICfgBridgeDelay; ++ u16 m_HICfgWakeUpKey; ++ u16 m_HICfgTimeout; ++ u16 m_HICfgCtrl; ++ s32 m_sysClockFreq; /**< system clock frequency in kHz */ ++ ++ enum EDrxkState m_DrxkState; /**< State of Drxk (init,stopped,started) */ ++ enum OperationMode m_OperationMode; /**< digital standards */ ++ struct SCfgAgc m_vsbRfAgcCfg; /**< settings for VSB RF-AGC */ ++ struct SCfgAgc m_vsbIfAgcCfg; /**< settings for VSB IF-AGC */ ++ u16 m_vsbPgaCfg; /**< settings for VSB PGA */ ++ struct SCfgPreSaw m_vsbPreSawCfg; /**< settings for pre SAW sense */ ++ s32 m_Quality83percent; /**< MER level (*0.1 dB) for 83% quality indication */ ++ s32 m_Quality93percent; /**< MER level (*0.1 dB) for 93% quality indication */ ++ bool m_smartAntInverted; ++ bool m_bDebugEnableBridge; ++ bool m_bPDownOpenBridge; /**< only open DRXK bridge before power-down once it has been accessed */ ++ bool m_bPowerDown; /**< Power down when not used */ ++ ++ u32 m_IqmFsRateOfs; /**< frequency shift as written to DRXK register (28bit fixpoint) */ ++ ++ bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */ ++ bool m_insertRSByte; /**< If TRUE, insert RS byte */ ++ bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */ ++ bool m_invertDATA; /**< If TRUE, invert DATA signals */ ++ bool m_invertERR; /**< If TRUE, invert ERR signal */ ++ bool m_invertSTR; /**< If TRUE, invert STR signals */ ++ bool m_invertVAL; /**< If TRUE, invert VAL signals */ ++ bool m_invertCLK; /**< If TRUE, invert CLK signals */ ++ bool m_DVBCStaticCLK; ++ bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will + be used, otherwise clockrate will + adapt to the bitrate of the TS */ +- u32 m_dvbt_bitrate; +- u32 m_dvbc_bitrate; ++ u32 m_DVBTBitrate; ++ u32 m_DVBCBitrate; + +- u8 m_ts_data_strength; +- u8 m_ts_clockk_strength; ++ u8 m_TSDataStrength; ++ u8 m_TSClockkStrength; + + bool m_itut_annex_c; /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */ + +- enum drxmpeg_str_width_t m_width_str; /* MPEG start width */ +- u32 m_mpeg_ts_static_bitrate; /* Maximum bitrate in b/s in case ++ enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */ ++ u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case + static clockrate is selected */ + +- /* LARGE_INTEGER m_startTime; */ /* Contains the time of the last demod start */ +- s32 m_mpeg_lock_time_out; /* WaitForLockStatus Timeout (counts from start time) */ +- s32 m_demod_lock_time_out; /* WaitForLockStatus Timeout (counts from start time) */ +- +- bool m_disable_te_ihandling; +- +- bool m_rf_agc_pol; +- bool m_if_agc_pol; +- +- struct s_cfg_agc m_atv_rf_agc_cfg; /* settings for ATV RF-AGC */ +- struct s_cfg_agc m_atv_if_agc_cfg; /* settings for ATV IF-AGC */ +- struct s_cfg_pre_saw m_atv_pre_saw_cfg; /* settings for ATV pre SAW sense */ +- bool m_phase_correction_bypass; +- s16 m_atv_top_vid_peak; +- u16 m_atv_top_noise_th; +- enum e_drxk_sif_attenuation m_sif_attenuation; +- bool m_enable_cvbs_output; +- bool m_enable_sif_output; +- bool m_b_mirror_freq_spect; +- enum e_drxk_constellation m_constellation; /* constellation type of the channel */ +- u32 m_curr_symbol_rate; /* Current QAM symbol rate */ +- struct s_cfg_agc m_qam_rf_agc_cfg; /* settings for QAM RF-AGC */ +- struct s_cfg_agc m_qam_if_agc_cfg; /* settings for QAM IF-AGC */ +- u16 m_qam_pga_cfg; /* settings for QAM PGA */ +- struct s_cfg_pre_saw m_qam_pre_saw_cfg; /* settings for QAM pre SAW sense */ +- enum e_drxk_interleave_mode m_qam_interleave_mode; /* QAM Interleave mode */ +- u16 m_fec_rs_plen; +- u16 m_fec_rs_prescale; +- +- enum drxk_cfg_dvbt_sqi_speed m_sqi_speed; +- +- u16 m_gpio; +- u16 m_gpio_cfg; +- +- struct s_cfg_agc m_dvbt_rf_agc_cfg; /* settings for QAM RF-AGC */ +- struct s_cfg_agc m_dvbt_if_agc_cfg; /* settings for QAM IF-AGC */ +- struct s_cfg_pre_saw m_dvbt_pre_saw_cfg; /* settings for QAM pre SAW sense */ +- +- u16 m_agcfast_clip_ctrl_delay; +- bool m_adc_comp_passed; ++ /* LARGE_INTEGER m_StartTime; */ /**< Contains the time of the last demod start */ ++ s32 m_MpegLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */ ++ s32 m_DemodLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */ ++ ++ bool m_disableTEIhandling; ++ ++ bool m_RfAgcPol; ++ bool m_IfAgcPol; ++ ++ struct SCfgAgc m_atvRfAgcCfg; /**< settings for ATV RF-AGC */ ++ struct SCfgAgc m_atvIfAgcCfg; /**< settings for ATV IF-AGC */ ++ struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */ ++ bool m_phaseCorrectionBypass; ++ s16 m_atvTopVidPeak; ++ u16 m_atvTopNoiseTh; ++ enum EDrxkSifAttenuation m_sifAttenuation; ++ bool m_enableCVBSOutput; ++ bool m_enableSIFOutput; ++ bool m_bMirrorFreqSpect; ++ enum EDrxkConstellation m_Constellation; /**< Constellation type of the channel */ ++ u32 m_CurrSymbolRate; /**< Current QAM symbol rate */ ++ struct SCfgAgc m_qamRfAgcCfg; /**< settings for QAM RF-AGC */ ++ struct SCfgAgc m_qamIfAgcCfg; /**< settings for QAM IF-AGC */ ++ u16 m_qamPgaCfg; /**< settings for QAM PGA */ ++ struct SCfgPreSaw m_qamPreSawCfg; /**< settings for QAM pre SAW sense */ ++ enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */ ++ u16 m_fecRsPlen; ++ u16 m_fecRsPrescale; ++ ++ enum DRXKCfgDvbtSqiSpeed m_sqiSpeed; ++ ++ u16 m_GPIO; ++ u16 m_GPIOCfg; ++ ++ struct SCfgAgc m_dvbtRfAgcCfg; /**< settings for QAM RF-AGC */ ++ struct SCfgAgc m_dvbtIfAgcCfg; /**< settings for QAM IF-AGC */ ++ struct SCfgPreSaw m_dvbtPreSawCfg; /**< settings for QAM pre SAW sense */ ++ ++ u16 m_agcFastClipCtrlDelay; ++ bool m_adcCompPassed; + u16 m_adcCompCoef[64]; +- u16 m_adc_state; ++ u16 m_adcState; + + u8 *m_microcode; + int m_microcode_length; +- bool m_drxk_a3_rom_code; +- bool m_drxk_a3_patch_code; ++ bool m_DRXK_A1_PATCH_CODE; ++ bool m_DRXK_A1_ROM_CODE; ++ bool m_DRXK_A2_ROM_CODE; ++ bool m_DRXK_A3_ROM_CODE; ++ bool m_DRXK_A2_PATCH_CODE; ++ bool m_DRXK_A3_PATCH_CODE; + + bool m_rfmirror; +- u8 m_device_spin; +- u32 m_iqm_rc_rate; +- +- enum drx_power_mode m_current_power_mode; ++ u8 m_deviceSpin; ++ u32 m_iqmRcRate; + +- /* when true, avoids other devices to use the I2C bus */ +- bool drxk_i2c_exclusive_lock; ++ enum DRXPowerMode m_currentPowerMode; + + /* + * Configurable parameters at the driver. They stores the values found + * at struct drxk_config. + */ + +- u16 uio_mask; /* Bits used by UIO */ ++ u16 UIO_mask; /* Bits used by UIO */ + + bool enable_merr_cfg; + bool single_master; +@@ -350,13 +338,7 @@ struct drxk_state { + bool antenna_dvbt; + u16 antenna_gpio; + +- fe_status_t fe_status; +- +- /* Firmware */ + const char *microcode_name; +- struct completion fw_wait_load; +- const struct firmware *fw; +- int qam_demod_parameter_count; + }; + + #define NEVER_LOCK 0 +diff --git a/drivers/media/dvb-frontends/drxk_map.h b/drivers/media/dvb-frontends/drxk_map.h +index 761613f..23e16c1 100644 +--- a/drivers/media/dvb-frontends/drxk_map.h ++++ b/drivers/media/dvb-frontends/drxk_map.h +@@ -10,7 +10,6 @@ + #define FEC_RS_COMM_EXEC_STOP 0x0 + #define FEC_RS_MEASUREMENT_PERIOD__A 0x1C30012 + #define FEC_RS_MEASUREMENT_PRESCALE__A 0x1C30013 +-#define FEC_RS_NR_BIT_ERRORS__A 0x1C30014 + #define FEC_OC_MODE__A 0x1C40011 + #define FEC_OC_MODE_PARITY__M 0x1 + #define FEC_OC_DTO_MODE__A 0x1C40014 +@@ -130,8 +129,6 @@ + #define OFDM_EC_SB_PRIOR__A 0x3410013 + #define OFDM_EC_SB_PRIOR_HI 0x0 + #define OFDM_EC_SB_PRIOR_LO 0x1 +-#define OFDM_EC_VD_ERR_BIT_CNT__A 0x3420017 +-#define OFDM_EC_VD_IN_BIT_CNT__A 0x3420018 + #define OFDM_EQ_TOP_TD_TPS_CONST__A 0x3010054 + #define OFDM_EQ_TOP_TD_TPS_CONST__M 0x3 + #define OFDM_EQ_TOP_TD_TPS_CONST_64QAM 0x2 +diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c +new file mode 100644 +index 0000000..f167e67 +--- /dev/null ++++ b/drivers/media/dvb-frontends/lnbh25.c +@@ -0,0 +1,153 @@ ++/* ++ * Driver for the ST LNBH25 ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "lnbh25.h" ++ ++struct lnbh25 { ++ struct i2c_adapter *i2c; ++ u8 adr; ++ u8 reg[4]; ++ u8 boost; ++}; ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("lnbh25: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int lnbh25_write_regs(struct lnbh25 *lnbh, int reg, int len) ++{ ++ u8 d[5]; ++ ++ memcpy(&d[1], &lnbh->reg[reg], len); ++ d[0] = reg + 2; ++ return i2c_write(lnbh->i2c, lnbh->adr, d, len + 1); ++} ++ ++static int lnbh25_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_OFF: ++ lnbh->reg[0] = 0x00; ++ lnbh->reg[1] &= ~0x01; /* Disable Tone */ ++ lnbh->reg[2] = 0x00; ++ return lnbh25_write_regs(lnbh, 0, 3); ++ case SEC_VOLTAGE_13: ++ lnbh->reg[0] = lnbh->boost + 1; ++ break; ++ case SEC_VOLTAGE_18: ++ lnbh->reg[0] = lnbh->boost + 8; ++ break; ++ default: ++ return -EINVAL; ++ }; ++ ++ if (lnbh->reg[0] == 0x00) { ++ lnbh->reg[2] = 4; ++ lnbh25_write_regs(lnbh, 2, 2); ++ } else if (lnbh->reg[2] != 0x00) { ++ lnbh->reg[2] = 0; ++ lnbh25_write_regs(lnbh, 2, 2); ++ } ++ lnbh->reg[1] |= 0x01; ++ return lnbh25_write_regs(lnbh, 0, 3); ++} ++ ++static int lnbh25_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) ++{ ++ struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; ++ ++ lnbh->boost = arg ? 3 : 0; ++ ++ return 0; ++} ++ ++static int lnbh25_set_tone(struct dvb_frontend *fe, ++ fe_sec_tone_mode_t tone) ++{ ++ /* struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; */ ++ ++ return 0; ++} ++ ++static int lnbh25_init(struct lnbh25 *lnbh) ++{ ++ return lnbh25_write_regs(lnbh, 0, 2); ++} ++ ++static void lnbh25_release(struct dvb_frontend *fe) ++{ ++ kfree(fe->sec_priv); ++ fe->sec_priv = NULL; ++} ++ ++struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, ++ u8 adr) ++{ ++ struct lnbh25 *lnbh = kzalloc(sizeof(struct lnbh25), GFP_KERNEL); ++ if (!lnbh) ++ return NULL; ++ ++ lnbh->i2c = i2c; ++ lnbh->adr = adr; ++ lnbh->boost = 3; ++ ++ if (lnbh25_init(lnbh)) { ++ kfree(lnbh); ++ return NULL; ++ } ++ fe->sec_priv = lnbh; ++ fe->ops.set_voltage = lnbh25_set_voltage; ++ fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage; ++ fe->ops.release_sec = lnbh25_release; ++ ++ pr_info("LNB25 on %02x\n", lnbh->adr); ++ ++ return fe; ++} ++EXPORT_SYMBOL(lnbh25_attach); ++ ++MODULE_DESCRIPTION("LNBH25"); ++MODULE_AUTHOR("Ralph Metzler"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb-frontends/lnbh25.h b/drivers/media/dvb-frontends/lnbh25.h +new file mode 100644 +index 0000000..4e8b3cc +--- /dev/null ++++ b/drivers/media/dvb-frontends/lnbh25.h +@@ -0,0 +1,28 @@ ++/* ++ * lnbh25.h ++ */ ++ ++#ifndef _LNBH25_H ++#define _LNBH25_H ++ ++#include ++ ++#if defined(CONFIG_DVB_LNBH25) || \ ++ (defined(CONFIG_DVB_LNBH25_MODULE) && defined(MODULE)) ++ ++extern struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, ++ u8 i2c_addr); ++#else ++ ++static inline struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, ++ u8 i2c_addr) ++{ ++ pr_warn("%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++ ++#endif ++ ++#endif +diff --git a/drivers/media/dvb-frontends/stv0367dd.c b/drivers/media/dvb-frontends/stv0367dd.c +new file mode 100644 +index 0000000..64f7970 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0367dd.c +@@ -0,0 +1,2331 @@ ++/* ++ * stv0367dd: STV0367 DVB-C/T demodulator driver ++ * ++ * Copyright (C) 2011 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "stv0367dd.h" ++#include "stv0367dd_regs.h" ++ ++enum omode { OM_NONE, OM_DVBT, OM_DVBC, OM_QAM_ITU_C }; ++enum { QAM_MOD_QAM4 = 0, ++ QAM_MOD_QAM16, ++ QAM_MOD_QAM32, ++ QAM_MOD_QAM64, ++ QAM_MOD_QAM128, ++ QAM_MOD_QAM256, ++ QAM_MOD_QAM512, ++ QAM_MOD_QAM1024 ++}; ++ ++enum {QAM_SPECT_NORMAL, QAM_SPECT_INVERTED }; ++ ++enum { ++ QAM_FEC_A = 1, /* J83 Annex A */ ++ QAM_FEC_B = (1<<1), /* J83 Annex B */ ++ QAM_FEC_C = (1<<2) /* J83 Annex C */ ++}; ++ ++enum EDemodState { Off, QAMSet, OFDMSet, QAMStarted, OFDMStarted }; ++ ++struct stv_state { ++#ifdef USE_API3 ++ struct dvb_frontend c_frontend; ++ struct dvb_frontend t_frontend; ++#else ++ struct dvb_frontend frontend; ++#endif ++ fe_modulation_t modulation; ++ u32 symbol_rate; ++ u32 bandwidth; ++ struct device *dev; ++ ++ struct i2c_adapter *i2c; ++ u8 adr; ++ void *priv; ++ ++ struct mutex mutex; ++ struct mutex ctlock; ++ ++ u32 master_clock; ++ u32 adc_clock; ++ u8 ID; ++ u8 I2CRPT; ++ u32 omode; ++ u8 qam_inversion; ++ ++ s32 IF; ++ ++ s32 m_FECTimeOut; ++ s32 m_DemodTimeOut; ++ s32 m_SignalTimeOut; ++ s32 m_DemodLockTime; ++ s32 m_FFTTimeOut; ++ s32 m_TSTimeOut; ++ ++ bool m_bFirstTimeLock; ++ ++ u8 m_Save_QAM_AGC_CTL; ++ ++ enum EDemodState demod_state; ++ ++ u8 m_OFDM_FFTMode; // 0 = 2k, 1 = 8k, 2 = 4k ++ u8 m_OFDM_Modulation; // ++ u8 m_OFDM_FEC; // ++ u8 m_OFDM_Guard; ++ ++ u32 ucblocks; ++ u32 ber; ++}; ++ ++struct init_table { ++ u16 adr; ++ u8 data; ++}; ++ ++struct init_table base_init[] = { ++ { R367_IOCFG0, 0x80 }, ++ { R367_DAC0R, 0x00 }, ++ { R367_IOCFG1, 0x00 }, ++ { R367_DAC1R, 0x00 }, ++ { R367_IOCFG2, 0x00 }, ++ { R367_SDFR, 0x00 }, ++ { R367_AUX_CLK, 0x00 }, ++ { R367_FREESYS1, 0x00 }, ++ { R367_FREESYS2, 0x00 }, ++ { R367_FREESYS3, 0x00 }, ++ { R367_GPIO_CFG, 0x55 }, ++ { R367_GPIO_CMD, 0x01 }, ++ { R367_TSTRES, 0x00 }, ++ { R367_ANACTRL, 0x00 }, ++ { R367_TSTBUS, 0x00 }, ++ { R367_RF_AGC2, 0x20 }, ++ { R367_ANADIGCTRL, 0x0b }, ++ { R367_PLLMDIV, 0x01 }, ++ { R367_PLLNDIV, 0x08 }, ++ { R367_PLLSETUP, 0x18 }, ++ { R367_DUAL_AD12, 0x04 }, ++ { R367_TSTBIST, 0x00 }, ++ { 0x0000, 0x00 } ++}; ++ ++struct init_table qam_init[] = { ++ { R367_QAM_CTRL_1, 0x06 },// Orginal 0x04 ++ { R367_QAM_CTRL_2, 0x03 }, ++ { R367_QAM_IT_STATUS1, 0x2b }, ++ { R367_QAM_IT_STATUS2, 0x08 }, ++ { R367_QAM_IT_EN1, 0x00 }, ++ { R367_QAM_IT_EN2, 0x00 }, ++ { R367_QAM_CTRL_STATUS, 0x04 }, ++ { R367_QAM_TEST_CTL, 0x00 }, ++ { R367_QAM_AGC_CTL, 0x73 }, ++ { R367_QAM_AGC_IF_CFG, 0x50 }, ++ { R367_QAM_AGC_RF_CFG, 0x02 },// RF Freeze ++ { R367_QAM_AGC_PWM_CFG, 0x03 }, ++ { R367_QAM_AGC_PWR_REF_L, 0x5a }, ++ { R367_QAM_AGC_PWR_REF_H, 0x00 }, ++ { R367_QAM_AGC_RF_TH_L, 0xff }, ++ { R367_QAM_AGC_RF_TH_H, 0x07 }, ++ { R367_QAM_AGC_IF_LTH_L, 0x00 }, ++ { R367_QAM_AGC_IF_LTH_H, 0x08 }, ++ { R367_QAM_AGC_IF_HTH_L, 0xff }, ++ { R367_QAM_AGC_IF_HTH_H, 0x07 }, ++ { R367_QAM_AGC_PWR_RD_L, 0xa0 }, ++ { R367_QAM_AGC_PWR_RD_M, 0xe9 }, ++ { R367_QAM_AGC_PWR_RD_H, 0x03 }, ++ { R367_QAM_AGC_PWM_IFCMD_L, 0xe4 }, ++ { R367_QAM_AGC_PWM_IFCMD_H, 0x00 }, ++ { R367_QAM_AGC_PWM_RFCMD_L, 0xff }, ++ { R367_QAM_AGC_PWM_RFCMD_H, 0x07 }, ++ { R367_QAM_IQDEM_CFG, 0x01 }, ++ { R367_QAM_MIX_NCO_LL, 0x22 }, ++ { R367_QAM_MIX_NCO_HL, 0x96 }, ++ { R367_QAM_MIX_NCO_HH, 0x55 }, ++ { R367_QAM_SRC_NCO_LL, 0xff }, ++ { R367_QAM_SRC_NCO_LH, 0x0c }, ++ { R367_QAM_SRC_NCO_HL, 0xf5 }, ++ { R367_QAM_SRC_NCO_HH, 0x20 }, ++ { R367_QAM_IQDEM_GAIN_SRC_L, 0x06 }, ++ { R367_QAM_IQDEM_GAIN_SRC_H, 0x01 }, ++ { R367_QAM_IQDEM_DCRM_CFG_LL, 0xfe }, ++ { R367_QAM_IQDEM_DCRM_CFG_LH, 0xff }, ++ { R367_QAM_IQDEM_DCRM_CFG_HL, 0x0f }, ++ { R367_QAM_IQDEM_DCRM_CFG_HH, 0x00 }, ++ { R367_QAM_IQDEM_ADJ_COEFF0, 0x34 }, ++ { R367_QAM_IQDEM_ADJ_COEFF1, 0xae }, ++ { R367_QAM_IQDEM_ADJ_COEFF2, 0x46 }, ++ { R367_QAM_IQDEM_ADJ_COEFF3, 0x77 }, ++ { R367_QAM_IQDEM_ADJ_COEFF4, 0x96 }, ++ { R367_QAM_IQDEM_ADJ_COEFF5, 0x69 }, ++ { R367_QAM_IQDEM_ADJ_COEFF6, 0xc7 }, ++ { R367_QAM_IQDEM_ADJ_COEFF7, 0x01 }, ++ { R367_QAM_IQDEM_ADJ_EN, 0x04 }, ++ { R367_QAM_IQDEM_ADJ_AGC_REF, 0x94 }, ++ { R367_QAM_ALLPASSFILT1, 0xc9 }, ++ { R367_QAM_ALLPASSFILT2, 0x2d }, ++ { R367_QAM_ALLPASSFILT3, 0xa3 }, ++ { R367_QAM_ALLPASSFILT4, 0xfb }, ++ { R367_QAM_ALLPASSFILT5, 0xf6 }, ++ { R367_QAM_ALLPASSFILT6, 0x45 }, ++ { R367_QAM_ALLPASSFILT7, 0x6f }, ++ { R367_QAM_ALLPASSFILT8, 0x7e }, ++ { R367_QAM_ALLPASSFILT9, 0x05 }, ++ { R367_QAM_ALLPASSFILT10, 0x0a }, ++ { R367_QAM_ALLPASSFILT11, 0x51 }, ++ { R367_QAM_TRL_AGC_CFG, 0x20 }, ++ { R367_QAM_TRL_LPF_CFG, 0x28 }, ++ { R367_QAM_TRL_LPF_ACQ_GAIN, 0x44 }, ++ { R367_QAM_TRL_LPF_TRK_GAIN, 0x22 }, ++ { R367_QAM_TRL_LPF_OUT_GAIN, 0x03 }, ++ { R367_QAM_TRL_LOCKDET_LTH, 0x04 }, ++ { R367_QAM_TRL_LOCKDET_HTH, 0x11 }, ++ { R367_QAM_TRL_LOCKDET_TRGVAL, 0x20 }, ++ { R367_QAM_IQ_QAM, 0x01 }, ++ { R367_QAM_FSM_STATE, 0xa0 }, ++ { R367_QAM_FSM_CTL, 0x08 }, ++ { R367_QAM_FSM_STS, 0x0c }, ++ { R367_QAM_FSM_SNR0_HTH, 0x00 }, ++ { R367_QAM_FSM_SNR1_HTH, 0x00 }, ++ { R367_QAM_FSM_SNR2_HTH, 0x00 }, ++ { R367_QAM_FSM_SNR0_LTH, 0x00 }, ++ { R367_QAM_FSM_SNR1_LTH, 0x00 }, ++ { R367_QAM_FSM_EQA1_HTH, 0x00 }, ++ { R367_QAM_FSM_TEMPO, 0x32 }, ++ { R367_QAM_FSM_CONFIG, 0x03 }, ++ { R367_QAM_EQU_I_TESTTAP_L, 0x11 }, ++ { R367_QAM_EQU_I_TESTTAP_M, 0x00 }, ++ { R367_QAM_EQU_I_TESTTAP_H, 0x00 }, ++ { R367_QAM_EQU_TESTAP_CFG, 0x00 }, ++ { R367_QAM_EQU_Q_TESTTAP_L, 0xff }, ++ { R367_QAM_EQU_Q_TESTTAP_M, 0x00 }, ++ { R367_QAM_EQU_Q_TESTTAP_H, 0x00 }, ++ { R367_QAM_EQU_TAP_CTRL, 0x00 }, ++ { R367_QAM_EQU_CTR_CRL_CONTROL_L, 0x11 }, ++ { R367_QAM_EQU_CTR_CRL_CONTROL_H, 0x05 }, ++ { R367_QAM_EQU_CTR_HIPOW_L, 0x00 }, ++ { R367_QAM_EQU_CTR_HIPOW_H, 0x00 }, ++ { R367_QAM_EQU_I_EQU_LO, 0xef }, ++ { R367_QAM_EQU_I_EQU_HI, 0x00 }, ++ { R367_QAM_EQU_Q_EQU_LO, 0xee }, ++ { R367_QAM_EQU_Q_EQU_HI, 0x00 }, ++ { R367_QAM_EQU_MAPPER, 0xc5 }, ++ { R367_QAM_EQU_SWEEP_RATE, 0x80 }, ++ { R367_QAM_EQU_SNR_LO, 0x64 }, ++ { R367_QAM_EQU_SNR_HI, 0x03 }, ++ { R367_QAM_EQU_GAMMA_LO, 0x00 }, ++ { R367_QAM_EQU_GAMMA_HI, 0x00 }, ++ { R367_QAM_EQU_ERR_GAIN, 0x36 }, ++ { R367_QAM_EQU_RADIUS, 0xaa }, ++ { R367_QAM_EQU_FFE_MAINTAP, 0x00 }, ++ { R367_QAM_EQU_FFE_LEAKAGE, 0x63 }, ++ { R367_QAM_EQU_FFE_MAINTAP_POS, 0xdf }, ++ { R367_QAM_EQU_GAIN_WIDE, 0x88 }, ++ { R367_QAM_EQU_GAIN_NARROW, 0x41 }, ++ { R367_QAM_EQU_CTR_LPF_GAIN, 0xd1 }, ++ { R367_QAM_EQU_CRL_LPF_GAIN, 0xa7 }, ++ { R367_QAM_EQU_GLOBAL_GAIN, 0x06 }, ++ { R367_QAM_EQU_CRL_LD_SEN, 0x85 }, ++ { R367_QAM_EQU_CRL_LD_VAL, 0xe2 }, ++ { R367_QAM_EQU_CRL_TFR, 0x20 }, ++ { R367_QAM_EQU_CRL_BISTH_LO, 0x00 }, ++ { R367_QAM_EQU_CRL_BISTH_HI, 0x00 }, ++ { R367_QAM_EQU_SWEEP_RANGE_LO, 0x00 }, ++ { R367_QAM_EQU_SWEEP_RANGE_HI, 0x00 }, ++ { R367_QAM_EQU_CRL_LIMITER, 0x40 }, ++ { R367_QAM_EQU_MODULUS_MAP, 0x90 }, ++ { R367_QAM_EQU_PNT_GAIN, 0xa7 }, ++ { R367_QAM_FEC_AC_CTR_0, 0x16 }, ++ { R367_QAM_FEC_AC_CTR_1, 0x0b }, ++ { R367_QAM_FEC_AC_CTR_2, 0x88 }, ++ { R367_QAM_FEC_AC_CTR_3, 0x02 }, ++ { R367_QAM_FEC_STATUS, 0x12 }, ++ { R367_QAM_RS_COUNTER_0, 0x7d }, ++ { R367_QAM_RS_COUNTER_1, 0xd0 }, ++ { R367_QAM_RS_COUNTER_2, 0x19 }, ++ { R367_QAM_RS_COUNTER_3, 0x0b }, ++ { R367_QAM_RS_COUNTER_4, 0xa3 }, ++ { R367_QAM_RS_COUNTER_5, 0x00 }, ++ { R367_QAM_BERT_0, 0x01 }, ++ { R367_QAM_BERT_1, 0x25 }, ++ { R367_QAM_BERT_2, 0x41 }, ++ { R367_QAM_BERT_3, 0x39 }, ++ { R367_QAM_OUTFORMAT_0, 0xc2 }, ++ { R367_QAM_OUTFORMAT_1, 0x22 }, ++ { R367_QAM_SMOOTHER_2, 0x28 }, ++ { R367_QAM_TSMF_CTRL_0, 0x01 }, ++ { R367_QAM_TSMF_CTRL_1, 0xc6 }, ++ { R367_QAM_TSMF_CTRL_3, 0x43 }, ++ { R367_QAM_TS_ON_ID_0, 0x00 }, ++ { R367_QAM_TS_ON_ID_1, 0x00 }, ++ { R367_QAM_TS_ON_ID_2, 0x00 }, ++ { R367_QAM_TS_ON_ID_3, 0x00 }, ++ { R367_QAM_RE_STATUS_0, 0x00 }, ++ { R367_QAM_RE_STATUS_1, 0x00 }, ++ { R367_QAM_RE_STATUS_2, 0x00 }, ++ { R367_QAM_RE_STATUS_3, 0x00 }, ++ { R367_QAM_TS_STATUS_0, 0x00 }, ++ { R367_QAM_TS_STATUS_1, 0x00 }, ++ { R367_QAM_TS_STATUS_2, 0xa0 }, ++ { R367_QAM_TS_STATUS_3, 0x00 }, ++ { R367_QAM_T_O_ID_0, 0x00 }, ++ { R367_QAM_T_O_ID_1, 0x00 }, ++ { R367_QAM_T_O_ID_2, 0x00 }, ++ { R367_QAM_T_O_ID_3, 0x00 }, ++ { 0x0000, 0x00 } // EOT ++}; ++ ++struct init_table ofdm_init[] = { ++ //{R367_OFDM_ID ,0x60}, ++ //{R367_OFDM_I2CRPT ,0x22}, ++ //{R367_OFDM_TOPCTRL ,0x02}, ++ //{R367_OFDM_IOCFG0 ,0x40}, ++ //{R367_OFDM_DAC0R ,0x00}, ++ //{R367_OFDM_IOCFG1 ,0x00}, ++ //{R367_OFDM_DAC1R ,0x00}, ++ //{R367_OFDM_IOCFG2 ,0x62}, ++ //{R367_OFDM_SDFR ,0x00}, ++ //{R367_OFDM_STATUS ,0xf8}, ++ //{R367_OFDM_AUX_CLK ,0x0a}, ++ //{R367_OFDM_FREESYS1 ,0x00}, ++ //{R367_OFDM_FREESYS2 ,0x00}, ++ //{R367_OFDM_FREESYS3 ,0x00}, ++ //{R367_OFDM_GPIO_CFG ,0x55}, ++ //{R367_OFDM_GPIO_CMD ,0x00}, ++ {R367_OFDM_AGC2MAX ,0xff}, ++ {R367_OFDM_AGC2MIN ,0x00}, ++ {R367_OFDM_AGC1MAX ,0xff}, ++ {R367_OFDM_AGC1MIN ,0x00}, ++ {R367_OFDM_AGCR ,0xbc}, ++ {R367_OFDM_AGC2TH ,0x00}, ++ //{R367_OFDM_AGC12C ,0x01}, //Note: This defines AGC pins, also needed for QAM ++ {R367_OFDM_AGCCTRL1 ,0x85}, ++ {R367_OFDM_AGCCTRL2 ,0x1f}, ++ {R367_OFDM_AGC1VAL1 ,0x00}, ++ {R367_OFDM_AGC1VAL2 ,0x00}, ++ {R367_OFDM_AGC2VAL1 ,0x6f}, ++ {R367_OFDM_AGC2VAL2 ,0x05}, ++ {R367_OFDM_AGC2PGA ,0x00}, ++ {R367_OFDM_OVF_RATE1 ,0x00}, ++ {R367_OFDM_OVF_RATE2 ,0x00}, ++ {R367_OFDM_GAIN_SRC1 ,0x2b}, ++ {R367_OFDM_GAIN_SRC2 ,0x04}, ++ {R367_OFDM_INC_DEROT1 ,0x55}, ++ {R367_OFDM_INC_DEROT2 ,0x55}, ++ {R367_OFDM_PPM_CPAMP_DIR ,0x2c}, ++ {R367_OFDM_PPM_CPAMP_INV ,0x00}, ++ {R367_OFDM_FREESTFE_1 ,0x00}, ++ {R367_OFDM_FREESTFE_2 ,0x1c}, ++ {R367_OFDM_DCOFFSET ,0x00}, ++ {R367_OFDM_EN_PROCESS ,0x05}, ++ {R367_OFDM_SDI_SMOOTHER ,0x80}, ++ {R367_OFDM_FE_LOOP_OPEN ,0x1c}, ++ {R367_OFDM_FREQOFF1 ,0x00}, ++ {R367_OFDM_FREQOFF2 ,0x00}, ++ {R367_OFDM_FREQOFF3 ,0x00}, ++ {R367_OFDM_TIMOFF1 ,0x00}, ++ {R367_OFDM_TIMOFF2 ,0x00}, ++ {R367_OFDM_EPQ ,0x02}, ++ {R367_OFDM_EPQAUTO ,0x01}, ++ {R367_OFDM_SYR_UPDATE ,0xf5}, ++ {R367_OFDM_CHPFREE ,0x00}, ++ {R367_OFDM_PPM_STATE_MAC ,0x23}, ++ {R367_OFDM_INR_THRESHOLD ,0xff}, ++ {R367_OFDM_EPQ_TPS_ID_CELL ,0xf9}, ++ {R367_OFDM_EPQ_CFG ,0x00}, ++ {R367_OFDM_EPQ_STATUS ,0x01}, ++ {R367_OFDM_AUTORELOCK ,0x81}, ++ {R367_OFDM_BER_THR_VMSB ,0x00}, ++ {R367_OFDM_BER_THR_MSB ,0x00}, ++ {R367_OFDM_BER_THR_LSB ,0x00}, ++ {R367_OFDM_CCD ,0x83}, ++ {R367_OFDM_SPECTR_CFG ,0x00}, ++ {R367_OFDM_CHC_DUMMY ,0x18}, ++ {R367_OFDM_INC_CTL ,0x88}, ++ {R367_OFDM_INCTHRES_COR1 ,0xb4}, ++ {R367_OFDM_INCTHRES_COR2 ,0x96}, ++ {R367_OFDM_INCTHRES_DET1 ,0x0e}, ++ {R367_OFDM_INCTHRES_DET2 ,0x11}, ++ {R367_OFDM_IIR_CELLNB ,0x8d}, ++ {R367_OFDM_IIRCX_COEFF1_MSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF1_LSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF2_MSB ,0x09}, ++ {R367_OFDM_IIRCX_COEFF2_LSB ,0x18}, ++ {R367_OFDM_IIRCX_COEFF3_MSB ,0x14}, ++ {R367_OFDM_IIRCX_COEFF3_LSB ,0x9c}, ++ {R367_OFDM_IIRCX_COEFF4_MSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF4_LSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF5_MSB ,0x36}, ++ {R367_OFDM_IIRCX_COEFF5_LSB ,0x42}, ++ {R367_OFDM_FEPATH_CFG ,0x00}, ++ {R367_OFDM_PMC1_FUNC ,0x65}, ++ {R367_OFDM_PMC1_FOR ,0x00}, ++ {R367_OFDM_PMC2_FUNC ,0x00}, ++ {R367_OFDM_STATUS_ERR_DA ,0xe0}, ++ {R367_OFDM_DIG_AGC_R ,0xfe}, ++ {R367_OFDM_COMAGC_TARMSB ,0x0b}, ++ {R367_OFDM_COM_AGC_TAR_ENMODE ,0x41}, ++ {R367_OFDM_COM_AGC_CFG ,0x3e}, ++ {R367_OFDM_COM_AGC_GAIN1 ,0x39}, ++ {R367_OFDM_AUT_AGC_TARGETMSB ,0x0b}, ++ {R367_OFDM_LOCK_DET_MSB ,0x01}, ++ {R367_OFDM_AGCTAR_LOCK_LSBS ,0x40}, ++ {R367_OFDM_AUT_GAIN_EN ,0xf4}, ++ {R367_OFDM_AUT_CFG ,0xf0}, ++ {R367_OFDM_LOCKN ,0x23}, ++ {R367_OFDM_INT_X_3 ,0x00}, ++ {R367_OFDM_INT_X_2 ,0x03}, ++ {R367_OFDM_INT_X_1 ,0x8d}, ++ {R367_OFDM_INT_X_0 ,0xa0}, ++ {R367_OFDM_MIN_ERRX_MSB ,0x00}, ++ {R367_OFDM_COR_CTL ,0x00}, ++ {R367_OFDM_COR_STAT ,0xf6}, ++ {R367_OFDM_COR_INTEN ,0x00}, ++ {R367_OFDM_COR_INTSTAT ,0x3f}, ++ {R367_OFDM_COR_MODEGUARD ,0x03}, ++ {R367_OFDM_AGC_CTL ,0x08}, ++ {R367_OFDM_AGC_MANUAL1 ,0x00}, ++ {R367_OFDM_AGC_MANUAL2 ,0x00}, ++ {R367_OFDM_AGC_TARG ,0x16}, ++ {R367_OFDM_AGC_GAIN1 ,0x53}, ++ {R367_OFDM_AGC_GAIN2 ,0x1d}, ++ {R367_OFDM_RESERVED_1 ,0x00}, ++ {R367_OFDM_RESERVED_2 ,0x00}, ++ {R367_OFDM_RESERVED_3 ,0x00}, ++ {R367_OFDM_CAS_CTL ,0x44}, ++ {R367_OFDM_CAS_FREQ ,0xb3}, ++ {R367_OFDM_CAS_DAGCGAIN ,0x12}, ++ {R367_OFDM_SYR_CTL ,0x04}, ++ {R367_OFDM_SYR_STAT ,0x10}, ++ {R367_OFDM_SYR_NCO1 ,0x00}, ++ {R367_OFDM_SYR_NCO2 ,0x00}, ++ {R367_OFDM_SYR_OFFSET1 ,0x00}, ++ {R367_OFDM_SYR_OFFSET2 ,0x00}, ++ {R367_OFDM_FFT_CTL ,0x00}, ++ {R367_OFDM_SCR_CTL ,0x70}, ++ {R367_OFDM_PPM_CTL1 ,0xf8}, ++ {R367_OFDM_TRL_CTL ,0xac}, ++ {R367_OFDM_TRL_NOMRATE1 ,0x1e}, ++ {R367_OFDM_TRL_NOMRATE2 ,0x58}, ++ {R367_OFDM_TRL_TIME1 ,0x1d}, ++ {R367_OFDM_TRL_TIME2 ,0xfc}, ++ {R367_OFDM_CRL_CTL ,0x24}, ++ {R367_OFDM_CRL_FREQ1 ,0xad}, ++ {R367_OFDM_CRL_FREQ2 ,0x9d}, ++ {R367_OFDM_CRL_FREQ3 ,0xff}, ++ {R367_OFDM_CHC_CTL ,0x01}, ++ {R367_OFDM_CHC_SNR ,0xf0}, ++ {R367_OFDM_BDI_CTL ,0x00}, ++ {R367_OFDM_DMP_CTL ,0x00}, ++ {R367_OFDM_TPS_RCVD1 ,0x30}, ++ {R367_OFDM_TPS_RCVD2 ,0x02}, ++ {R367_OFDM_TPS_RCVD3 ,0x01}, ++ {R367_OFDM_TPS_RCVD4 ,0x00}, ++ {R367_OFDM_TPS_ID_CELL1 ,0x00}, ++ {R367_OFDM_TPS_ID_CELL2 ,0x00}, ++ {R367_OFDM_TPS_RCVD5_SET1 ,0x02}, ++ {R367_OFDM_TPS_SET2 ,0x02}, ++ {R367_OFDM_TPS_SET3 ,0x01}, ++ {R367_OFDM_TPS_CTL ,0x00}, ++ {R367_OFDM_CTL_FFTOSNUM ,0x34}, ++ {R367_OFDM_TESTSELECT ,0x09}, ++ {R367_OFDM_MSC_REV ,0x0a}, ++ {R367_OFDM_PIR_CTL ,0x00}, ++ {R367_OFDM_SNR_CARRIER1 ,0xa1}, ++ {R367_OFDM_SNR_CARRIER2 ,0x9a}, ++ {R367_OFDM_PPM_CPAMP ,0x2c}, ++ {R367_OFDM_TSM_AP0 ,0x00}, ++ {R367_OFDM_TSM_AP1 ,0x00}, ++ {R367_OFDM_TSM_AP2 ,0x00}, ++ {R367_OFDM_TSM_AP3 ,0x00}, ++ {R367_OFDM_TSM_AP4 ,0x00}, ++ {R367_OFDM_TSM_AP5 ,0x00}, ++ {R367_OFDM_TSM_AP6 ,0x00}, ++ {R367_OFDM_TSM_AP7 ,0x00}, ++ //{R367_OFDM_TSTRES ,0x00}, ++ //{R367_OFDM_ANACTRL ,0x0D},/*caution PLL stopped, to be restarted at init!!!*/ ++ //{R367_OFDM_TSTBUS ,0x00}, ++ //{R367_OFDM_TSTRATE ,0x00}, ++ {R367_OFDM_CONSTMODE ,0x01}, ++ {R367_OFDM_CONSTCARR1 ,0x00}, ++ {R367_OFDM_CONSTCARR2 ,0x00}, ++ {R367_OFDM_ICONSTEL ,0x0a}, ++ {R367_OFDM_QCONSTEL ,0x15}, ++ {R367_OFDM_TSTBISTRES0 ,0x00}, ++ {R367_OFDM_TSTBISTRES1 ,0x00}, ++ {R367_OFDM_TSTBISTRES2 ,0x28}, ++ {R367_OFDM_TSTBISTRES3 ,0x00}, ++ //{R367_OFDM_RF_AGC1 ,0xff}, ++ //{R367_OFDM_RF_AGC2 ,0x83}, ++ //{R367_OFDM_ANADIGCTRL ,0x19}, ++ //{R367_OFDM_PLLMDIV ,0x0c}, ++ //{R367_OFDM_PLLNDIV ,0x55}, ++ //{R367_OFDM_PLLSETUP ,0x18}, ++ //{R367_OFDM_DUAL_AD12 ,0x00}, ++ //{R367_OFDM_TSTBIST ,0x00}, ++ //{R367_OFDM_PAD_COMP_CTRL ,0x00}, ++ //{R367_OFDM_PAD_COMP_WR ,0x00}, ++ //{R367_OFDM_PAD_COMP_RD ,0xe0}, ++ {R367_OFDM_SYR_TARGET_FFTADJT_MSB ,0x00}, ++ {R367_OFDM_SYR_TARGET_FFTADJT_LSB ,0x00}, ++ {R367_OFDM_SYR_TARGET_CHCADJT_MSB ,0x00}, ++ {R367_OFDM_SYR_TARGET_CHCADJT_LSB ,0x00}, ++ {R367_OFDM_SYR_FLAG ,0x00}, ++ {R367_OFDM_CRL_TARGET1 ,0x00}, ++ {R367_OFDM_CRL_TARGET2 ,0x00}, ++ {R367_OFDM_CRL_TARGET3 ,0x00}, ++ {R367_OFDM_CRL_TARGET4 ,0x00}, ++ {R367_OFDM_CRL_FLAG ,0x00}, ++ {R367_OFDM_TRL_TARGET1 ,0x00}, ++ {R367_OFDM_TRL_TARGET2 ,0x00}, ++ {R367_OFDM_TRL_CHC ,0x00}, ++ {R367_OFDM_CHC_SNR_TARG ,0x00}, ++ {R367_OFDM_TOP_TRACK ,0x00}, ++ {R367_OFDM_TRACKER_FREE1 ,0x00}, ++ {R367_OFDM_ERROR_CRL1 ,0x00}, ++ {R367_OFDM_ERROR_CRL2 ,0x00}, ++ {R367_OFDM_ERROR_CRL3 ,0x00}, ++ {R367_OFDM_ERROR_CRL4 ,0x00}, ++ {R367_OFDM_DEC_NCO1 ,0x2c}, ++ {R367_OFDM_DEC_NCO2 ,0x0f}, ++ {R367_OFDM_DEC_NCO3 ,0x20}, ++ {R367_OFDM_SNR ,0xf1}, ++ {R367_OFDM_SYR_FFTADJ1 ,0x00}, ++ {R367_OFDM_SYR_FFTADJ2 ,0x00}, ++ {R367_OFDM_SYR_CHCADJ1 ,0x00}, ++ {R367_OFDM_SYR_CHCADJ2 ,0x00}, ++ {R367_OFDM_SYR_OFF ,0x00}, ++ {R367_OFDM_PPM_OFFSET1 ,0x00}, ++ {R367_OFDM_PPM_OFFSET2 ,0x03}, ++ {R367_OFDM_TRACKER_FREE2 ,0x00}, ++ {R367_OFDM_DEBG_LT10 ,0x00}, ++ {R367_OFDM_DEBG_LT11 ,0x00}, ++ {R367_OFDM_DEBG_LT12 ,0x00}, ++ {R367_OFDM_DEBG_LT13 ,0x00}, ++ {R367_OFDM_DEBG_LT14 ,0x00}, ++ {R367_OFDM_DEBG_LT15 ,0x00}, ++ {R367_OFDM_DEBG_LT16 ,0x00}, ++ {R367_OFDM_DEBG_LT17 ,0x00}, ++ {R367_OFDM_DEBG_LT18 ,0x00}, ++ {R367_OFDM_DEBG_LT19 ,0x00}, ++ {R367_OFDM_DEBG_LT1A ,0x00}, ++ {R367_OFDM_DEBG_LT1B ,0x00}, ++ {R367_OFDM_DEBG_LT1C ,0x00}, ++ {R367_OFDM_DEBG_LT1D ,0x00}, ++ {R367_OFDM_DEBG_LT1E ,0x00}, ++ {R367_OFDM_DEBG_LT1F ,0x00}, ++ {R367_OFDM_RCCFGH ,0x00}, ++ {R367_OFDM_RCCFGM ,0x00}, ++ {R367_OFDM_RCCFGL ,0x00}, ++ {R367_OFDM_RCINSDELH ,0x00}, ++ {R367_OFDM_RCINSDELM ,0x00}, ++ {R367_OFDM_RCINSDELL ,0x00}, ++ {R367_OFDM_RCSTATUS ,0x00}, ++ {R367_OFDM_RCSPEED ,0x6f}, ++ {R367_OFDM_RCDEBUGM ,0xe7}, ++ {R367_OFDM_RCDEBUGL ,0x9b}, ++ {R367_OFDM_RCOBSCFG ,0x00}, ++ {R367_OFDM_RCOBSM ,0x00}, ++ {R367_OFDM_RCOBSL ,0x00}, ++ {R367_OFDM_RCFECSPY ,0x00}, ++ {R367_OFDM_RCFSPYCFG ,0x00}, ++ {R367_OFDM_RCFSPYDATA ,0x00}, ++ {R367_OFDM_RCFSPYOUT ,0x00}, ++ {R367_OFDM_RCFSTATUS ,0x00}, ++ {R367_OFDM_RCFGOODPACK ,0x00}, ++ {R367_OFDM_RCFPACKCNT ,0x00}, ++ {R367_OFDM_RCFSPYMISC ,0x00}, ++ {R367_OFDM_RCFBERCPT4 ,0x00}, ++ {R367_OFDM_RCFBERCPT3 ,0x00}, ++ {R367_OFDM_RCFBERCPT2 ,0x00}, ++ {R367_OFDM_RCFBERCPT1 ,0x00}, ++ {R367_OFDM_RCFBERCPT0 ,0x00}, ++ {R367_OFDM_RCFBERERR2 ,0x00}, ++ {R367_OFDM_RCFBERERR1 ,0x00}, ++ {R367_OFDM_RCFBERERR0 ,0x00}, ++ {R367_OFDM_RCFSTATESM ,0x00}, ++ {R367_OFDM_RCFSTATESL ,0x00}, ++ {R367_OFDM_RCFSPYBER ,0x00}, ++ {R367_OFDM_RCFSPYDISTM ,0x00}, ++ {R367_OFDM_RCFSPYDISTL ,0x00}, ++ {R367_OFDM_RCFSPYOBS7 ,0x00}, ++ {R367_OFDM_RCFSPYOBS6 ,0x00}, ++ {R367_OFDM_RCFSPYOBS5 ,0x00}, ++ {R367_OFDM_RCFSPYOBS4 ,0x00}, ++ {R367_OFDM_RCFSPYOBS3 ,0x00}, ++ {R367_OFDM_RCFSPYOBS2 ,0x00}, ++ {R367_OFDM_RCFSPYOBS1 ,0x00}, ++ {R367_OFDM_RCFSPYOBS0 ,0x00}, ++ //{R367_OFDM_TSGENERAL ,0x00}, ++ //{R367_OFDM_RC1SPEED ,0x6f}, ++ //{R367_OFDM_TSGSTATUS ,0x18}, ++ {R367_OFDM_FECM ,0x01}, ++ {R367_OFDM_VTH12 ,0xff}, ++ {R367_OFDM_VTH23 ,0xa1}, ++ {R367_OFDM_VTH34 ,0x64}, ++ {R367_OFDM_VTH56 ,0x40}, ++ {R367_OFDM_VTH67 ,0x00}, ++ {R367_OFDM_VTH78 ,0x2c}, ++ {R367_OFDM_VITCURPUN ,0x12}, ++ {R367_OFDM_VERROR ,0x01}, ++ {R367_OFDM_PRVIT ,0x3f}, ++ {R367_OFDM_VAVSRVIT ,0x00}, ++ {R367_OFDM_VSTATUSVIT ,0xbd}, ++ {R367_OFDM_VTHINUSE ,0xa1}, ++ {R367_OFDM_KDIV12 ,0x20}, ++ {R367_OFDM_KDIV23 ,0x40}, ++ {R367_OFDM_KDIV34 ,0x20}, ++ {R367_OFDM_KDIV56 ,0x30}, ++ {R367_OFDM_KDIV67 ,0x00}, ++ {R367_OFDM_KDIV78 ,0x30}, ++ {R367_OFDM_SIGPOWER ,0x54}, ++ {R367_OFDM_DEMAPVIT ,0x40}, ++ {R367_OFDM_VITSCALE ,0x00}, ++ {R367_OFDM_FFEC1PRG ,0x00}, ++ {R367_OFDM_FVITCURPUN ,0x12}, ++ {R367_OFDM_FVERROR ,0x01}, ++ {R367_OFDM_FVSTATUSVIT ,0xbd}, ++ {R367_OFDM_DEBUG_LT1 ,0x00}, ++ {R367_OFDM_DEBUG_LT2 ,0x00}, ++ {R367_OFDM_DEBUG_LT3 ,0x00}, ++ {R367_OFDM_TSTSFMET ,0x00}, ++ {R367_OFDM_SELOUT ,0x00}, ++ {R367_OFDM_TSYNC ,0x00}, ++ {R367_OFDM_TSTERR ,0x00}, ++ {R367_OFDM_TSFSYNC ,0x00}, ++ {R367_OFDM_TSTSFERR ,0x00}, ++ {R367_OFDM_TSTTSSF1 ,0x01}, ++ {R367_OFDM_TSTTSSF2 ,0x1f}, ++ {R367_OFDM_TSTTSSF3 ,0x00}, ++ {R367_OFDM_TSTTS1 ,0x00}, ++ {R367_OFDM_TSTTS2 ,0x1f}, ++ {R367_OFDM_TSTTS3 ,0x01}, ++ {R367_OFDM_TSTTS4 ,0x00}, ++ {R367_OFDM_TSTTSRC ,0x00}, ++ {R367_OFDM_TSTTSRS ,0x00}, ++ {R367_OFDM_TSSTATEM ,0xb0}, ++ {R367_OFDM_TSSTATEL ,0x40}, ++ {R367_OFDM_TSCFGH ,0x80}, ++ {R367_OFDM_TSCFGM ,0x00}, ++ {R367_OFDM_TSCFGL ,0x20}, ++ {R367_OFDM_TSSYNC ,0x00}, ++ {R367_OFDM_TSINSDELH ,0x00}, ++ {R367_OFDM_TSINSDELM ,0x00}, ++ {R367_OFDM_TSINSDELL ,0x00}, ++ {R367_OFDM_TSDIVN ,0x03}, ++ {R367_OFDM_TSDIVPM ,0x00}, ++ {R367_OFDM_TSDIVPL ,0x00}, ++ {R367_OFDM_TSDIVQM ,0x00}, ++ {R367_OFDM_TSDIVQL ,0x00}, ++ {R367_OFDM_TSDILSTKM ,0x00}, ++ {R367_OFDM_TSDILSTKL ,0x00}, ++ {R367_OFDM_TSSPEED ,0x6f}, ++ {R367_OFDM_TSSTATUS ,0x81}, ++ {R367_OFDM_TSSTATUS2 ,0x6a}, ++ {R367_OFDM_TSBITRATEM ,0x0f}, ++ {R367_OFDM_TSBITRATEL ,0xc6}, ++ {R367_OFDM_TSPACKLENM ,0x00}, ++ {R367_OFDM_TSPACKLENL ,0xfc}, ++ {R367_OFDM_TSBLOCLENM ,0x0a}, ++ {R367_OFDM_TSBLOCLENL ,0x80}, ++ {R367_OFDM_TSDLYH ,0x90}, ++ {R367_OFDM_TSDLYM ,0x68}, ++ {R367_OFDM_TSDLYL ,0x01}, ++ {R367_OFDM_TSNPDAV ,0x00}, ++ {R367_OFDM_TSBUFSTATH ,0x00}, ++ {R367_OFDM_TSBUFSTATM ,0x00}, ++ {R367_OFDM_TSBUFSTATL ,0x00}, ++ {R367_OFDM_TSDEBUGM ,0xcf}, ++ {R367_OFDM_TSDEBUGL ,0x1e}, ++ {R367_OFDM_TSDLYSETH ,0x00}, ++ {R367_OFDM_TSDLYSETM ,0x68}, ++ {R367_OFDM_TSDLYSETL ,0x00}, ++ {R367_OFDM_TSOBSCFG ,0x00}, ++ {R367_OFDM_TSOBSM ,0x47}, ++ {R367_OFDM_TSOBSL ,0x1f}, ++ {R367_OFDM_ERRCTRL1 ,0x95}, ++ {R367_OFDM_ERRCNT1H ,0x80}, ++ {R367_OFDM_ERRCNT1M ,0x00}, ++ {R367_OFDM_ERRCNT1L ,0x00}, ++ {R367_OFDM_ERRCTRL2 ,0x95}, ++ {R367_OFDM_ERRCNT2H ,0x00}, ++ {R367_OFDM_ERRCNT2M ,0x00}, ++ {R367_OFDM_ERRCNT2L ,0x00}, ++ {R367_OFDM_FECSPY ,0x88}, ++ {R367_OFDM_FSPYCFG ,0x2c}, ++ {R367_OFDM_FSPYDATA ,0x3a}, ++ {R367_OFDM_FSPYOUT ,0x06}, ++ {R367_OFDM_FSTATUS ,0x61}, ++ {R367_OFDM_FGOODPACK ,0xff}, ++ {R367_OFDM_FPACKCNT ,0xff}, ++ {R367_OFDM_FSPYMISC ,0x66}, ++ {R367_OFDM_FBERCPT4 ,0x00}, ++ {R367_OFDM_FBERCPT3 ,0x00}, ++ {R367_OFDM_FBERCPT2 ,0x36}, ++ {R367_OFDM_FBERCPT1 ,0x36}, ++ {R367_OFDM_FBERCPT0 ,0x14}, ++ {R367_OFDM_FBERERR2 ,0x00}, ++ {R367_OFDM_FBERERR1 ,0x03}, ++ {R367_OFDM_FBERERR0 ,0x28}, ++ {R367_OFDM_FSTATESM ,0x00}, ++ {R367_OFDM_FSTATESL ,0x02}, ++ {R367_OFDM_FSPYBER ,0x00}, ++ {R367_OFDM_FSPYDISTM ,0x01}, ++ {R367_OFDM_FSPYDISTL ,0x9f}, ++ {R367_OFDM_FSPYOBS7 ,0xc9}, ++ {R367_OFDM_FSPYOBS6 ,0x99}, ++ {R367_OFDM_FSPYOBS5 ,0x08}, ++ {R367_OFDM_FSPYOBS4 ,0xec}, ++ {R367_OFDM_FSPYOBS3 ,0x01}, ++ {R367_OFDM_FSPYOBS2 ,0x0f}, ++ {R367_OFDM_FSPYOBS1 ,0xf5}, ++ {R367_OFDM_FSPYOBS0 ,0x08}, ++ {R367_OFDM_SFDEMAP ,0x40}, ++ {R367_OFDM_SFERROR ,0x00}, ++ {R367_OFDM_SFAVSR ,0x30}, ++ {R367_OFDM_SFECSTATUS ,0xcc}, ++ {R367_OFDM_SFKDIV12 ,0x20}, ++ {R367_OFDM_SFKDIV23 ,0x40}, ++ {R367_OFDM_SFKDIV34 ,0x20}, ++ {R367_OFDM_SFKDIV56 ,0x20}, ++ {R367_OFDM_SFKDIV67 ,0x00}, ++ {R367_OFDM_SFKDIV78 ,0x20}, ++ {R367_OFDM_SFDILSTKM ,0x00}, ++ {R367_OFDM_SFDILSTKL ,0x00}, ++ {R367_OFDM_SFSTATUS ,0xb5}, ++ {R367_OFDM_SFDLYH ,0x90}, ++ {R367_OFDM_SFDLYM ,0x60}, ++ {R367_OFDM_SFDLYL ,0x01}, ++ {R367_OFDM_SFDLYSETH ,0xc0}, ++ {R367_OFDM_SFDLYSETM ,0x60}, ++ {R367_OFDM_SFDLYSETL ,0x00}, ++ {R367_OFDM_SFOBSCFG ,0x00}, ++ {R367_OFDM_SFOBSM ,0x47}, ++ {R367_OFDM_SFOBSL ,0x05}, ++ {R367_OFDM_SFECINFO ,0x40}, ++ {R367_OFDM_SFERRCTRL ,0x74}, ++ {R367_OFDM_SFERRCNTH ,0x80}, ++ {R367_OFDM_SFERRCNTM ,0x00}, ++ {R367_OFDM_SFERRCNTL ,0x00}, ++ {R367_OFDM_SYMBRATEM ,0x2f}, ++ {R367_OFDM_SYMBRATEL ,0x50}, ++ {R367_OFDM_SYMBSTATUS ,0x7f}, ++ {R367_OFDM_SYMBCFG ,0x00}, ++ {R367_OFDM_SYMBFIFOM ,0xf4}, ++ {R367_OFDM_SYMBFIFOL ,0x0d}, ++ {R367_OFDM_SYMBOFFSM ,0xf0}, ++ {R367_OFDM_SYMBOFFSL ,0x2d}, ++ //{R367_OFDM_DEBUG_LT4 ,0x00}, ++ //{R367_OFDM_DEBUG_LT5 ,0x00}, ++ //{R367_OFDM_DEBUG_LT6 ,0x00}, ++ //{R367_OFDM_DEBUG_LT7 ,0x00}, ++ //{R367_OFDM_DEBUG_LT8 ,0x00}, ++ //{R367_OFDM_DEBUG_LT9 ,0x00}, ++ { 0x0000, 0x00 } // EOT ++}; ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = ++ {.addr = adr, .flags = 0, .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ printk("stv0367: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++#if 0 ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ printk("stv0367: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++#endif ++ ++static int writereg(struct stv_state *state, u16 reg, u8 dat) ++{ ++ u8 mm[3] = { (reg >> 8), reg & 0xff, dat }; ++ ++ return i2c_write(state->i2c, state->adr, mm, 3); ++} ++ ++static int readreg(struct stv_state *state, u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = state->adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = state->adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1}}; ++ return (i2c_transfer(state->i2c, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int readregs(struct stv_state *state, u16 reg, u8 *val, int count) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = state->adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = state->adr, .flags = I2C_M_RD, ++ .buf = val, .len = count}}; ++ return (i2c_transfer(state->i2c, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int write_init_table(struct stv_state *state, struct init_table *tab) ++{ ++ while (1) { ++ if (!tab->adr) ++ break; ++ if (writereg(state, tab->adr, tab->data) < 0) ++ return -1; ++ tab++; ++ } ++ return 0; ++} ++ ++static int qam_set_modulation(struct stv_state *state) ++{ ++ int stat = 0; ++ ++ switch(state->modulation) { ++ case QAM_16: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM16 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x64); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x00); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0x90); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x95); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x40); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0x8a); ++ break; ++ case QAM_32: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM32 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x6e); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x00); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0xb0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xb7); ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x9d); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x7f); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0xa7); ++ break; ++ case QAM_64: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM64 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x5a); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x82); /* Set digital AGC reference */ ++ if(state->symbol_rate>4500000) ++ { ++ writereg(state, R367_QAM_FSM_STATE,0xb0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa5); ++ } ++ else if(state->symbol_rate>2500000) // 25000000 ++ { ++ writereg(state, R367_QAM_FSM_STATE,0xa0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa6); ++ } ++ else ++ { ++ writereg(state, R367_QAM_FSM_STATE,0xa0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xd1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ } ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x95); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x40); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0x99); ++ break; ++ case QAM_128: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM128 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x76); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x00); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0x90); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xb1); ++ if(state->symbol_rate>4500000) // 45000000 ++ { ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ } ++ else if(state->symbol_rate>2500000) // 25000000 ++ { ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa6); ++ } ++ else ++ { ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0x97); ++ } ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x8e); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x7f); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0xa7); ++ break; ++ case QAM_256: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM256 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x5a); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x94); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0xa0); ++ if(state->symbol_rate>4500000) // 45000000 ++ { ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ } ++ else if(state->symbol_rate>2500000) // 25000000 ++ { ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ } ++ else ++ { ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xd1); ++ } ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x85); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x40); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0xa7); ++ break; ++ default: ++ stat = -EINVAL; ++ break; ++ } ++ return stat; ++} ++ ++ ++static int QAM_SetSymbolRate(struct stv_state *state) ++{ ++ int status = 0; ++ u32 sr = state->symbol_rate; ++ u32 Corr = 0; ++ u32 Temp, Temp1, AdpClk; ++ ++ switch(state->modulation) { ++ default: ++ case QAM_16: Corr = 1032; break; ++ case QAM_32: Corr = 954; break; ++ case QAM_64: Corr = 983; break; ++ case QAM_128: Corr = 957; break; ++ case QAM_256: Corr = 948; break; ++ } ++ ++ // Transfer ration ++ Temp = (256*sr) / state->adc_clock; ++ writereg(state, R367_QAM_EQU_CRL_TFR,(Temp)); ++ ++ /* Symbol rate and SRC gain calculation */ ++ AdpClk = (state->master_clock) / 2000; /* TRL works at half the system clock */ ++ ++ Temp = state->symbol_rate; ++ Temp1 = sr; ++ ++ if(sr < 2097152) /* 2097152 = 2^21 */ ++ { ++ Temp = ((((sr * 2048) / AdpClk) * 16384 ) / 125 ) * 8; ++ Temp1 = (((((sr * 2048) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 10000000; ++ } ++ else if(sr < 4194304) /* 4194304 = 2**22 */ ++ { ++ Temp = ((((sr * 1024) / AdpClk) * 16384 ) / 125 ) * 16; ++ Temp1 = (((((sr * 1024) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 5000000; ++ } ++ else if(sr < 8388608) /* 8388608 = 2**23 */ ++ { ++ Temp = ((((sr * 512) / AdpClk) * 16384 ) / 125 ) * 32; ++ Temp1 = (((((sr * 512) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 2500000; ++ } ++ else ++ { ++ Temp = ((((sr * 256) / AdpClk) * 16384 ) / 125 ) * 64; ++ Temp1 = (((((sr * 256) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 1250000; ++ } ++ ++ ///* Filters' coefficients are calculated and written into registers only if the filters are enabled */ ++ //if (ChipGetField(hChip,F367qam_ADJ_EN)) // Is disabled from init! ++ //{ ++ // FE_367qam_SetIirAdjacentcoefficient(hChip, MasterClk_Hz, SymbolRate); ++ //} ++ ///* AllPass filter is never used on this IC */ ++ //ChipSetField(hChip,F367qam_ALLPASSFILT_EN,0); // should be disabled from init! ++ ++ writereg(state, R367_QAM_SRC_NCO_LL,(Temp)); ++ writereg(state, R367_QAM_SRC_NCO_LH,(Temp>>8)); ++ writereg(state, R367_QAM_SRC_NCO_HL,(Temp>>16)); ++ writereg(state, R367_QAM_SRC_NCO_HH,(Temp>>24)); ++ ++ writereg(state, R367_QAM_IQDEM_GAIN_SRC_L,(Temp1)); ++ writereg(state, R367_QAM_IQDEM_GAIN_SRC_H,(Temp1>>8)); ++ return status; ++} ++ ++ ++static int QAM_SetDerotFrequency(struct stv_state *state, u32 DerotFrequency) ++{ ++ int status = 0; ++ u32 Sampled_IF; ++ ++ do { ++ //if (DerotFrequency < 1000000) ++ // DerotFrequency = state->adc_clock/4; /* ZIF operation */ ++ if (DerotFrequency > state->adc_clock) ++ DerotFrequency = DerotFrequency - state->adc_clock; // User Alias ++ ++ Sampled_IF = ((32768 * (DerotFrequency/1000)) / (state->adc_clock/1000)) * 256; ++ if(Sampled_IF > 8388607) ++ Sampled_IF = 8388607; ++ ++ writereg(state, R367_QAM_MIX_NCO_LL, (Sampled_IF)); ++ writereg(state, R367_QAM_MIX_NCO_HL, (Sampled_IF>>8)); ++ writereg(state, R367_QAM_MIX_NCO_HH, (Sampled_IF>>16)); ++ } while(0); ++ ++ return status; ++} ++ ++ ++ ++static int QAM_Start(struct stv_state *state, s32 offsetFreq,s32 IntermediateFrequency) ++{ ++ int status = 0; ++ u32 AGCTimeOut = 25; ++ u32 TRLTimeOut = 100000000 / state->symbol_rate; ++ u32 CRLSymbols = 0; ++ u32 EQLTimeOut = 100; ++ u32 SearchRange = state->symbol_rate / 25; ++ u32 CRLTimeOut; ++ u8 Temp; ++ ++ if( state->demod_state != QAMSet ) { ++ writereg(state, R367_DEBUG_LT4,0x00); ++ writereg(state, R367_DEBUG_LT5,0x01); ++ writereg(state, R367_DEBUG_LT6,0x06);// R367_QAM_CTRL_1 ++ writereg(state, R367_DEBUG_LT7,0x03);// R367_QAM_CTRL_2 ++ writereg(state, R367_DEBUG_LT8,0x00); ++ writereg(state, R367_DEBUG_LT9,0x00); ++ ++ // Tuner Setup ++ writereg(state, R367_ANADIGCTRL,0x8B); /* Buffer Q disabled, I Enabled, signed ADC */ ++ writereg(state, R367_DUAL_AD12,0x04); /* ADCQ disabled */ ++ ++ // Clock setup ++ writereg(state, R367_ANACTRL,0x0D); /* PLL bypassed and disabled */ ++ writereg(state, R367_TOPCTRL,0x10); // Set QAM ++ ++ writereg(state, R367_PLLMDIV,27); /* IC runs at 58 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV,232); ++ writereg(state, R367_PLLSETUP,0x18); /* ADC clock is equal to system clock */ ++ ++ msleep(50); ++ writereg(state, R367_ANACTRL,0x00); /* PLL enabled and used */ ++ ++ state->master_clock = 58000000; ++ state->adc_clock = 58000000; ++ ++ state->demod_state = QAMSet; ++ } ++ ++ state->m_bFirstTimeLock = true; ++ state->m_DemodLockTime = -1; ++ ++ qam_set_modulation(state); ++ QAM_SetSymbolRate(state); ++ ++ // Will make problems on low symbol rates ( < 2500000 ) ++ ++ switch(state->modulation) { ++ default: ++ case QAM_16: CRLSymbols = 150000; break; ++ case QAM_32: CRLSymbols = 250000; break; ++ case QAM_64: CRLSymbols = 200000; break; ++ case QAM_128: CRLSymbols = 250000; break; ++ case QAM_256: CRLSymbols = 250000; break; ++ } ++ ++ CRLTimeOut = (25 * CRLSymbols * (SearchRange/1000)) / (state->symbol_rate/1000); ++ CRLTimeOut = (1000 * CRLTimeOut) / state->symbol_rate; ++ if( CRLTimeOut < 50 ) CRLTimeOut = 50; ++ ++ state->m_FECTimeOut = 20; ++ state->m_DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut; ++ state->m_SignalTimeOut = AGCTimeOut + TRLTimeOut; ++ ++ // QAM_AGC_ACCUMRSTSEL = 0; ++ readreg(state, R367_QAM_AGC_CTL,&state->m_Save_QAM_AGC_CTL); ++ writereg(state, R367_QAM_AGC_CTL,state->m_Save_QAM_AGC_CTL & ~0x0F); ++ ++ // QAM_MODULUSMAP_EN = 0 ++ readreg(state, R367_QAM_EQU_PNT_GAIN,&Temp); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,Temp & ~0x40); ++ ++ // QAM_SWEEP_EN = 0 ++ readreg(state, R367_QAM_EQU_CTR_LPF_GAIN,&Temp); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,Temp & ~0x08); ++ ++ QAM_SetDerotFrequency(state, IntermediateFrequency); ++ ++ // Release TRL ++ writereg(state, R367_QAM_CTRL_1,0x00); ++ ++ state->IF = IntermediateFrequency; ++ state->demod_state = QAMStarted; ++ ++ return status; ++} ++ ++static int OFDM_Start(struct stv_state *state, s32 offsetFreq,s32 IntermediateFrequency) ++{ ++ int status = 0; ++ u8 GAIN_SRC1; ++ u32 Derot; ++ u8 SYR_CTL; ++ u8 tmp1; ++ u8 tmp2; ++ ++ if ( state->demod_state != OFDMSet ) { ++ // QAM Disable ++ writereg(state, R367_DEBUG_LT4, 0x00); ++ writereg(state, R367_DEBUG_LT5, 0x00); ++ writereg(state, R367_DEBUG_LT6, 0x00);// R367_QAM_CTRL_1 ++ writereg(state, R367_DEBUG_LT7, 0x00);// R367_QAM_CTRL_2 ++ writereg(state, R367_DEBUG_LT8, 0x00); ++ writereg(state, R367_DEBUG_LT9, 0x00); ++ ++ // Tuner Setup ++ writereg(state, R367_ANADIGCTRL, 0x89); /* Buffer Q disabled, I Enabled, unsigned ADC */ ++ writereg(state, R367_DUAL_AD12, 0x04); /* ADCQ disabled */ ++ ++ // Clock setup ++ writereg(state, R367_ANACTRL, 0x0D); /* PLL bypassed and disabled */ ++ writereg(state, R367_TOPCTRL, 0x00); // Set OFDM ++ ++ writereg(state, R367_PLLMDIV, 1); /* IC runs at 54 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV, 8); ++ writereg(state, R367_PLLSETUP, 0x18); /* ADC clock is equal to system clock */ ++ ++ msleep(50); ++ writereg(state, R367_ANACTRL, 0x00); /* PLL enabled and used */ ++ ++ state->master_clock = 54000000; ++ state->adc_clock = 54000000; ++ ++ state->demod_state = OFDMSet; ++ } ++ ++ state->m_bFirstTimeLock = true; ++ state->m_DemodLockTime = -1; ++ ++ // Set inversion in GAIN_SRC1 (fixed from init) ++ // is in GAIN_SRC1, see below ++ ++ GAIN_SRC1 = 0xA0; ++ // Bandwidth ++ ++ // Fixed values for 54 MHz ++ switch(state->bandwidth) { ++ case 0: ++ case 8000000: ++ // Normrate = 44384; ++ writereg(state, R367_OFDM_TRL_CTL,0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1,0xB0); ++ writereg(state, R367_OFDM_TRL_NOMRATE2,0x56); ++ // Gain SRC = 2774 ++ writereg(state, R367_OFDM_GAIN_SRC1,0x0A | GAIN_SRC1); ++ writereg(state, R367_OFDM_GAIN_SRC2,0xD6); ++ break; ++ case 7000000: ++ // Normrate = 38836; ++ writereg(state, R367_OFDM_TRL_CTL,0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1,0xDA); ++ writereg(state, R367_OFDM_TRL_NOMRATE2,0x4B); ++ // Gain SRC = 2427 ++ writereg(state, R367_OFDM_GAIN_SRC1,0x09 | GAIN_SRC1); ++ writereg(state, R367_OFDM_GAIN_SRC2,0x7B); ++ break; ++ case 6000000: ++ // Normrate = 33288; ++ writereg(state, R367_OFDM_TRL_CTL,0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1,0x04); ++ writereg(state, R367_OFDM_TRL_NOMRATE2,0x41); ++ // Gain SRC = 2080 ++ writereg(state, R367_OFDM_GAIN_SRC1,0x08 | GAIN_SRC1); ++ writereg(state, R367_OFDM_GAIN_SRC2,0x20); ++ break; ++ default: ++ return -EINVAL; ++ break; ++ } ++ ++ Derot = ((IntermediateFrequency / 1000) * 65536) / (state->master_clock / 1000); ++ ++ writereg(state, R367_OFDM_INC_DEROT1,(Derot>>8)); ++ writereg(state, R367_OFDM_INC_DEROT2,(Derot)); ++ ++ readreg(state, R367_OFDM_SYR_CTL,&SYR_CTL); ++ SYR_CTL &= ~0x78; ++ writereg(state, R367_OFDM_SYR_CTL,SYR_CTL); // EchoPos = 0 ++ ++ ++ writereg(state, R367_OFDM_COR_MODEGUARD,0x03); // Force = 0, Mode = 0, Guard = 3 ++ SYR_CTL &= 0x01; ++ writereg(state, R367_OFDM_SYR_CTL,SYR_CTL); // SYR_TR_DIS = 0 ++ ++ msleep(5); ++ ++ writereg(state, R367_OFDM_COR_CTL,0x20); // Start core ++ ++ // -- Begin M.V. ++ // Reset FEC and Read Solomon ++ readreg(state, R367_OFDM_SFDLYSETH,&tmp1); ++ readreg(state, R367_TSGENERAL,&tmp2); ++ writereg(state, R367_OFDM_SFDLYSETH,tmp1 | 0x08); ++ writereg(state, R367_TSGENERAL,tmp2 | 0x01); ++ // -- End M.V. ++ ++ state->m_SignalTimeOut = 200; ++ state->IF = IntermediateFrequency; ++ state->demod_state = OFDMStarted; ++ state->m_DemodTimeOut = 0; ++ state->m_FECTimeOut = 0; ++ state->m_TSTimeOut = 0; ++ ++ return status; ++} ++ ++#if 0 ++static int Stop(struct stv_state *state) ++{ ++ int status = 0; ++ ++ switch(state->demod_state) ++ { ++ case QAMStarted: ++ status = writereg(state, R367_QAM_CTRL_1,0x06); ++ state->demod_state = QAMSet; ++ break; ++ case OFDMStarted: ++ status = writereg(state, R367_OFDM_COR_CTL,0x00); ++ state->demod_state = OFDMSet; ++ break; ++ default: ++ break; ++ } ++ return status; ++} ++#endif ++ ++static s32 Log10x100(u32 x) ++{ ++ static u32 LookupTable[100] = { ++ 101157945, 103514217, 105925373, 108392691, 110917482, ++ 113501082, 116144861, 118850223, 121618600, 124451461, // 800.5 - 809.5 ++ 127350308, 130316678, 133352143, 136458314, 139636836, ++ 142889396, 146217717, 149623566, 153108746, 156675107, // 810.5 - 819.5 ++ 160324539, 164058977, 167880402, 171790839, 175792361, ++ 179887092, 184077200, 188364909, 192752491, 197242274, // 820.5 - 829.5 ++ 201836636, 206538016, 211348904, 216271852, 221309471, ++ 226464431, 231739465, 237137371, 242661010, 248313311, // 830.5 - 839.5 ++ 254097271, 260015956, 266072506, 272270131, 278612117, ++ 285101827, 291742701, 298538262, 305492111, 312607937, // 840.5 - 849.5 ++ 319889511, 327340695, 334965439, 342767787, 350751874, ++ 358921935, 367282300, 375837404, 384591782, 393550075, // 850.5 - 859.5 ++ 402717034, 412097519, 421696503, 431519077, 441570447, ++ 451855944, 462381021, 473151259, 484172368, 495450191, // 860.5 - 869.5 ++ 506990708, 518800039, 530884444, 543250331, 555904257, ++ 568852931, 582103218, 595662144, 609536897, 623734835, // 870.5 - 879.5 ++ 638263486, 653130553, 668343918, 683911647, 699841996, ++ 716143410, 732824533, 749894209, 767361489, 785235635, // 880.5 - 889.5 ++ 803526122, 822242650, 841395142, 860993752, 881048873, ++ 901571138, 922571427, 944060876, 966050879, 988553095, // 890.5 - 899.5 ++ }; ++ s32 y; ++ int i; ++ ++ if (x == 0) ++ return 0; ++ y = 800; ++ if (x >= 1000000000) { ++ x /= 10; ++ y += 100; ++ } ++ ++ while (x < 100000000) { ++ x *= 10; ++ y -= 100; ++ } ++ i = 0; ++ while (i < 100 && x > LookupTable[i]) ++ i += 1; ++ y += i; ++ return y; ++} ++ ++static int QAM_GetSignalToNoise(struct stv_state *state, s32 *pSignalToNoise) ++{ ++ u32 RegValAvg = 0; ++ u8 RegVal[2]; ++ int status = 0, i; ++ ++ *pSignalToNoise = 0; ++ for (i = 0; i < 10; i += 1 ) { ++ readregs(state, R367_QAM_EQU_SNR_LO, RegVal, 2); ++ RegValAvg += RegVal[0] + 256 * RegVal[1]; ++ } ++ if (RegValAvg != 0) { ++ s32 Power = 1; ++ switch(state->modulation) { ++ case QAM_16: ++ Power = 20480; ++ break; ++ case QAM_32: ++ Power = 23040; ++ break; ++ case QAM_64: ++ Power = 21504; ++ break; ++ case QAM_128: ++ Power = 23616; ++ break; ++ case QAM_256: ++ Power = 21760; ++ break; ++ default: ++ break; ++ } ++ *pSignalToNoise = Log10x100((Power * 320) / RegValAvg); ++ } else { ++ *pSignalToNoise = 380; ++ } ++ return status; ++} ++ ++static int OFDM_GetSignalToNoise(struct stv_state *state, s32 *pSignalToNoise) ++{ ++ u8 CHC_SNR = 0; ++ ++ int status = readreg(state, R367_OFDM_CHC_SNR, &CHC_SNR); ++ if (status >= 0) { ++ // Note: very unclear documentation on this. ++ // Datasheet states snr = CHC_SNR/4 dB -> way to high values! ++ // Software snr = ( 1000 * CHC_SNR ) / 8 / 32 / 10; -> to low values ++ // Comment in SW states this should be ( 1000 * CHC_SNR ) / 4 / 32 / 10; for the 367 ++ // 361/362 Datasheet: snr = CHC_SNR/8 dB -> this looks best ++ *pSignalToNoise = ( (s32)CHC_SNR * 10) / 8; ++ } ++ //printk("SNR %d\n", *pSignalToNoise); ++ return status; ++} ++ ++#if 0 ++static int DVBC_GetQuality(struct stv_state *state, s32 SignalToNoise, s32 *pQuality) ++{ ++ *pQuality = 100; ++ return 0; ++}; ++ ++static int DVBT_GetQuality(struct stv_state *state, s32 SignalToNoise, s32 *pQuality) ++{ ++ static s32 QE_SN[] = { ++ 51, // QPSK 1/2 ++ 69, // QPSK 2/3 ++ 79, // QPSK 3/4 ++ 89, // QPSK 5/6 ++ 97, // QPSK 7/8 ++ 108, // 16-QAM 1/2 ++ 131, // 16-QAM 2/3 ++ 146, // 16-QAM 3/4 ++ 156, // 16-QAM 5/6 ++ 160, // 16-QAM 7/8 ++ 165, // 64-QAM 1/2 ++ 187, // 64-QAM 2/3 ++ 202, // 64-QAM 3/4 ++ 216, // 64-QAM 5/6 ++ 225, // 64-QAM 7/8 ++ }; ++ u8 TPS_Received[2]; ++ int Constellation; ++ int CodeRate; ++ s32 SignalToNoiseRel, BERQuality; ++ ++ *pQuality = 0; ++ readregs(state, R367_OFDM_TPS_RCVD2, TPS_Received, sizeof(TPS_Received)); ++ Constellation = TPS_Received[0] & 0x03; ++ CodeRate = TPS_Received[1] & 0x07; ++ ++ if( Constellation > 2 || CodeRate > 5 ) ++ return -1; ++ SignalToNoiseRel = SignalToNoise - QE_SN[Constellation * 5 + CodeRate]; ++ BERQuality = 100; ++ ++ if( SignalToNoiseRel < -70 ) ++ *pQuality = 0; ++ else if( SignalToNoiseRel < 30 ) { ++ *pQuality = ((SignalToNoiseRel + 70) * BERQuality)/100; ++ } else ++ *pQuality = BERQuality; ++ return 0; ++}; ++ ++static s32 DVBCQuality(struct stv_state *state, s32 SignalToNoise) ++{ ++ s32 SignalToNoiseRel = 0; ++ s32 Quality = 0; ++ s32 BERQuality = 100; ++ ++ switch(state->modulation) { ++ case QAM_16: SignalToNoiseRel = SignalToNoise - 200 ; break; ++ case QAM_32: SignalToNoiseRel = SignalToNoise - 230 ; break; // Not in NorDig ++ case QAM_64: SignalToNoiseRel = SignalToNoise - 260 ; break; ++ case QAM_128: SignalToNoiseRel = SignalToNoise - 290 ; break; ++ case QAM_256: SignalToNoiseRel = SignalToNoise - 320 ; break; ++ } ++ ++ if( SignalToNoiseRel < -70 ) Quality = 0; ++ else if( SignalToNoiseRel < 30 ) ++ { ++ Quality = ((SignalToNoiseRel + 70) * BERQuality)/100; ++ } ++ else ++ Quality = BERQuality; ++ ++ return Quality; ++} ++ ++static int GetQuality(struct stv_state *state, s32 SignalToNoise, s32 *pQuality) ++{ ++ *pQuality = 0; ++ switch(state->demod_state) ++ { ++ case QAMStarted: ++ *pQuality = DVBCQuality(state, SignalToNoise); ++ break; ++ case OFDMStarted: ++ return DVBT_GetQuality(state, SignalToNoise, pQuality); ++ } ++ return 0; ++}; ++#endif ++ ++static int attach_init(struct stv_state *state) ++{ ++ int stat = 0; ++ ++ stat = readreg(state, R367_ID, &state->ID); ++ if ( stat < 0 || state->ID != 0x60 ) ++ return -ENODEV; ++ printk("stv0367 found\n"); ++ ++ writereg(state, R367_TOPCTRL, 0x10); ++ write_init_table(state, base_init); ++ write_init_table(state, qam_init); ++ ++ writereg(state, R367_TOPCTRL, 0x00); ++ write_init_table(state, ofdm_init); ++ ++ writereg(state, R367_OFDM_GAIN_SRC1, 0x2A); ++ writereg(state, R367_OFDM_GAIN_SRC2, 0xD6); ++ writereg(state, R367_OFDM_INC_DEROT1, 0x55); ++ writereg(state, R367_OFDM_INC_DEROT2, 0x55); ++ writereg(state, R367_OFDM_TRL_CTL, 0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1, 0xAE); ++ writereg(state, R367_OFDM_TRL_NOMRATE2, 0x56); ++ writereg(state, R367_OFDM_FEPATH_CFG, 0x0); ++ ++ // OFDM TS Setup ++ ++ writereg(state, R367_OFDM_TSCFGH, 0x70); ++ writereg(state, R367_OFDM_TSCFGM, 0xC0); ++ writereg(state, R367_OFDM_TSCFGL, 0x20); ++ writereg(state, R367_OFDM_TSSPEED, 0x40); // Fixed at 54 MHz ++ //writereg(state, R367_TSTBUS, 0x80); // Invert CLK ++ ++ writereg(state, R367_OFDM_TSCFGH, 0x71); ++ writereg(state, R367_OFDM_TSCFGH, 0x70); ++ ++ writereg(state, R367_TOPCTRL, 0x10); ++ ++ // Also needed for QAM ++ writereg(state, R367_OFDM_AGC12C, 0x01); // AGC Pin setup ++ ++ writereg(state, R367_OFDM_AGCCTRL1, 0x8A); // ++ ++ // QAM TS setup, note exact format also depends on descrambler settings ++ writereg(state, R367_QAM_OUTFORMAT_0, 0x85); // Inverted Clock, Swap, serial ++ // writereg(state, R367_QAM_OUTFORMAT_1, 0x00); // ++ ++ // Clock setup ++ writereg(state, R367_ANACTRL, 0x0D); /* PLL bypassed and disabled */ ++ ++ if( state->master_clock == 58000000 ) { ++ writereg(state, R367_PLLMDIV,27); /* IC runs at 58 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV,232); ++ } else { ++ writereg(state, R367_PLLMDIV,1); /* IC runs at 54 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV,8); ++ } ++ writereg(state, R367_PLLSETUP, 0x18); /* ADC clock is equal to system clock */ ++ ++ // Tuner setup ++ writereg(state, R367_ANADIGCTRL, 0x8b); /* Buffer Q disabled, I Enabled, signed ADC */ ++ writereg(state, R367_DUAL_AD12, 0x04); /* ADCQ disabled */ ++ ++ writereg(state, R367_QAM_FSM_SNR2_HTH, 0x23); /* Improves the C/N lock limit */ ++ writereg(state, R367_QAM_IQ_QAM, 0x01); /* ZIF/IF Automatic mode */ ++ writereg(state, R367_QAM_EQU_FFE_LEAKAGE, 0x83); /* Improving burst noise performances */ ++ writereg(state, R367_QAM_IQDEM_ADJ_EN, 0x05); /* Improving ACI performances */ ++ ++ writereg(state, R367_ANACTRL, 0x00); /* PLL enabled and used */ ++ ++ writereg(state, R367_I2CRPT, state->I2CRPT); ++ state->demod_state = QAMSet; ++ return stat; ++} ++ ++#ifdef USE_API3 ++static void c_release(struct dvb_frontend* fe) ++#else ++static void release(struct dvb_frontend* fe) ++#endif ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ printk("%s\n", __FUNCTION__); ++ kfree(state); ++} ++ ++#ifdef USE_API3 ++static int c_init (struct dvb_frontend *fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ ++ if (mutex_trylock(&state->ctlock)==0) ++ return -EBUSY; ++ state->omode = OM_DVBC; ++ return 0; ++} ++ ++static int c_sleep(struct dvb_frontend* fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ ++ mutex_unlock(&state->ctlock); ++ return 0; ++} ++#endif ++ ++static int gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u8 i2crpt = state->I2CRPT & ~0x80; ++ ++ if (enable) ++ i2crpt |= 0x80; ++ if (writereg(state, R367_I2CRPT, i2crpt) < 0) ++ return -1; ++ state->I2CRPT = i2crpt; ++ return 0; ++} ++ ++#if 0 ++static int c_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) ++{ ++ return DVBFE_ALGO_SEARCH_AGAIN; ++} ++#endif ++ ++#if 0 ++int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); ++int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); ++#endif ++ ++static int ofdm_lock(struct stv_state *state) ++{ ++ int status = 0; ++ u8 OFDM_Status; ++ s32 DemodTimeOut = 10; ++ s32 FECTimeOut = 0; ++ s32 TSTimeOut = 0; ++ u8 CPAMPMin = 255; ++ u8 CPAMPValue; ++ u8 SYR_STAT; ++ u8 FFTMode; ++ u8 TSStatus; ++ ++ msleep(state->m_SignalTimeOut); ++ readreg(state, R367_OFDM_STATUS,&OFDM_Status); ++ ++ if (!(OFDM_Status & 0x40)) ++ return -1; ++ //printk("lock 1\n"); ++ ++ readreg(state, R367_OFDM_SYR_STAT,&SYR_STAT); ++ FFTMode = (SYR_STAT & 0x0C) >> 2; ++ ++ switch(FFTMode) ++ { ++ case 0: // 2K ++ DemodTimeOut = 10; ++ FECTimeOut = 150; ++ TSTimeOut = 125; ++ CPAMPMin = 20; ++ break; ++ case 1: // 8K ++ DemodTimeOut = 55; ++ FECTimeOut = 600; ++ TSTimeOut = 500; ++ CPAMPMin = 80; ++ break; ++ case 2: // 4K ++ DemodTimeOut = 40; ++ FECTimeOut = 300; ++ TSTimeOut = 250; ++ CPAMPMin = 30; ++ break; ++ } ++ state->m_OFDM_FFTMode = FFTMode; ++ readreg(state, R367_OFDM_PPM_CPAMP_DIR,&CPAMPValue); ++ msleep(DemodTimeOut); ++ { ++ // Release FEC and Read Solomon Reset ++ u8 tmp1; ++ u8 tmp2; ++ readreg(state, R367_OFDM_SFDLYSETH,&tmp1); ++ readreg(state, R367_TSGENERAL,&tmp2); ++ writereg(state, R367_OFDM_SFDLYSETH,tmp1 & ~0x08); ++ writereg(state, R367_TSGENERAL,tmp2 & ~0x01); ++ } ++ msleep(FECTimeOut); ++ if( (OFDM_Status & 0x98) != 0x98 ) ++ ;//return -1; ++ //printk("lock 2\n"); ++ ++ { ++ u8 Guard = (SYR_STAT & 0x03); ++ if(Guard < 2) ++ { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp & ~0x04); // Clear AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp & ~0x10); // Clear SYR_FILTER ++ } else { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp | 0x04); // Set AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp | 0x10); // Set SYR_FILTER ++ } ++ ++ // apply Sfec workaround if 8K 64QAM CR!=1/2 ++ if( FFTMode == 1) ++ { ++ u8 tmp[2]; ++ readregs(state, R367_OFDM_TPS_RCVD2, tmp, 2); ++ if( ((tmp[0] & 0x03) == 0x02) && (( tmp[1] & 0x07 ) != 0) ) ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0xc0); ++ writereg(state, R367_OFDM_SFDLYSETM,0x60); ++ writereg(state, R367_OFDM_SFDLYSETL,0x00); ++ } ++ else ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0x00); ++ } ++ } ++ } ++ msleep(TSTimeOut); ++ readreg(state, R367_OFDM_TSSTATUS,&TSStatus); ++ if( (TSStatus & 0x80) != 0x80 ) ++ return -1; ++ //printk("lock 3\n"); ++ return status; ++} ++ ++ ++#ifdef USE_API3 ++static int set_parameters(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *p) ++{ ++ int stat; ++ struct stv_state *state = fe->demodulator_priv; ++ u32 OF = 0; ++ u32 IF; ++ ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe, p); ++ ++ switch (state->omode) { ++ case OM_DVBC: ++ case OM_QAM_ITU_C: ++ state->modulation = p->u.qam.modulation; ++ state->symbol_rate = p->u.qam.symbol_rate; ++ break; ++ case OM_DVBT: ++ switch (p->u.ofdm.bandwidth) { ++ case BANDWIDTH_AUTO: ++ case BANDWIDTH_8_MHZ: ++ state->bandwidth = 8000000; ++ break; ++ case BANDWIDTH_7_MHZ: ++ state->bandwidth = 7000000; ++ break; ++ case BANDWIDTH_6_MHZ: ++ state->bandwidth = 6000000; ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ default: ++ return -EINVAL; ++ } ++#else ++static int set_parameters(struct dvb_frontend *fe) ++{ ++ int stat; ++ struct stv_state *state = fe->demodulator_priv; ++ u32 OF = 0; ++ u32 IF; ++ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ state->omode = OM_DVBC; ++ /* symbol rate 0 might cause an oops */ ++ if (fe->dtv_property_cache.symbol_rate == 0) { ++ printk(KERN_ERR "stv0367dd: Invalid symbol rate\n"); ++ return -EINVAL; ++ } ++ break; ++ case SYS_DVBT: ++ state->omode = OM_DVBT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe); ++ state->modulation = fe->dtv_property_cache.modulation; ++ state->symbol_rate = fe->dtv_property_cache.symbol_rate; ++ state->bandwidth = fe->dtv_property_cache.bandwidth_hz; ++#endif ++ fe->ops.tuner_ops.get_if_frequency(fe, &IF); ++ //fe->ops.tuner_ops.get_frequency(fe, &IF); ++ ++ switch(state->omode) { ++ case OM_DVBT: ++ stat = OFDM_Start(state, OF, IF); ++ ofdm_lock(state); ++ break; ++ case OM_DVBC: ++ case OM_QAM_ITU_C: ++ stat = QAM_Start(state, OF, IF); ++ break; ++ default: ++ stat = -EINVAL; ++ } ++ //printk("%s IF=%d OF=%d done\n", __FUNCTION__, IF, OF); ++ return stat; ++} ++ ++#if 0 ++static int c_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) ++{ ++ //struct stv_state *state = fe->demodulator_priv; ++ //printk("%s\n", __FUNCTION__); ++ return 0; ++} ++ ++static int OFDM_GetLockStatus(struct stv_state *state, LOCK_STATUS* pLockStatus, s32 Time) ++{ ++ int status = STATUS_SUCCESS; ++ u8 OFDM_Status; ++ s32 DemodTimeOut = 0; ++ s32 FECTimeOut = 0; ++ s32 TSTimeOut = 0; ++ u8 CPAMPMin = 255; ++ u8 CPAMPValue; ++ bool SYRLock; ++ u8 SYR_STAT; ++ u8 FFTMode; ++ u8 TSStatus; ++ ++ readreg(state, R367_OFDM_STATUS,&OFDM_Status); ++ ++ SYRLock = (OFDM_Status & 0x40) != 0; ++ ++ if( Time > m_SignalTimeOut && !SYRLock ) ++ { ++ *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ ++ if( !SYRLock ) break; ++ ++ *pLockStatus = SIGNAL_PRESENT; ++ ++ // Check Mode ++ ++ readreg(state, R367_OFDM_SYR_STAT,&SYR_STAT); ++ FFTMode = (SYR_STAT & 0x0C) >> 2; ++ ++ switch(FFTMode) ++ { ++ case 0: // 2K ++ DemodTimeOut = 10; ++ FECTimeOut = 150; ++ TSTimeOut = 125; ++ CPAMPMin = 20; ++ break; ++ case 1: // 8K ++ DemodTimeOut = 55; ++ FECTimeOut = 600; ++ TSTimeOut = 500; ++ CPAMPMin = 80; ++ break; ++ case 2: // 4K ++ DemodTimeOut = 40; ++ FECTimeOut = 300; ++ TSTimeOut = 250; ++ CPAMPMin = 30; ++ break; ++ } ++ ++ m_OFDM_FFTMode = FFTMode; ++ ++ if( m_DemodTimeOut == 0 && m_bFirstTimeLock ) ++ { ++ m_DemodTimeOut = Time + DemodTimeOut; ++ //break; ++ } ++ ++ readreg(state, R367_OFDM_PPM_CPAMP_DIR,&CPAMPValue); ++ ++ if( Time <= m_DemodTimeOut && CPAMPValue < CPAMPMin ) ++ { ++ break; ++ } ++ ++ if( CPAMPValue < CPAMPMin && m_bFirstTimeLock ) ++ { ++ // initiate retry ++ *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ ++ if( CPAMPValue < CPAMPMin ) break; ++ ++ *pLockStatus = DEMOD_LOCK; ++ ++ if( m_FECTimeOut == 0 && m_bFirstTimeLock ) ++ { ++ // Release FEC and Read Solomon Reset ++ u8 tmp1; ++ u8 tmp2; ++ readreg(state, R367_OFDM_SFDLYSETH,&tmp1); ++ readreg(state, R367_TSGENERAL,&tmp2); ++ writereg(state, R367_OFDM_SFDLYSETH,tmp1 & ~0x08); ++ writereg(state, R367_TSGENERAL,tmp2 & ~0x01); ++ ++ m_FECTimeOut = Time + FECTimeOut; ++ } ++ ++ // Wait for TSP_LOCK, LK, PRF ++ if( (OFDM_Status & 0x98) != 0x98 ) ++ { ++ if( Time > m_FECTimeOut ) *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ ++ if( m_bFirstTimeLock && m_TSTimeOut == 0) ++ { ++ u8 Guard = (SYR_STAT & 0x03); ++ if(Guard < 2) ++ { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp & ~0x04); // Clear AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp & ~0x10); // Clear SYR_FILTER ++ } else { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp | 0x04); // Set AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp | 0x10); // Set SYR_FILTER ++ } ++ ++ // apply Sfec workaround if 8K 64QAM CR!=1/2 ++ if( FFTMode == 1) ++ { ++ u8 tmp[2]; ++ readreg(state, R367_OFDM_TPS_RCVD2,tmp,2); ++ if( ((tmp[0] & 0x03) == 0x02) && (( tmp[1] & 0x07 ) != 0) ) ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0xc0); ++ writereg(state, R367_OFDM_SFDLYSETM,0x60); ++ writereg(state, R367_OFDM_SFDLYSETL,0x00); ++ } ++ else ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0x00); ++ } ++ } ++ ++ m_TSTimeOut = Time + TSTimeOut; ++ } ++ readreg(state, R367_OFDM_TSSTATUS,&TSStatus); ++ if( (TSStatus & 0x80) != 0x80 ) ++ { ++ if( Time > m_TSTimeOut ) *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ *pLockStatus = MPEG_LOCK; ++ m_bFirstTimeLock = false; ++ return status; ++} ++ ++#endif ++ ++static int read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ *status=0; ++ ++ switch(state->demod_state) { ++ case QAMStarted: ++ { ++ u8 FEC_Lock; ++ u8 QAM_Lock; ++ ++ readreg(state, R367_QAM_FSM_STS, &QAM_Lock); ++ QAM_Lock &= 0x0F; ++ if (QAM_Lock >10) ++ *status|=0x07; ++ readreg(state, R367_QAM_FEC_STATUS,&FEC_Lock); ++ if (FEC_Lock&2) ++ *status|=0x1f; ++ if (state->m_bFirstTimeLock) { ++ state->m_bFirstTimeLock = false; ++ // QAM_AGC_ACCUMRSTSEL to Tracking; ++ writereg(state, R367_QAM_AGC_CTL, state->m_Save_QAM_AGC_CTL); ++ } ++ break; ++ } ++ case OFDMStarted: ++ { ++ u8 OFDM_Status; ++ u8 TSStatus; ++ ++ readreg(state, R367_OFDM_TSSTATUS, &TSStatus); ++ ++ readreg(state, R367_OFDM_STATUS, &OFDM_Status); ++ if (OFDM_Status & 0x40) ++ *status |= FE_HAS_SIGNAL; ++ ++ if ((OFDM_Status & 0x98) == 0x98) ++ *status|=0x0f; ++ ++ if (TSStatus & 0x80) ++ *status |= 0x1f; ++ break; ++ } ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int read_ber_ter(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u32 err; ++ u8 cnth, cntm, cntl; ++ ++#if 1 ++ readreg(state, R367_OFDM_SFERRCNTH, &cnth); ++ ++ if (cnth & 0x80) { ++ *ber = state->ber; ++ return 0; ++ } ++ ++ readreg(state, R367_OFDM_SFERRCNTM, &cntm); ++ readreg(state, R367_OFDM_SFERRCNTL, &cntl); ++ ++ err = ((cnth & 0x7f) << 16) | (cntm << 8) | cntl; ++ ++#if 0 ++ { ++ u64 err64; ++ err64 = (u64) err; ++ err64 *= 1000000000ULL; ++ err64 >>= 21; ++ err = err64; ++ } ++#endif ++#else ++ readreg(state, R367_OFDM_ERRCNT1HM, &cnth); ++ ++#endif ++ *ber = state->ber = err; ++ return 0; ++} ++ ++static int read_ber_cab(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u32 err; ++ u8 cntm, cntl, ctrl; ++ ++ readreg(state, R367_QAM_BERT_1, &ctrl); ++ if (!(ctrl & 0x20)) { ++ readreg(state, R367_QAM_BERT_2, &cntl); ++ readreg(state, R367_QAM_BERT_3, &cntm); ++ err = (cntm << 8) | cntl; ++ //printk("err %04x\n", err); ++ state->ber = err; ++ writereg(state, R367_QAM_BERT_1, 0x27); ++ } ++ *ber = (u32) state->ber; ++ return 0; ++} ++ ++static int read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ ++ if (state->demod_state == QAMStarted) ++ return read_ber_cab(fe, ber); ++ if (state->demod_state == OFDMStarted) ++ return read_ber_ter(fe, ber); ++ *ber = 0; ++ return 0; ++} ++ ++static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) ++{ ++ if (fe->ops.tuner_ops.get_rf_strength) ++ fe->ops.tuner_ops.get_rf_strength(fe, strength); ++ else ++ *strength = 0; ++ return 0; ++} ++ ++static int read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ s32 snr2 = 0; ++ ++ switch(state->demod_state) { ++ case QAMStarted: ++ QAM_GetSignalToNoise(state, &snr2); ++ break; ++ case OFDMStarted: ++ OFDM_GetSignalToNoise(state, &snr2); ++ break; ++ default: ++ break; ++ } ++ *snr = snr2&0xffff; ++ return 0; ++} ++ ++static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u8 errl, errm, errh; ++ u8 val; ++ ++ switch(state->demod_state) { ++ case QAMStarted: ++ readreg(state, R367_QAM_RS_COUNTER_4, &errl); ++ readreg(state, R367_QAM_RS_COUNTER_5, &errm); ++ *ucblocks = (errm << 8) | errl; ++ break; ++ case OFDMStarted: ++ readreg(state, R367_OFDM_SFERRCNTH, &val); ++ if ((val & 0x80) == 0) { ++ readreg(state, R367_OFDM_ERRCNT1H, &errh); ++ readreg(state, R367_OFDM_ERRCNT1M, &errl); ++ readreg(state, R367_OFDM_ERRCNT1L, &errm); ++ state->ucblocks = (errh <<16) | (errm << 8) | errl; ++ } ++ *ucblocks = state->ucblocks; ++ break; ++ default: ++ *ucblocks = 0; ++ break; ++ } ++ return 0; ++} ++ ++static int c_get_tune_settings(struct dvb_frontend *fe, ++ struct dvb_frontend_tune_settings *sets) ++{ ++ sets->min_delay_ms=3000; ++ sets->max_drift=0; ++ sets->step_size=0; ++ return 0; ++} ++ ++#ifndef USE_API3 ++static int get_tune_settings(struct dvb_frontend *fe, ++ struct dvb_frontend_tune_settings *sets) ++{ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ case SYS_DVBC_ANNEX_C: ++ return c_get_tune_settings(fe, sets); ++ default: ++ /* DVB-T: Use info.frequency_stepsize. */ ++ return -EINVAL; ++ } ++} ++#endif ++ ++#ifdef USE_API3 ++static void t_release(struct dvb_frontend* fe) ++{ ++ //struct stv_state *state=fe->demodulator_priv; ++ //printk("%s\n", __FUNCTION__); ++ //kfree(state); ++} ++ ++static int t_init (struct dvb_frontend *fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ if (mutex_trylock(&state->ctlock)==0) ++ return -EBUSY; ++ state->omode = OM_DVBT; ++ return 0; ++} ++ ++static int t_sleep(struct dvb_frontend* fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ mutex_unlock(&state->ctlock); ++ return 0; ++} ++#endif ++ ++#if 0 ++static int t_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) ++{ ++ //struct stv_state *state = fe->demodulator_priv; ++ //printk("%s\n", __FUNCTION__); ++ return 0; ++} ++ ++static enum dvbfe_algo algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_CUSTOM; ++} ++#endif ++ ++#ifdef USE_API3 ++static struct dvb_frontend_ops c_ops = { ++ .info = { ++ .name = "STV0367 DVB-C", ++ .type = FE_QAM, ++ .frequency_stepsize = 62500, ++ .frequency_min = 47000000, ++ .frequency_max = 862000000, ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO ++ }, ++ .release = c_release, ++ .init = c_init, ++ .sleep = c_sleep, ++ .i2c_gate_ctrl = gate_ctrl, ++ ++ .get_tune_settings = c_get_tune_settings, ++ ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++ ++#if 1 ++ .set_frontend = set_parameters, ++#else ++ .get_frontend_algo = algo, ++ .search = search, ++#endif ++}; ++ ++static struct dvb_frontend_ops t_ops = { ++ .info = { ++ .name = "STV0367 DVB-T", ++ .type = FE_OFDM, ++ .frequency_min = 47125000, ++ .frequency_max = 865000000, ++ .frequency_stepsize = 166667, ++ .frequency_tolerance = 0, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ .release = t_release, ++ .init = t_init, ++ .sleep = t_sleep, ++ .i2c_gate_ctrl = gate_ctrl, ++ ++ .set_frontend = set_parameters, ++ ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++}; ++ ++#else ++ ++static struct dvb_frontend_ops common_ops = { ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT }, ++ .info = { ++ .name = "STV0367 DVB-C DVB-T", ++ .frequency_stepsize = 166667, /* DVB-T only */ ++ .frequency_min = 47000000, /* DVB-T: 47125000 */ ++ .frequency_max = 865000000, /* DVB-C: 862000000 */ ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = /* DVB-C */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | ++ FE_CAN_FEC_AUTO | ++ /* DVB-T */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | ++ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ ++ .get_tune_settings = get_tune_settings, ++ ++ .set_frontend = set_parameters, ++ ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++}; ++#endif ++ ++ ++static void init_state(struct stv_state *state, struct stv0367_cfg *cfg) ++{ ++ u32 ulENARPTLEVEL = 5; ++ u32 ulQAMInversion = 2; ++ state->omode = OM_NONE; ++ state->adr = cfg->adr; ++ ++ mutex_init(&state->mutex); ++ mutex_init(&state->ctlock); ++ ++#ifdef USE_API3 ++ memcpy(&state->c_frontend.ops, &c_ops, sizeof(struct dvb_frontend_ops)); ++ memcpy(&state->t_frontend.ops, &t_ops, sizeof(struct dvb_frontend_ops)); ++ state->c_frontend.demodulator_priv = state; ++ state->t_frontend.demodulator_priv = state; ++#else ++ memcpy(&state->frontend.ops, &common_ops, sizeof(struct dvb_frontend_ops)); ++ state->frontend.demodulator_priv = state; ++#endif ++ ++ state->master_clock = 58000000; ++ state->adc_clock = 58000000; ++ state->I2CRPT = 0x08 | ((ulENARPTLEVEL & 0x07) << 4); ++ state->qam_inversion = ((ulQAMInversion & 3) << 6 ); ++ state->demod_state = Off; ++} ++ ++ ++struct dvb_frontend *stv0367_attach(struct i2c_adapter *i2c, struct stv0367_cfg *cfg, ++ struct dvb_frontend **fe_t) ++{ ++ struct stv_state *state = NULL; ++ ++ state = kzalloc(sizeof(struct stv_state), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ ++ state->i2c = i2c; ++ init_state(state, cfg); ++ ++ if (attach_init(state)<0) ++ goto error; ++#ifdef USE_API3 ++ *fe_t = &state->t_frontend; ++ return &state->c_frontend; ++#else ++ return &state->frontend; ++#endif ++ ++error: ++ printk("stv0367: not found\n"); ++ kfree(state); ++ return NULL; ++} ++ ++ ++MODULE_DESCRIPTION("STV0367DD driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); ++ ++EXPORT_SYMBOL(stv0367_attach); ++ ++ ++ +diff --git a/drivers/media/dvb-frontends/stv0367dd.h b/drivers/media/dvb-frontends/stv0367dd.h +new file mode 100644 +index 0000000..665d4c8 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0367dd.h +@@ -0,0 +1,17 @@ ++#ifndef _STV0367DD_H_ ++#define _STV0367DD_H_ ++ ++#include ++#include ++ ++struct stv0367_cfg { ++ u8 adr; ++ u32 xtal; ++ u32 ts_mode; ++}; ++ ++ ++extern struct dvb_frontend *stv0367_attach(struct i2c_adapter *i2c, ++ struct stv0367_cfg *cfg, ++ struct dvb_frontend **fe_t); ++#endif +diff --git a/drivers/media/dvb-frontends/stv0367dd_regs.h b/drivers/media/dvb-frontends/stv0367dd_regs.h +new file mode 100644 +index 0000000..eec0f57 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0367dd_regs.h +@@ -0,0 +1,3431 @@ ++// @DVB-C/DVB-T STMicroelectronics STV0367 register defintions ++// Author Manfred Völkel, Februar 2011 ++// (c) 2010 DigitalDevices GmbH Germany. All rights reserved ++ ++// $Id: DD_STV0367Register.h 357 2011-04-27 02:39:13Z manfred $ ++ ++/* ======================================================================= ++ -- Registers Declaration ++ -- ------------------------- ++ -- Each register (R367_XXXXX) is defined by its address (2 bytes). ++ -- ++ -- Each field (F367_XXXXX)is defined as follow: ++ -- [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte] ++ ======================================================================= */ ++ ++/* ID */ ++#define R367_ID 0xF000 ++#define F367_IDENTIFICATIONREG 0xF00000FF ++ ++/* I2CRPT */ ++#define R367_I2CRPT 0xF001 ++#define F367_I2CT_ON 0xF0010080 ++#define F367_ENARPT_LEVEL 0xF0010070 ++#define F367_SCLT_DELAY 0xF0010008 ++#define F367_SCLT_NOD 0xF0010004 ++#define F367_STOP_ENABLE 0xF0010002 ++#define F367_SDAT_NOD 0xF0010001 ++ ++/* TOPCTRL */ ++#define R367_TOPCTRL 0xF002 ++#define F367_STDBY 0xF0020080 ++#define F367_STDBY_FEC 0xF0020040 ++#define F367_STDBY_CORE 0xF0020020 ++#define F367_QAM_COFDM 0xF0020010 ++#define F367_TS_DIS 0xF0020008 ++#define F367_DIR_CLK_216 0xF0020004 ++#define F367_TUNER_BB 0xF0020002 ++#define F367_DVBT_H 0xF0020001 ++ ++/* IOCFG0 */ ++#define R367_IOCFG0 0xF003 ++#define F367_OP0_SD 0xF0030080 ++#define F367_OP0_VAL 0xF0030040 ++#define F367_OP0_OD 0xF0030020 ++#define F367_OP0_INV 0xF0030010 ++#define F367_OP0_DACVALUE_HI 0xF003000F ++ ++/* DAC0R */ ++#define R367_DAC0R 0xF004 ++#define F367_OP0_DACVALUE_LO 0xF00400FF ++ ++/* IOCFG1 */ ++#define R367_IOCFG1 0xF005 ++#define F367_IP0 0xF0050040 ++#define F367_OP1_OD 0xF0050020 ++#define F367_OP1_INV 0xF0050010 ++#define F367_OP1_DACVALUE_HI 0xF005000F ++ ++/* DAC1R */ ++#define R367_DAC1R 0xF006 ++#define F367_OP1_DACVALUE_LO 0xF00600FF ++ ++/* IOCFG2 */ ++#define R367_IOCFG2 0xF007 ++#define F367_OP2_LOCK_CONF 0xF00700E0 ++#define F367_OP2_OD 0xF0070010 ++#define F367_OP2_VAL 0xF0070008 ++#define F367_OP1_LOCK_CONF 0xF0070007 ++ ++/* SDFR */ ++#define R367_SDFR 0xF008 ++#define F367_OP0_FREQ 0xF00800F0 ++#define F367_OP1_FREQ 0xF008000F ++ ++/* STATUS */ ++#define R367_OFDM_STATUS 0xF009 ++#define F367_TPS_LOCK 0xF0090080 ++#define F367_SYR_LOCK 0xF0090040 ++#define F367_AGC_LOCK 0xF0090020 ++#define F367_PRF 0xF0090010 ++#define F367_LK 0xF0090008 ++#define F367_PR 0xF0090007 ++ ++/* AUX_CLK */ ++#define R367_AUX_CLK 0xF00A ++#define F367_AUXFEC_CTL 0xF00A00C0 ++#define F367_DIS_CKX4 0xF00A0020 ++#define F367_CKSEL 0xF00A0018 ++#define F367_CKDIV_PROG 0xF00A0006 ++#define F367_AUXCLK_ENA 0xF00A0001 ++ ++/* FREESYS1 */ ++#define R367_FREESYS1 0xF00B ++#define F367_FREE_SYS1 0xF00B00FF ++ ++/* FREESYS2 */ ++#define R367_FREESYS2 0xF00C ++#define F367_FREE_SYS2 0xF00C00FF ++ ++/* FREESYS3 */ ++#define R367_FREESYS3 0xF00D ++#define F367_FREE_SYS3 0xF00D00FF ++ ++/* GPIO_CFG */ ++#define R367_GPIO_CFG 0xF00E ++#define F367_GPIO7_NOD 0xF00E0080 ++#define F367_GPIO7_CFG 0xF00E0040 ++#define F367_GPIO6_NOD 0xF00E0020 ++#define F367_GPIO6_CFG 0xF00E0010 ++#define F367_GPIO5_NOD 0xF00E0008 ++#define F367_GPIO5_CFG 0xF00E0004 ++#define F367_GPIO4_NOD 0xF00E0002 ++#define F367_GPIO4_CFG 0xF00E0001 ++ ++/* GPIO_CMD */ ++#define R367_GPIO_CMD 0xF00F ++#define F367_GPIO7_VAL 0xF00F0008 ++#define F367_GPIO6_VAL 0xF00F0004 ++#define F367_GPIO5_VAL 0xF00F0002 ++#define F367_GPIO4_VAL 0xF00F0001 ++ ++/* AGC2MAX */ ++#define R367_OFDM_AGC2MAX 0xF010 ++#define F367_OFDM_AGC2_MAX 0xF01000FF ++ ++/* AGC2MIN */ ++#define R367_OFDM_AGC2MIN 0xF011 ++#define F367_OFDM_AGC2_MIN 0xF01100FF ++ ++/* AGC1MAX */ ++#define R367_OFDM_AGC1MAX 0xF012 ++#define F367_OFDM_AGC1_MAX 0xF01200FF ++ ++/* AGC1MIN */ ++#define R367_OFDM_AGC1MIN 0xF013 ++#define F367_OFDM_AGC1_MIN 0xF01300FF ++ ++/* AGCR */ ++#define R367_OFDM_AGCR 0xF014 ++#define F367_OFDM_RATIO_A 0xF01400E0 ++#define F367_OFDM_RATIO_B 0xF0140018 ++#define F367_OFDM_RATIO_C 0xF0140007 ++ ++/* AGC2TH */ ++#define R367_OFDM_AGC2TH 0xF015 ++#define F367_OFDM_AGC2_THRES 0xF01500FF ++ ++/* AGC12C */ ++#define R367_OFDM_AGC12C 0xF016 ++#define F367_OFDM_AGC1_IV 0xF0160080 ++#define F367_OFDM_AGC1_OD 0xF0160040 ++#define F367_OFDM_AGC1_LOAD 0xF0160020 ++#define F367_OFDM_AGC2_IV 0xF0160010 ++#define F367_OFDM_AGC2_OD 0xF0160008 ++#define F367_OFDM_AGC2_LOAD 0xF0160004 ++#define F367_OFDM_AGC12_MODE 0xF0160003 ++ ++/* AGCCTRL1 */ ++#define R367_OFDM_AGCCTRL1 0xF017 ++#define F367_OFDM_DAGC_ON 0xF0170080 ++#define F367_OFDM_INVERT_AGC12 0xF0170040 ++#define F367_OFDM_AGC1_MODE 0xF0170008 ++#define F367_OFDM_AGC2_MODE 0xF0170007 ++ ++/* AGCCTRL2 */ ++#define R367_OFDM_AGCCTRL2 0xF018 ++#define F367_OFDM_FRZ2_CTRL 0xF0180060 ++#define F367_OFDM_FRZ1_CTRL 0xF0180018 ++#define F367_OFDM_TIME_CST 0xF0180007 ++ ++/* AGC1VAL1 */ ++#define R367_OFDM_AGC1VAL1 0xF019 ++#define F367_OFDM_AGC1_VAL_LO 0xF01900FF ++ ++/* AGC1VAL2 */ ++#define R367_OFDM_AGC1VAL2 0xF01A ++#define F367_OFDM_AGC1_VAL_HI 0xF01A000F ++ ++/* AGC2VAL1 */ ++#define R367_OFDM_AGC2VAL1 0xF01B ++#define F367_OFDM_AGC2_VAL_LO 0xF01B00FF ++ ++/* AGC2VAL2 */ ++#define R367_OFDM_AGC2VAL2 0xF01C ++#define F367_OFDM_AGC2_VAL_HI 0xF01C000F ++ ++/* AGC2PGA */ ++#define R367_OFDM_AGC2PGA 0xF01D ++#define F367_OFDM_AGC2_PGA 0xF01D00FF ++ ++/* OVF_RATE1 */ ++#define R367_OFDM_OVF_RATE1 0xF01E ++#define F367_OFDM_OVF_RATE_HI 0xF01E000F ++ ++/* OVF_RATE2 */ ++#define R367_OFDM_OVF_RATE2 0xF01F ++#define F367_OFDM_OVF_RATE_LO 0xF01F00FF ++ ++/* GAIN_SRC1 */ ++#define R367_OFDM_GAIN_SRC1 0xF020 ++#define F367_OFDM_INV_SPECTR 0xF0200080 ++#define F367_OFDM_IQ_INVERT 0xF0200040 ++#define F367_OFDM_INR_BYPASS 0xF0200020 ++#define F367_OFDM_STATUS_INV_SPECRUM 0xF0200010 ++#define F367_OFDM_GAIN_SRC_HI 0xF020000F ++ ++/* GAIN_SRC2 */ ++#define R367_OFDM_GAIN_SRC2 0xF021 ++#define F367_OFDM_GAIN_SRC_LO 0xF02100FF ++ ++/* INC_DEROT1 */ ++#define R367_OFDM_INC_DEROT1 0xF022 ++#define F367_OFDM_INC_DEROT_HI 0xF02200FF ++ ++/* INC_DEROT2 */ ++#define R367_OFDM_INC_DEROT2 0xF023 ++#define F367_OFDM_INC_DEROT_LO 0xF02300FF ++ ++/* PPM_CPAMP_DIR */ ++#define R367_OFDM_PPM_CPAMP_DIR 0xF024 ++#define F367_OFDM_PPM_CPAMP_DIRECT 0xF02400FF ++ ++/* PPM_CPAMP_INV */ ++#define R367_OFDM_PPM_CPAMP_INV 0xF025 ++#define F367_OFDM_PPM_CPAMP_INVER 0xF02500FF ++ ++/* FREESTFE_1 */ ++#define R367_OFDM_FREESTFE_1 0xF026 ++#define F367_OFDM_SYMBOL_NUMBER_INC 0xF02600C0 ++#define F367_OFDM_SEL_LSB 0xF0260004 ++#define F367_OFDM_AVERAGE_ON 0xF0260002 ++#define F367_OFDM_DC_ADJ 0xF0260001 ++ ++/* FREESTFE_2 */ ++#define R367_OFDM_FREESTFE_2 0xF027 ++#define F367_OFDM_SEL_SRCOUT 0xF02700C0 ++#define F367_OFDM_SEL_SYRTHR 0xF027001F ++ ++/* DCOFFSET */ ++#define R367_OFDM_DCOFFSET 0xF028 ++#define F367_OFDM_SELECT_I_Q 0xF0280080 ++#define F367_OFDM_DC_OFFSET 0xF028007F ++ ++/* EN_PROCESS */ ++#define R367_OFDM_EN_PROCESS 0xF029 ++#define F367_OFDM_FREE 0xF02900F0 ++#define F367_OFDM_ENAB_MANUAL 0xF0290001 ++ ++/* SDI_SMOOTHER */ ++#define R367_OFDM_SDI_SMOOTHER 0xF02A ++#define F367_OFDM_DIS_SMOOTH 0xF02A0080 ++#define F367_OFDM_SDI_INC_SMOOTHER 0xF02A007F ++ ++/* FE_LOOP_OPEN */ ++#define R367_OFDM_FE_LOOP_OPEN 0xF02B ++#define F367_OFDM_TRL_LOOP_OP 0xF02B0002 ++#define F367_OFDM_CRL_LOOP_OP 0xF02B0001 ++ ++/* FREQOFF1 */ ++#define R367_OFDM_FREQOFF1 0xF02C ++#define F367_OFDM_FREQ_OFFSET_LOOP_OPEN_VHI 0xF02C00FF ++ ++/* FREQOFF2 */ ++#define R367_OFDM_FREQOFF2 0xF02D ++#define F367_OFDM_FREQ_OFFSET_LOOP_OPEN_HI 0xF02D00FF ++ ++/* FREQOFF3 */ ++#define R367_OFDM_FREQOFF3 0xF02E ++#define F367_OFDM_FREQ_OFFSET_LOOP_OPEN_LO 0xF02E00FF ++ ++/* TIMOFF1 */ ++#define R367_OFDM_TIMOFF1 0xF02F ++#define F367_OFDM_TIM_OFFSET_LOOP_OPEN_HI 0xF02F00FF ++ ++/* TIMOFF2 */ ++#define R367_OFDM_TIMOFF2 0xF030 ++#define F367_OFDM_TIM_OFFSET_LOOP_OPEN_LO 0xF03000FF ++ ++/* EPQ */ ++#define R367_OFDM_EPQ 0xF031 ++#define F367_OFDM_EPQ1 0xF03100FF ++ ++/* EPQAUTO */ ++#define R367_OFDM_EPQAUTO 0xF032 ++#define F367_OFDM_EPQ2 0xF03200FF ++ ++/* SYR_UPDATE */ ++#define R367_OFDM_SYR_UPDATE 0xF033 ++#define F367_OFDM_SYR_PROTV 0xF0330080 ++#define F367_OFDM_SYR_PROTV_GAIN 0xF0330060 ++#define F367_OFDM_SYR_FILTER 0xF0330010 ++#define F367_OFDM_SYR_TRACK_THRES 0xF033000C ++ ++/* CHPFREE */ ++#define R367_OFDM_CHPFREE 0xF034 ++#define F367_OFDM_CHP_FREE 0xF03400FF ++ ++/* PPM_STATE_MAC */ ++#define R367_OFDM_PPM_STATE_MAC 0xF035 ++#define F367_OFDM_PPM_STATE_MACHINE_DECODER 0xF035003F ++ ++/* INR_THRESHOLD */ ++#define R367_OFDM_INR_THRESHOLD 0xF036 ++#define F367_OFDM_INR_THRESH 0xF03600FF ++ ++/* EPQ_TPS_ID_CELL */ ++#define R367_OFDM_EPQ_TPS_ID_CELL 0xF037 ++#define F367_OFDM_ENABLE_LGTH_TO_CF 0xF0370080 ++#define F367_OFDM_DIS_TPS_RSVD 0xF0370040 ++#define F367_OFDM_DIS_BCH 0xF0370020 ++#define F367_OFDM_DIS_ID_CEL 0xF0370010 ++#define F367_OFDM_TPS_ADJUST_SYM 0xF037000F ++ ++/* EPQ_CFG */ ++#define R367_OFDM_EPQ_CFG 0xF038 ++#define F367_OFDM_EPQ_RANGE 0xF0380002 ++#define F367_OFDM_EPQ_SOFT 0xF0380001 ++ ++/* EPQ_STATUS */ ++#define R367_OFDM_EPQ_STATUS 0xF039 ++#define F367_OFDM_SLOPE_INC 0xF03900FC ++#define F367_OFDM_TPS_FIELD 0xF0390003 ++ ++/* AUTORELOCK */ ++#define R367_OFDM_AUTORELOCK 0xF03A ++#define F367_OFDM_BYPASS_BER_TEMPO 0xF03A0080 ++#define F367_OFDM_BER_TEMPO 0xF03A0070 ++#define F367_OFDM_BYPASS_COFDM_TEMPO 0xF03A0008 ++#define F367_OFDM_COFDM_TEMPO 0xF03A0007 ++ ++/* BER_THR_VMSB */ ++#define R367_OFDM_BER_THR_VMSB 0xF03B ++#define F367_OFDM_BER_THRESHOLD_HI 0xF03B00FF ++ ++/* BER_THR_MSB */ ++#define R367_OFDM_BER_THR_MSB 0xF03C ++#define F367_OFDM_BER_THRESHOLD_MID 0xF03C00FF ++ ++/* BER_THR_LSB */ ++#define R367_OFDM_BER_THR_LSB 0xF03D ++#define F367_OFDM_BER_THRESHOLD_LO 0xF03D00FF ++ ++/* CCD */ ++#define R367_OFDM_CCD 0xF03E ++#define F367_OFDM_CCD_DETECTED 0xF03E0080 ++#define F367_OFDM_CCD_RESET 0xF03E0040 ++#define F367_OFDM_CCD_THRESHOLD 0xF03E000F ++ ++/* SPECTR_CFG */ ++#define R367_OFDM_SPECTR_CFG 0xF03F ++#define F367_OFDM_SPECT_CFG 0xF03F0003 ++ ++/* CONSTMU_MSB */ ++#define R367_OFDM_CONSTMU_MSB 0xF040 ++#define F367_OFDM_CONSTMU_FREEZE 0xF0400080 ++#define F367_OFDM_CONSTNU_FORCE_EN 0xF0400040 ++#define F367_OFDM_CONST_MU_MSB 0xF040003F ++ ++/* CONSTMU_LSB */ ++#define R367_OFDM_CONSTMU_LSB 0xF041 ++#define F367_OFDM_CONST_MU_LSB 0xF04100FF ++ ++/* CONSTMU_MAX_MSB */ ++#define R367_OFDM_CONSTMU_MAX_MSB 0xF042 ++#define F367_OFDM_CONST_MU_MAX_MSB 0xF042003F ++ ++/* CONSTMU_MAX_LSB */ ++#define R367_OFDM_CONSTMU_MAX_LSB 0xF043 ++#define F367_OFDM_CONST_MU_MAX_LSB 0xF04300FF ++ ++/* ALPHANOISE */ ++#define R367_OFDM_ALPHANOISE 0xF044 ++#define F367_OFDM_USE_ALLFILTER 0xF0440080 ++#define F367_OFDM_INTER_ON 0xF0440040 ++#define F367_OFDM_ALPHA_NOISE 0xF044001F ++ ++/* MAXGP_MSB */ ++#define R367_OFDM_MAXGP_MSB 0xF045 ++#define F367_OFDM_MUFILTER_LENGTH 0xF04500F0 ++#define F367_OFDM_MAX_GP_MSB 0xF045000F ++ ++/* MAXGP_LSB */ ++#define R367_OFDM_MAXGP_LSB 0xF046 ++#define F367_OFDM_MAX_GP_LSB 0xF04600FF ++ ++/* ALPHAMSB */ ++#define R367_OFDM_ALPHAMSB 0xF047 ++#define F367_OFDM_CHC_DATARATE 0xF04700C0 ++#define F367_OFDM_ALPHA_MSB 0xF047003F ++ ++/* ALPHALSB */ ++#define R367_OFDM_ALPHALSB 0xF048 ++#define F367_OFDM_ALPHA_LSB 0xF04800FF ++ ++/* PILOT_ACCU */ ++#define R367_OFDM_PILOT_ACCU 0xF049 ++#define F367_OFDM_USE_SCAT4ADDAPT 0xF0490080 ++#define F367_OFDM_PILOT_ACC 0xF049001F ++ ++/* PILOTMU_ACCU */ ++#define R367_OFDM_PILOTMU_ACCU 0xF04A ++#define F367_OFDM_DISCARD_BAD_SP 0xF04A0080 ++#define F367_OFDM_DISCARD_BAD_CP 0xF04A0040 ++#define F367_OFDM_PILOT_MU_ACCU 0xF04A001F ++ ++/* FILT_CHANNEL_EST */ ++#define R367_OFDM_FILT_CHANNEL_EST 0xF04B ++#define F367_OFDM_USE_FILT_PILOT 0xF04B0080 ++#define F367_OFDM_FILT_CHANNEL 0xF04B007F ++ ++/* ALPHA_NOPISE_FREQ */ ++#define R367_OFDM_ALPHA_NOPISE_FREQ 0xF04C ++#define F367_OFDM_NOISE_FREQ_FILT 0xF04C0040 ++#define F367_OFDM_ALPHA_NOISE_FREQ 0xF04C003F ++ ++/* RATIO_PILOT */ ++#define R367_OFDM_RATIO_PILOT 0xF04D ++#define F367_OFDM_RATIO_MEAN_SP 0xF04D00F0 ++#define F367_OFDM_RATIO_MEAN_CP 0xF04D000F ++ ++/* CHC_CTL */ ++#define R367_OFDM_CHC_CTL 0xF04E ++#define F367_OFDM_TRACK_EN 0xF04E0080 ++#define F367_OFDM_NOISE_NORM_EN 0xF04E0040 ++#define F367_OFDM_FORCE_CHC_RESET 0xF04E0020 ++#define F367_OFDM_SHORT_TIME 0xF04E0010 ++#define F367_OFDM_FORCE_STATE_EN 0xF04E0008 ++#define F367_OFDM_FORCE_STATE 0xF04E0007 ++ ++/* EPQ_ADJUST */ ++#define R367_OFDM_EPQ_ADJUST 0xF04F ++#define F367_OFDM_ADJUST_SCAT_IND 0xF04F00C0 ++#define F367_OFDM_ONE_SYMBOL 0xF04F0010 ++#define F367_OFDM_EPQ_DECAY 0xF04F000E ++#define F367_OFDM_HOLD_SLOPE 0xF04F0001 ++ ++/* EPQ_THRES */ ++#define R367_OFDM_EPQ_THRES 0xF050 ++#define F367_OFDM_EPQ_THR 0xF05000FF ++ ++/* OMEGA_CTL */ ++#define R367_OFDM_OMEGA_CTL 0xF051 ++#define F367_OFDM_OMEGA_RST 0xF0510080 ++#define F367_OFDM_FREEZE_OMEGA 0xF0510040 ++#define F367_OFDM_OMEGA_SEL 0xF051003F ++ ++/* GP_CTL */ ++#define R367_OFDM_GP_CTL 0xF052 ++#define F367_OFDM_CHC_STATE 0xF05200E0 ++#define F367_OFDM_FREEZE_GP 0xF0520010 ++#define F367_OFDM_GP_SEL 0xF052000F ++ ++/* MUMSB */ ++#define R367_OFDM_MUMSB 0xF053 ++#define F367_OFDM_MU_MSB 0xF053007F ++ ++/* MULSB */ ++#define R367_OFDM_MULSB 0xF054 ++#define F367_OFDM_MU_LSB 0xF05400FF ++ ++/* GPMSB */ ++#define R367_OFDM_GPMSB 0xF055 ++#define F367_OFDM_CSI_THRESHOLD 0xF05500E0 ++#define F367_OFDM_GP_MSB 0xF055000F ++ ++/* GPLSB */ ++#define R367_OFDM_GPLSB 0xF056 ++#define F367_OFDM_GP_LSB 0xF05600FF ++ ++/* OMEGAMSB */ ++#define R367_OFDM_OMEGAMSB 0xF057 ++#define F367_OFDM_OMEGA_MSB 0xF057007F ++ ++/* OMEGALSB */ ++#define R367_OFDM_OMEGALSB 0xF058 ++#define F367_OFDM_OMEGA_LSB 0xF05800FF ++ ++/* SCAT_NB */ ++#define R367_OFDM_SCAT_NB 0xF059 ++#define F367_OFDM_CHC_TEST 0xF05900F8 ++#define F367_OFDM_SCAT_NUMB 0xF0590003 ++ ++/* CHC_DUMMY */ ++#define R367_OFDM_CHC_DUMMY 0xF05A ++#define F367_OFDM_CHC_DUM 0xF05A00FF ++ ++/* INC_CTL */ ++#define R367_OFDM_INC_CTL 0xF05B ++#define F367_OFDM_INC_BYPASS 0xF05B0080 ++#define F367_OFDM_INC_NDEPTH 0xF05B000C ++#define F367_OFDM_INC_MADEPTH 0xF05B0003 ++ ++/* INCTHRES_COR1 */ ++#define R367_OFDM_INCTHRES_COR1 0xF05C ++#define F367_OFDM_INC_THRES_COR1 0xF05C00FF ++ ++/* INCTHRES_COR2 */ ++#define R367_OFDM_INCTHRES_COR2 0xF05D ++#define F367_OFDM_INC_THRES_COR2 0xF05D00FF ++ ++/* INCTHRES_DET1 */ ++#define R367_OFDM_INCTHRES_DET1 0xF05E ++#define F367_OFDM_INC_THRES_DET1 0xF05E003F ++ ++/* INCTHRES_DET2 */ ++#define R367_OFDM_INCTHRES_DET2 0xF05F ++#define F367_OFDM_INC_THRES_DET2 0xF05F003F ++ ++/* IIR_CELLNB */ ++#define R367_OFDM_IIR_CELLNB 0xF060 ++#define F367_OFDM_NRST_IIR 0xF0600080 ++#define F367_OFDM_IIR_CELL_NB 0xF0600007 ++ ++/* IIRCX_COEFF1_MSB */ ++#define R367_OFDM_IIRCX_COEFF1_MSB 0xF061 ++#define F367_OFDM_IIR_CX_COEFF1_MSB 0xF06100FF ++ ++/* IIRCX_COEFF1_LSB */ ++#define R367_OFDM_IIRCX_COEFF1_LSB 0xF062 ++#define F367_OFDM_IIR_CX_COEFF1_LSB 0xF06200FF ++ ++/* IIRCX_COEFF2_MSB */ ++#define R367_OFDM_IIRCX_COEFF2_MSB 0xF063 ++#define F367_OFDM_IIR_CX_COEFF2_MSB 0xF06300FF ++ ++/* IIRCX_COEFF2_LSB */ ++#define R367_OFDM_IIRCX_COEFF2_LSB 0xF064 ++#define F367_OFDM_IIR_CX_COEFF2_LSB 0xF06400FF ++ ++/* IIRCX_COEFF3_MSB */ ++#define R367_OFDM_IIRCX_COEFF3_MSB 0xF065 ++#define F367_OFDM_IIR_CX_COEFF3_MSB 0xF06500FF ++ ++/* IIRCX_COEFF3_LSB */ ++#define R367_OFDM_IIRCX_COEFF3_LSB 0xF066 ++#define F367_OFDM_IIR_CX_COEFF3_LSB 0xF06600FF ++ ++/* IIRCX_COEFF4_MSB */ ++#define R367_OFDM_IIRCX_COEFF4_MSB 0xF067 ++#define F367_OFDM_IIR_CX_COEFF4_MSB 0xF06700FF ++ ++/* IIRCX_COEFF4_LSB */ ++#define R367_OFDM_IIRCX_COEFF4_LSB 0xF068 ++#define F367_OFDM_IIR_CX_COEFF4_LSB 0xF06800FF ++ ++/* IIRCX_COEFF5_MSB */ ++#define R367_OFDM_IIRCX_COEFF5_MSB 0xF069 ++#define F367_OFDM_IIR_CX_COEFF5_MSB 0xF06900FF ++ ++/* IIRCX_COEFF5_LSB */ ++#define R367_OFDM_IIRCX_COEFF5_LSB 0xF06A ++#define F367_OFDM_IIR_CX_COEFF5_LSB 0xF06A00FF ++ ++/* FEPATH_CFG */ ++#define R367_OFDM_FEPATH_CFG 0xF06B ++#define F367_OFDM_DEMUX_SWAP 0xF06B0004 ++#define F367_OFDM_DIGAGC_SWAP 0xF06B0002 ++#define F367_OFDM_LONGPATH_IF 0xF06B0001 ++ ++/* PMC1_FUNC */ ++#define R367_OFDM_PMC1_FUNC 0xF06C ++#define F367_OFDM_SOFT_RSTN 0xF06C0080 ++#define F367_OFDM_PMC1_AVERAGE_TIME 0xF06C0078 ++#define F367_OFDM_PMC1_WAIT_TIME 0xF06C0006 ++#define F367_OFDM_PMC1_2N_SEL 0xF06C0001 ++ ++/* PMC1_FOR */ ++#define R367_OFDM_PMC1_FOR 0xF06D ++#define F367_OFDM_PMC1_FORCE 0xF06D0080 ++#define F367_OFDM_PMC1_FORCE_VALUE 0xF06D007C ++ ++/* PMC2_FUNC */ ++#define R367_OFDM_PMC2_FUNC 0xF06E ++#define F367_OFDM_PMC2_SOFT_STN 0xF06E0080 ++#define F367_OFDM_PMC2_ACCU_TIME 0xF06E0070 ++#define F367_OFDM_PMC2_CMDP_MN 0xF06E0008 ++#define F367_OFDM_PMC2_SWAP 0xF06E0004 ++ ++/* STATUS_ERR_DA */ ++#define R367_OFDM_STATUS_ERR_DA 0xF06F ++#define F367_OFDM_COM_USEGAINTRK 0xF06F0080 ++#define F367_OFDM_COM_AGCLOCK 0xF06F0040 ++#define F367_OFDM_AUT_AGCLOCK 0xF06F0020 ++#define F367_OFDM_MIN_ERR_X_LSB 0xF06F000F ++ ++/* DIG_AGC_R */ ++#define R367_OFDM_DIG_AGC_R 0xF070 ++#define F367_OFDM_COM_SOFT_RSTN 0xF0700080 ++#define F367_OFDM_COM_AGC_ON 0xF0700040 ++#define F367_OFDM_COM_EARLY 0xF0700020 ++#define F367_OFDM_AUT_SOFT_RESETN 0xF0700010 ++#define F367_OFDM_AUT_AGC_ON 0xF0700008 ++#define F367_OFDM_AUT_EARLY 0xF0700004 ++#define F367_OFDM_AUT_ROT_EN 0xF0700002 ++#define F367_OFDM_LOCK_SOFT_RESETN 0xF0700001 ++ ++/* COMAGC_TARMSB */ ++#define R367_OFDM_COMAGC_TARMSB 0xF071 ++#define F367_OFDM_COM_AGC_TARGET_MSB 0xF07100FF ++ ++/* COM_AGC_TAR_ENMODE */ ++#define R367_OFDM_COM_AGC_TAR_ENMODE 0xF072 ++#define F367_OFDM_COM_AGC_TARGET_LSB 0xF07200F0 ++#define F367_OFDM_COM_ENMODE 0xF072000F ++ ++/* COM_AGC_CFG */ ++#define R367_OFDM_COM_AGC_CFG 0xF073 ++#define F367_OFDM_COM_N 0xF07300F8 ++#define F367_OFDM_COM_STABMODE 0xF0730006 ++#define F367_OFDM_ERR_SEL 0xF0730001 ++ ++/* COM_AGC_GAIN1 */ ++#define R367_OFDM_COM_AGC_GAIN1 0xF074 ++#define F367_OFDM_COM_GAIN1ACK 0xF07400F0 ++#define F367_OFDM_COM_GAIN1TRK 0xF074000F ++ ++/* AUT_AGC_TARGETMSB */ ++#define R367_OFDM_AUT_AGC_TARGETMSB 0xF075 ++#define F367_OFDM_AUT_AGC_TARGET_MSB 0xF07500FF ++ ++/* LOCK_DET_MSB */ ++#define R367_OFDM_LOCK_DET_MSB 0xF076 ++#define F367_OFDM_LOCK_DETECT_MSB 0xF07600FF ++ ++/* AGCTAR_LOCK_LSBS */ ++#define R367_OFDM_AGCTAR_LOCK_LSBS 0xF077 ++#define F367_OFDM_AUT_AGC_TARGET_LSB 0xF07700F0 ++#define F367_OFDM_LOCK_DETECT_LSB 0xF077000F ++ ++/* AUT_GAIN_EN */ ++#define R367_OFDM_AUT_GAIN_EN 0xF078 ++#define F367_OFDM_AUT_ENMODE 0xF07800F0 ++#define F367_OFDM_AUT_GAIN2 0xF078000F ++ ++/* AUT_CFG */ ++#define R367_OFDM_AUT_CFG 0xF079 ++#define F367_OFDM_AUT_N 0xF07900F8 ++#define F367_OFDM_INT_CHOICE 0xF0790006 ++#define F367_OFDM_INT_LOAD 0xF0790001 ++ ++/* LOCKN */ ++#define R367_OFDM_LOCKN 0xF07A ++#define F367_OFDM_LOCK_N 0xF07A00F8 ++#define F367_OFDM_SEL_IQNTAR 0xF07A0004 ++#define F367_OFDM_LOCK_DETECT_CHOICE 0xF07A0003 ++ ++/* INT_X_3 */ ++#define R367_OFDM_INT_X_3 0xF07B ++#define F367_OFDM_INT_X3 0xF07B00FF ++ ++/* INT_X_2 */ ++#define R367_OFDM_INT_X_2 0xF07C ++#define F367_OFDM_INT_X2 0xF07C00FF ++ ++/* INT_X_1 */ ++#define R367_OFDM_INT_X_1 0xF07D ++#define F367_OFDM_INT_X1 0xF07D00FF ++ ++/* INT_X_0 */ ++#define R367_OFDM_INT_X_0 0xF07E ++#define F367_OFDM_INT_X0 0xF07E00FF ++ ++/* MIN_ERRX_MSB */ ++#define R367_OFDM_MIN_ERRX_MSB 0xF07F ++#define F367_OFDM_MIN_ERR_X_MSB 0xF07F00FF ++ ++/* COR_CTL */ ++#define R367_OFDM_COR_CTL 0xF080 ++#define F367_OFDM_CORE_ACTIVE 0xF0800020 ++#define F367_OFDM_HOLD 0xF0800010 ++#define F367_OFDM_CORE_STATE_CTL 0xF080000F ++ ++/* COR_STAT */ ++#define R367_OFDM_COR_STAT 0xF081 ++#define F367_OFDM_SCATT_LOCKED 0xF0810080 ++#define F367_OFDM_TPS_LOCKED 0xF0810040 ++#define F367_OFDM_SYR_LOCKED_COR 0xF0810020 ++#define F367_OFDM_AGC_LOCKED_STAT 0xF0810010 ++#define F367_OFDM_CORE_STATE_STAT 0xF081000F ++ ++/* COR_INTEN */ ++#define R367_OFDM_COR_INTEN 0xF082 ++#define F367_OFDM_INTEN 0xF0820080 ++#define F367_OFDM_INTEN_SYR 0xF0820020 ++#define F367_OFDM_INTEN_FFT 0xF0820010 ++#define F367_OFDM_INTEN_AGC 0xF0820008 ++#define F367_OFDM_INTEN_TPS1 0xF0820004 ++#define F367_OFDM_INTEN_TPS2 0xF0820002 ++#define F367_OFDM_INTEN_TPS3 0xF0820001 ++ ++/* COR_INTSTAT */ ++#define R367_OFDM_COR_INTSTAT 0xF083 ++#define F367_OFDM_INTSTAT_SYR 0xF0830020 ++#define F367_OFDM_INTSTAT_FFT 0xF0830010 ++#define F367_OFDM_INTSAT_AGC 0xF0830008 ++#define F367_OFDM_INTSTAT_TPS1 0xF0830004 ++#define F367_OFDM_INTSTAT_TPS2 0xF0830002 ++#define F367_OFDM_INTSTAT_TPS3 0xF0830001 ++ ++/* COR_MODEGUARD */ ++#define R367_OFDM_COR_MODEGUARD 0xF084 ++#define F367_OFDM_FORCE 0xF0840010 ++#define F367_OFDM_MODE 0xF084000C ++#define F367_OFDM_GUARD 0xF0840003 ++ ++/* AGC_CTL */ ++#define R367_OFDM_AGC_CTL 0xF085 ++#define F367_OFDM_AGC_TIMING_FACTOR 0xF08500E0 ++#define F367_OFDM_AGC_LAST 0xF0850010 ++#define F367_OFDM_AGC_GAIN 0xF085000C ++#define F367_OFDM_AGC_NEG 0xF0850002 ++#define F367_OFDM_AGC_SET 0xF0850001 ++ ++/* AGC_MANUAL1 */ ++#define R367_OFDM_AGC_MANUAL1 0xF086 ++#define F367_OFDM_AGC_VAL_LO 0xF08600FF ++ ++/* AGC_MANUAL2 */ ++#define R367_OFDM_AGC_MANUAL2 0xF087 ++#define F367_OFDM_AGC_VAL_HI 0xF087000F ++ ++/* AGC_TARG */ ++#define R367_OFDM_AGC_TARG 0xF088 ++#define F367_OFDM_AGC_TARGET 0xF08800FF ++ ++/* AGC_GAIN1 */ ++#define R367_OFDM_AGC_GAIN1 0xF089 ++#define F367_OFDM_AGC_GAIN_LO 0xF08900FF ++ ++/* AGC_GAIN2 */ ++#define R367_OFDM_AGC_GAIN2 0xF08A ++#define F367_OFDM_AGC_LOCKED_GAIN2 0xF08A0010 ++#define F367_OFDM_AGC_GAIN_HI 0xF08A000F ++ ++/* RESERVED_1 */ ++#define R367_OFDM_RESERVED_1 0xF08B ++#define F367_OFDM_RESERVED1 0xF08B00FF ++ ++/* RESERVED_2 */ ++#define R367_OFDM_RESERVED_2 0xF08C ++#define F367_OFDM_RESERVED2 0xF08C00FF ++ ++/* RESERVED_3 */ ++#define R367_OFDM_RESERVED_3 0xF08D ++#define F367_OFDM_RESERVED3 0xF08D00FF ++ ++/* CAS_CTL */ ++#define R367_OFDM_CAS_CTL 0xF08E ++#define F367_OFDM_CCS_ENABLE 0xF08E0080 ++#define F367_OFDM_ACS_DISABLE 0xF08E0040 ++#define F367_OFDM_DAGC_DIS 0xF08E0020 ++#define F367_OFDM_DAGC_GAIN 0xF08E0018 ++#define F367_OFDM_CCSMU 0xF08E0007 ++ ++/* CAS_FREQ */ ++#define R367_OFDM_CAS_FREQ 0xF08F ++#define F367_OFDM_CCS_FREQ 0xF08F00FF ++ ++/* CAS_DAGCGAIN */ ++#define R367_OFDM_CAS_DAGCGAIN 0xF090 ++#define F367_OFDM_CAS_DAGC_GAIN 0xF09000FF ++ ++/* SYR_CTL */ ++#define R367_OFDM_SYR_CTL 0xF091 ++#define F367_OFDM_SICTH_ENABLE 0xF0910080 ++#define F367_OFDM_LONG_ECHO 0xF0910078 ++#define F367_OFDM_AUTO_LE_EN 0xF0910004 ++#define F367_OFDM_SYR_BYPASS 0xF0910002 ++#define F367_OFDM_SYR_TR_DIS 0xF0910001 ++ ++/* SYR_STAT */ ++#define R367_OFDM_SYR_STAT 0xF092 ++#define F367_OFDM_SYR_LOCKED_STAT 0xF0920010 ++#define F367_OFDM_SYR_MODE 0xF092000C ++#define F367_OFDM_SYR_GUARD 0xF0920003 ++ ++/* SYR_NCO1 */ ++#define R367_OFDM_SYR_NCO1 0xF093 ++#define F367_OFDM_SYR_NCO_LO 0xF09300FF ++ ++/* SYR_NCO2 */ ++#define R367_OFDM_SYR_NCO2 0xF094 ++#define F367_OFDM_SYR_NCO_HI 0xF094003F ++ ++/* SYR_OFFSET1 */ ++#define R367_OFDM_SYR_OFFSET1 0xF095 ++#define F367_OFDM_SYR_OFFSET_LO 0xF09500FF ++ ++/* SYR_OFFSET2 */ ++#define R367_OFDM_SYR_OFFSET2 0xF096 ++#define F367_OFDM_SYR_OFFSET_HI 0xF096003F ++ ++/* FFT_CTL */ ++#define R367_OFDM_FFT_CTL 0xF097 ++#define F367_OFDM_SHIFT_FFT_TRIG 0xF0970018 ++#define F367_OFDM_FFT_TRIGGER 0xF0970004 ++#define F367_OFDM_FFT_MANUAL 0xF0970002 ++#define F367_OFDM_IFFT_MODE 0xF0970001 ++ ++/* SCR_CTL */ ++#define R367_OFDM_SCR_CTL 0xF098 ++#define F367_OFDM_SYRADJDECAY 0xF0980070 ++#define F367_OFDM_SCR_CPEDIS 0xF0980002 ++#define F367_OFDM_SCR_DIS 0xF0980001 ++ ++/* PPM_CTL1 */ ++#define R367_OFDM_PPM_CTL1 0xF099 ++#define F367_OFDM_PPM_MAXFREQ 0xF0990030 ++#define F367_OFDM_PPM_MAXTIM 0xF0990008 ++#define F367_OFDM_PPM_INVSEL 0xF0990004 ++#define F367_OFDM_PPM_SCATDIS 0xF0990002 ++#define F367_OFDM_PPM_BYP 0xF0990001 ++ ++/* TRL_CTL */ ++#define R367_OFDM_TRL_CTL 0xF09A ++#define F367_OFDM_TRL_NOMRATE_LSB 0xF09A0080 ++#define F367_OFDM_TRL_GAIN_FACTOR 0xF09A0078 ++#define F367_OFDM_TRL_LOOPGAIN 0xF09A0007 ++ ++/* TRL_NOMRATE1 */ ++#define R367_OFDM_TRL_NOMRATE1 0xF09B ++#define F367_OFDM_TRL_NOMRATE_LO 0xF09B00FF ++ ++/* TRL_NOMRATE2 */ ++#define R367_OFDM_TRL_NOMRATE2 0xF09C ++#define F367_OFDM_TRL_NOMRATE_HI 0xF09C00FF ++ ++/* TRL_TIME1 */ ++#define R367_OFDM_TRL_TIME1 0xF09D ++#define F367_OFDM_TRL_TOFFSET_LO 0xF09D00FF ++ ++/* TRL_TIME2 */ ++#define R367_OFDM_TRL_TIME2 0xF09E ++#define F367_OFDM_TRL_TOFFSET_HI 0xF09E00FF ++ ++/* CRL_CTL */ ++#define R367_OFDM_CRL_CTL 0xF09F ++#define F367_OFDM_CRL_DIS 0xF09F0080 ++#define F367_OFDM_CRL_GAIN_FACTOR 0xF09F0078 ++#define F367_OFDM_CRL_LOOPGAIN 0xF09F0007 ++ ++/* CRL_FREQ1 */ ++#define R367_OFDM_CRL_FREQ1 0xF0A0 ++#define F367_OFDM_CRL_FOFFSET_LO 0xF0A000FF ++ ++/* CRL_FREQ2 */ ++#define R367_OFDM_CRL_FREQ2 0xF0A1 ++#define F367_OFDM_CRL_FOFFSET_HI 0xF0A100FF ++ ++/* CRL_FREQ3 */ ++#define R367_OFDM_CRL_FREQ3 0xF0A2 ++#define F367_OFDM_CRL_FOFFSET_VHI 0xF0A200FF ++ ++/* TPS_SFRAME_CTL */ ++#define R367_OFDM_TPS_SFRAME_CTL 0xF0A3 ++#define F367_OFDM_TPS_SFRAME_SYNC 0xF0A30001 ++ ++/* CHC_SNR */ ++#define R367_OFDM_CHC_SNR 0xF0A4 ++#define F367_OFDM_CHCSNR 0xF0A400FF ++ ++/* BDI_CTL */ ++#define R367_OFDM_BDI_CTL 0xF0A5 ++#define F367_OFDM_BDI_LPSEL 0xF0A50002 ++#define F367_OFDM_BDI_SERIAL 0xF0A50001 ++ ++/* DMP_CTL */ ++#define R367_OFDM_DMP_CTL 0xF0A6 ++#define F367_OFDM_DMP_SCALING_FACTOR 0xF0A6001E ++#define F367_OFDM_DMP_SDDIS 0xF0A60001 ++ ++/* TPS_RCVD1 */ ++#define R367_OFDM_TPS_RCVD1 0xF0A7 ++#define F367_OFDM_TPS_CHANGE 0xF0A70040 ++#define F367_OFDM_BCH_OK 0xF0A70020 ++#define F367_OFDM_TPS_SYNC 0xF0A70010 ++#define F367_OFDM_TPS_FRAME 0xF0A70003 ++ ++/* TPS_RCVD2 */ ++#define R367_OFDM_TPS_RCVD2 0xF0A8 ++#define F367_OFDM_TPS_HIERMODE 0xF0A80070 ++#define F367_OFDM_TPS_CONST 0xF0A80003 ++ ++/* TPS_RCVD3 */ ++#define R367_OFDM_TPS_RCVD3 0xF0A9 ++#define F367_OFDM_TPS_LPCODE 0xF0A90070 ++#define F367_OFDM_TPS_HPCODE 0xF0A90007 ++ ++/* TPS_RCVD4 */ ++#define R367_OFDM_TPS_RCVD4 0xF0AA ++#define F367_OFDM_TPS_GUARD 0xF0AA0030 ++#define F367_OFDM_TPS_MODE 0xF0AA0003 ++ ++/* TPS_ID_CELL1 */ ++#define R367_OFDM_TPS_ID_CELL1 0xF0AB ++#define F367_OFDM_TPS_ID_CELL_LO 0xF0AB00FF ++ ++/* TPS_ID_CELL2 */ ++#define R367_OFDM_TPS_ID_CELL2 0xF0AC ++#define F367_OFDM_TPS_ID_CELL_HI 0xF0AC00FF ++ ++/* TPS_RCVD5_SET1 */ ++#define R367_OFDM_TPS_RCVD5_SET1 0xF0AD ++#define F367_OFDM_TPS_NA 0xF0AD00FC ++#define F367_OFDM_TPS_SETFRAME 0xF0AD0003 ++ ++/* TPS_SET2 */ ++#define R367_OFDM_TPS_SET2 0xF0AE ++#define F367_OFDM_TPS_SETHIERMODE 0xF0AE0070 ++#define F367_OFDM_TPS_SETCONST 0xF0AE0003 ++ ++/* TPS_SET3 */ ++#define R367_OFDM_TPS_SET3 0xF0AF ++#define F367_OFDM_TPS_SETLPCODE 0xF0AF0070 ++#define F367_OFDM_TPS_SETHPCODE 0xF0AF0007 ++ ++/* TPS_CTL */ ++#define R367_OFDM_TPS_CTL 0xF0B0 ++#define F367_OFDM_TPS_IMM 0xF0B00004 ++#define F367_OFDM_TPS_BCHDIS 0xF0B00002 ++#define F367_OFDM_TPS_UPDDIS 0xF0B00001 ++ ++/* CTL_FFTOSNUM */ ++#define R367_OFDM_CTL_FFTOSNUM 0xF0B1 ++#define F367_OFDM_SYMBOL_NUMBER 0xF0B1007F ++ ++/* TESTSELECT */ ++#define R367_OFDM_TESTSELECT 0xF0B2 ++#define F367_OFDM_TEST_SELECT 0xF0B2001F ++ ++/* MSC_REV */ ++#define R367_OFDM_MSC_REV 0xF0B3 ++#define F367_OFDM_REV_NUMBER 0xF0B300FF ++ ++/* PIR_CTL */ ++#define R367_OFDM_PIR_CTL 0xF0B4 ++#define F367_OFDM_FREEZE 0xF0B40001 ++ ++/* SNR_CARRIER1 */ ++#define R367_OFDM_SNR_CARRIER1 0xF0B5 ++#define F367_OFDM_SNR_CARRIER_LO 0xF0B500FF ++ ++/* SNR_CARRIER2 */ ++#define R367_OFDM_SNR_CARRIER2 0xF0B6 ++#define F367_OFDM_MEAN 0xF0B600C0 ++#define F367_OFDM_SNR_CARRIER_HI 0xF0B6001F ++ ++/* PPM_CPAMP */ ++#define R367_OFDM_PPM_CPAMP 0xF0B7 ++#define F367_OFDM_PPM_CPC 0xF0B700FF ++ ++/* TSM_AP0 */ ++#define R367_OFDM_TSM_AP0 0xF0B8 ++#define F367_OFDM_ADDRESS_BYTE_0 0xF0B800FF ++ ++/* TSM_AP1 */ ++#define R367_OFDM_TSM_AP1 0xF0B9 ++#define F367_OFDM_ADDRESS_BYTE_1 0xF0B900FF ++ ++/* TSM_AP2 */ ++#define R367_OFDM_TSM_AP2 0xF0BA ++#define F367_OFDM_DATA_BYTE_0 0xF0BA00FF ++ ++/* TSM_AP3 */ ++#define R367_OFDM_TSM_AP3 0xF0BB ++#define F367_OFDM_DATA_BYTE_1 0xF0BB00FF ++ ++/* TSM_AP4 */ ++#define R367_OFDM_TSM_AP4 0xF0BC ++#define F367_OFDM_DATA_BYTE_2 0xF0BC00FF ++ ++/* TSM_AP5 */ ++#define R367_OFDM_TSM_AP5 0xF0BD ++#define F367_OFDM_DATA_BYTE_3 0xF0BD00FF ++ ++/* TSM_AP6 */ ++#define R367_OFDM_TSM_AP6 0xF0BE ++#define F367_OFDM_TSM_AP_6 0xF0BE00FF ++ ++/* TSM_AP7 */ ++#define R367_OFDM_TSM_AP7 0xF0BF ++#define F367_OFDM_MEM_SELECT_BYTE 0xF0BF00FF ++ ++/* TSTRES */ ++#define R367_TSTRES 0xF0C0 ++#define F367_FRES_DISPLAY 0xF0C00080 ++#define F367_FRES_FIFO_AD 0xF0C00020 ++#define F367_FRESRS 0xF0C00010 ++#define F367_FRESACS 0xF0C00008 ++#define F367_FRESFEC 0xF0C00004 ++#define F367_FRES_PRIF 0xF0C00002 ++#define F367_FRESCORE 0xF0C00001 ++ ++/* ANACTRL */ ++#define R367_ANACTRL 0xF0C1 ++#define F367_BYPASS_XTAL 0xF0C10040 ++#define F367_BYPASS_PLLXN 0xF0C1000C ++#define F367_DIS_PAD_OSC 0xF0C10002 ++#define F367_STDBY_PLLXN 0xF0C10001 ++ ++/* TSTBUS */ ++#define R367_TSTBUS 0xF0C2 ++#define F367_TS_BYTE_CLK_INV 0xF0C20080 ++#define F367_CFG_IP 0xF0C20070 ++#define F367_CFG_TST 0xF0C2000F ++ ++/* TSTRATE */ ++#define R367_TSTRATE 0xF0C6 ++#define F367_FORCEPHA 0xF0C60080 ++#define F367_FNEWPHA 0xF0C60010 ++#define F367_FROT90 0xF0C60008 ++#define F367_FR 0xF0C60007 ++ ++/* CONSTMODE */ ++#define R367_OFDM_CONSTMODE 0xF0CB ++#define F367_OFDM_TST_PRIF 0xF0CB00E0 ++#define F367_OFDM_CAR_TYPE 0xF0CB0018 ++#define F367_OFDM_CONST_MODE 0xF0CB0003 ++ ++/* CONSTCARR1 */ ++#define R367_OFDM_CONSTCARR1 0xF0CC ++#define F367_OFDM_CONST_CARR_LO 0xF0CC00FF ++ ++/* CONSTCARR2 */ ++#define R367_OFDM_CONSTCARR2 0xF0CD ++#define F367_OFDM_CONST_CARR_HI 0xF0CD001F ++ ++/* ICONSTEL */ ++#define R367_OFDM_ICONSTEL 0xF0CE ++#define F367_OFDM_PICONSTEL 0xF0CE00FF ++ ++/* QCONSTEL */ ++#define R367_OFDM_QCONSTEL 0xF0CF ++#define F367_OFDM_PQCONSTEL 0xF0CF00FF ++ ++/* TSTBISTRES0 */ ++#define R367_OFDM_TSTBISTRES0 0xF0D0 ++#define F367_OFDM_BEND_PPM 0xF0D00080 ++#define F367_OFDM_BBAD_PPM 0xF0D00040 ++#define F367_OFDM_BEND_FFTW 0xF0D00020 ++#define F367_OFDM_BBAD_FFTW 0xF0D00010 ++#define F367_OFDM_BEND_FFT_BUF 0xF0D00008 ++#define F367_OFDM_BBAD_FFT_BUF 0xF0D00004 ++#define F367_OFDM_BEND_SYR 0xF0D00002 ++#define F367_OFDM_BBAD_SYR 0xF0D00001 ++ ++/* TSTBISTRES1 */ ++#define R367_OFDM_TSTBISTRES1 0xF0D1 ++#define F367_OFDM_BEND_CHC_CP 0xF0D10080 ++#define F367_OFDM_BBAD_CHC_CP 0xF0D10040 ++#define F367_OFDM_BEND_CHCI 0xF0D10020 ++#define F367_OFDM_BBAD_CHCI 0xF0D10010 ++#define F367_OFDM_BEND_BDI 0xF0D10008 ++#define F367_OFDM_BBAD_BDI 0xF0D10004 ++#define F367_OFDM_BEND_SDI 0xF0D10002 ++#define F367_OFDM_BBAD_SDI 0xF0D10001 ++ ++/* TSTBISTRES2 */ ++#define R367_OFDM_TSTBISTRES2 0xF0D2 ++#define F367_OFDM_BEND_CHC_INC 0xF0D20080 ++#define F367_OFDM_BBAD_CHC_INC 0xF0D20040 ++#define F367_OFDM_BEND_CHC_SPP 0xF0D20020 ++#define F367_OFDM_BBAD_CHC_SPP 0xF0D20010 ++#define F367_OFDM_BEND_CHC_CPP 0xF0D20008 ++#define F367_OFDM_BBAD_CHC_CPP 0xF0D20004 ++#define F367_OFDM_BEND_CHC_SP 0xF0D20002 ++#define F367_OFDM_BBAD_CHC_SP 0xF0D20001 ++ ++/* TSTBISTRES3 */ ++#define R367_OFDM_TSTBISTRES3 0xF0D3 ++#define F367_OFDM_BEND_QAM 0xF0D30080 ++#define F367_OFDM_BBAD_QAM 0xF0D30040 ++#define F367_OFDM_BEND_SFEC_VIT 0xF0D30020 ++#define F367_OFDM_BBAD_SFEC_VIT 0xF0D30010 ++#define F367_OFDM_BEND_SFEC_DLINE 0xF0D30008 ++#define F367_OFDM_BBAD_SFEC_DLINE 0xF0D30004 ++#define F367_OFDM_BEND_SFEC_HW 0xF0D30002 ++#define F367_OFDM_BBAD_SFEC_HW 0xF0D30001 ++ ++/* RF_AGC1 */ ++#define R367_RF_AGC1 0xF0D4 ++#define F367_RF_AGC1_LEVEL_HI 0xF0D400FF ++ ++/* RF_AGC2 */ ++#define R367_RF_AGC2 0xF0D5 ++#define F367_REF_ADGP 0xF0D50080 ++#define F367_STDBY_ADCGP 0xF0D50020 ++#define F367_CHANNEL_SEL 0xF0D5001C ++#define F367_RF_AGC1_LEVEL_LO 0xF0D50003 ++ ++/* ANADIGCTRL */ ++#define R367_ANADIGCTRL 0xF0D7 ++#define F367_SEL_CLKDEM 0xF0D70020 ++#define F367_EN_BUFFER_Q 0xF0D70010 ++#define F367_EN_BUFFER_I 0xF0D70008 ++#define F367_ADC_RIS_EGDE 0xF0D70004 ++#define F367_SGN_ADC 0xF0D70002 ++#define F367_SEL_AD12_SYNC 0xF0D70001 ++ ++/* PLLMDIV */ ++#define R367_PLLMDIV 0xF0D8 ++#define F367_PLL_MDIV 0xF0D800FF ++ ++/* PLLNDIV */ ++#define R367_PLLNDIV 0xF0D9 ++#define F367_PLL_NDIV 0xF0D900FF ++ ++/* PLLSETUP */ ++#define R367_PLLSETUP 0xF0DA ++#define F367_PLL_PDIV 0xF0DA0070 ++#define F367_PLL_KDIV 0xF0DA000F ++ ++/* DUAL_AD12 */ ++#define R367_DUAL_AD12 0xF0DB ++#define F367_FS20M 0xF0DB0020 ++#define F367_FS50M 0xF0DB0010 ++#define F367_INMODE0 0xF0DB0008 ++#define F367_POFFQ 0xF0DB0004 ++#define F367_POFFI 0xF0DB0002 ++#define F367_INMODE1 0xF0DB0001 ++ ++/* TSTBIST */ ++#define R367_TSTBIST 0xF0DC ++#define F367_TST_BYP_CLK 0xF0DC0080 ++#define F367_TST_GCLKENA_STD 0xF0DC0040 ++#define F367_TST_GCLKENA 0xF0DC0020 ++#define F367_TST_MEMBIST 0xF0DC001F ++ ++/* PAD_COMP_CTRL */ ++#define R367_PAD_COMP_CTRL 0xF0DD ++#define F367_COMPTQ 0xF0DD0010 ++#define F367_COMPEN 0xF0DD0008 ++#define F367_FREEZE2 0xF0DD0004 ++#define F367_SLEEP_INHBT 0xF0DD0002 ++#define F367_CHIP_SLEEP 0xF0DD0001 ++ ++/* PAD_COMP_WR */ ++#define R367_PAD_COMP_WR 0xF0DE ++#define F367_WR_ASRC 0xF0DE007F ++ ++/* PAD_COMP_RD */ ++#define R367_PAD_COMP_RD 0xF0DF ++#define F367_COMPOK 0xF0DF0080 ++#define F367_RD_ASRC 0xF0DF007F ++ ++/* SYR_TARGET_FFTADJT_MSB */ ++#define R367_OFDM_SYR_TARGET_FFTADJT_MSB 0xF100 ++#define F367_OFDM_SYR_START 0xF1000080 ++#define F367_OFDM_SYR_TARGET_FFTADJ_HI 0xF100000F ++ ++/* SYR_TARGET_FFTADJT_LSB */ ++#define R367_OFDM_SYR_TARGET_FFTADJT_LSB 0xF101 ++#define F367_OFDM_SYR_TARGET_FFTADJ_LO 0xF10100FF ++ ++/* SYR_TARGET_CHCADJT_MSB */ ++#define R367_OFDM_SYR_TARGET_CHCADJT_MSB 0xF102 ++#define F367_OFDM_SYR_TARGET_CHCADJ_HI 0xF102000F ++ ++/* SYR_TARGET_CHCADJT_LSB */ ++#define R367_OFDM_SYR_TARGET_CHCADJT_LSB 0xF103 ++#define F367_OFDM_SYR_TARGET_CHCADJ_LO 0xF10300FF ++ ++/* SYR_FLAG */ ++#define R367_OFDM_SYR_FLAG 0xF104 ++#define F367_OFDM_TRIG_FLG1 0xF1040080 ++#define F367_OFDM_TRIG_FLG0 0xF1040040 ++#define F367_OFDM_FFT_FLG1 0xF1040008 ++#define F367_OFDM_FFT_FLG0 0xF1040004 ++#define F367_OFDM_CHC_FLG1 0xF1040002 ++#define F367_OFDM_CHC_FLG0 0xF1040001 ++ ++/* CRL_TARGET1 */ ++#define R367_OFDM_CRL_TARGET1 0xF105 ++#define F367_OFDM_CRL_START 0xF1050080 ++#define F367_OFDM_CRL_TARGET_VHI 0xF105000F ++ ++/* CRL_TARGET2 */ ++#define R367_OFDM_CRL_TARGET2 0xF106 ++#define F367_OFDM_CRL_TARGET_HI 0xF10600FF ++ ++/* CRL_TARGET3 */ ++#define R367_OFDM_CRL_TARGET3 0xF107 ++#define F367_OFDM_CRL_TARGET_LO 0xF10700FF ++ ++/* CRL_TARGET4 */ ++#define R367_OFDM_CRL_TARGET4 0xF108 ++#define F367_OFDM_CRL_TARGET_VLO 0xF10800FF ++ ++/* CRL_FLAG */ ++#define R367_OFDM_CRL_FLAG 0xF109 ++#define F367_OFDM_CRL_FLAG1 0xF1090002 ++#define F367_OFDM_CRL_FLAG0 0xF1090001 ++ ++/* TRL_TARGET1 */ ++#define R367_OFDM_TRL_TARGET1 0xF10A ++#define F367_OFDM_TRL_TARGET_HI 0xF10A00FF ++ ++/* TRL_TARGET2 */ ++#define R367_OFDM_TRL_TARGET2 0xF10B ++#define F367_OFDM_TRL_TARGET_LO 0xF10B00FF ++ ++/* TRL_CHC */ ++#define R367_OFDM_TRL_CHC 0xF10C ++#define F367_OFDM_TRL_START 0xF10C0080 ++#define F367_OFDM_CHC_START 0xF10C0040 ++#define F367_OFDM_TRL_FLAG1 0xF10C0002 ++#define F367_OFDM_TRL_FLAG0 0xF10C0001 ++ ++/* CHC_SNR_TARG */ ++#define R367_OFDM_CHC_SNR_TARG 0xF10D ++#define F367_OFDM_CHC_SNR_TARGET 0xF10D00FF ++ ++/* TOP_TRACK */ ++#define R367_OFDM_TOP_TRACK 0xF10E ++#define F367_OFDM_TOP_START 0xF10E0080 ++#define F367_OFDM_FIRST_FLAG 0xF10E0070 ++#define F367_OFDM_TOP_FLAG1 0xF10E0008 ++#define F367_OFDM_TOP_FLAG0 0xF10E0004 ++#define F367_OFDM_CHC_FLAG1 0xF10E0002 ++#define F367_OFDM_CHC_FLAG0 0xF10E0001 ++ ++/* TRACKER_FREE1 */ ++#define R367_OFDM_TRACKER_FREE1 0xF10F ++#define F367_OFDM_TRACKER_FREE_1 0xF10F00FF ++ ++/* ERROR_CRL1 */ ++#define R367_OFDM_ERROR_CRL1 0xF110 ++#define F367_OFDM_ERROR_CRL_VHI 0xF11000FF ++ ++/* ERROR_CRL2 */ ++#define R367_OFDM_ERROR_CRL2 0xF111 ++#define F367_OFDM_ERROR_CRL_HI 0xF11100FF ++ ++/* ERROR_CRL3 */ ++#define R367_OFDM_ERROR_CRL3 0xF112 ++#define F367_OFDM_ERROR_CRL_LOI 0xF11200FF ++ ++/* ERROR_CRL4 */ ++#define R367_OFDM_ERROR_CRL4 0xF113 ++#define F367_OFDM_ERROR_CRL_VLO 0xF11300FF ++ ++/* DEC_NCO1 */ ++#define R367_OFDM_DEC_NCO1 0xF114 ++#define F367_OFDM_DEC_NCO_VHI 0xF11400FF ++ ++/* DEC_NCO2 */ ++#define R367_OFDM_DEC_NCO2 0xF115 ++#define F367_OFDM_DEC_NCO_HI 0xF11500FF ++ ++/* DEC_NCO3 */ ++#define R367_OFDM_DEC_NCO3 0xF116 ++#define F367_OFDM_DEC_NCO_LO 0xF11600FF ++ ++/* SNR */ ++#define R367_OFDM_SNR 0xF117 ++#define F367_OFDM_SNRATIO 0xF11700FF ++ ++/* SYR_FFTADJ1 */ ++#define R367_OFDM_SYR_FFTADJ1 0xF118 ++#define F367_OFDM_SYR_FFTADJ_HI 0xF11800FF ++ ++/* SYR_FFTADJ2 */ ++#define R367_OFDM_SYR_FFTADJ2 0xF119 ++#define F367_OFDM_SYR_FFTADJ_LO 0xF11900FF ++ ++/* SYR_CHCADJ1 */ ++#define R367_OFDM_SYR_CHCADJ1 0xF11A ++#define F367_OFDM_SYR_CHCADJ_HI 0xF11A00FF ++ ++/* SYR_CHCADJ2 */ ++#define R367_OFDM_SYR_CHCADJ2 0xF11B ++#define F367_OFDM_SYR_CHCADJ_LO 0xF11B00FF ++ ++/* SYR_OFF */ ++#define R367_OFDM_SYR_OFF 0xF11C ++#define F367_OFDM_SYR_OFFSET 0xF11C00FF ++ ++/* PPM_OFFSET1 */ ++#define R367_OFDM_PPM_OFFSET1 0xF11D ++#define F367_OFDM_PPM_OFFSET_HI 0xF11D00FF ++ ++/* PPM_OFFSET2 */ ++#define R367_OFDM_PPM_OFFSET2 0xF11E ++#define F367_OFDM_PPM_OFFSET_LO 0xF11E00FF ++ ++/* TRACKER_FREE2 */ ++#define R367_OFDM_TRACKER_FREE2 0xF11F ++#define F367_OFDM_TRACKER_FREE_2 0xF11F00FF ++ ++/* DEBG_LT10 */ ++#define R367_OFDM_DEBG_LT10 0xF120 ++#define F367_OFDM_DEBUG_LT10 0xF12000FF ++ ++/* DEBG_LT11 */ ++#define R367_OFDM_DEBG_LT11 0xF121 ++#define F367_OFDM_DEBUG_LT11 0xF12100FF ++ ++/* DEBG_LT12 */ ++#define R367_OFDM_DEBG_LT12 0xF122 ++#define F367_OFDM_DEBUG_LT12 0xF12200FF ++ ++/* DEBG_LT13 */ ++#define R367_OFDM_DEBG_LT13 0xF123 ++#define F367_OFDM_DEBUG_LT13 0xF12300FF ++ ++/* DEBG_LT14 */ ++#define R367_OFDM_DEBG_LT14 0xF124 ++#define F367_OFDM_DEBUG_LT14 0xF12400FF ++ ++/* DEBG_LT15 */ ++#define R367_OFDM_DEBG_LT15 0xF125 ++#define F367_OFDM_DEBUG_LT15 0xF12500FF ++ ++/* DEBG_LT16 */ ++#define R367_OFDM_DEBG_LT16 0xF126 ++#define F367_OFDM_DEBUG_LT16 0xF12600FF ++ ++/* DEBG_LT17 */ ++#define R367_OFDM_DEBG_LT17 0xF127 ++#define F367_OFDM_DEBUG_LT17 0xF12700FF ++ ++/* DEBG_LT18 */ ++#define R367_OFDM_DEBG_LT18 0xF128 ++#define F367_OFDM_DEBUG_LT18 0xF12800FF ++ ++/* DEBG_LT19 */ ++#define R367_OFDM_DEBG_LT19 0xF129 ++#define F367_OFDM_DEBUG_LT19 0xF12900FF ++ ++/* DEBG_LT1A */ ++#define R367_OFDM_DEBG_LT1A 0xF12A ++#define F367_OFDM_DEBUG_LT1A 0xF12A00FF ++ ++/* DEBG_LT1B */ ++#define R367_OFDM_DEBG_LT1B 0xF12B ++#define F367_OFDM_DEBUG_LT1B 0xF12B00FF ++ ++/* DEBG_LT1C */ ++#define R367_OFDM_DEBG_LT1C 0xF12C ++#define F367_OFDM_DEBUG_LT1C 0xF12C00FF ++ ++/* DEBG_LT1D */ ++#define R367_OFDM_DEBG_LT1D 0xF12D ++#define F367_OFDM_DEBUG_LT1D 0xF12D00FF ++ ++/* DEBG_LT1E */ ++#define R367_OFDM_DEBG_LT1E 0xF12E ++#define F367_OFDM_DEBUG_LT1E 0xF12E00FF ++ ++/* DEBG_LT1F */ ++#define R367_OFDM_DEBG_LT1F 0xF12F ++#define F367_OFDM_DEBUG_LT1F 0xF12F00FF ++ ++/* RCCFGH */ ++#define R367_OFDM_RCCFGH 0xF200 ++#define F367_OFDM_TSRCFIFO_DVBCI 0xF2000080 ++#define F367_OFDM_TSRCFIFO_SERIAL 0xF2000040 ++#define F367_OFDM_TSRCFIFO_DISABLE 0xF2000020 ++#define F367_OFDM_TSFIFO_2TORC 0xF2000010 ++#define F367_OFDM_TSRCFIFO_HSGNLOUT 0xF2000008 ++#define F367_OFDM_TSRCFIFO_ERRMODE 0xF2000006 ++#define F367_OFDM_RCCFGH_0 0xF2000001 ++ ++/* RCCFGM */ ++#define R367_OFDM_RCCFGM 0xF201 ++#define F367_OFDM_TSRCFIFO_MANSPEED 0xF20100C0 ++#define F367_OFDM_TSRCFIFO_PERMDATA 0xF2010020 ++#define F367_OFDM_TSRCFIFO_NONEWSGNL 0xF2010010 ++#define F367_OFDM_RCBYTE_OVERSAMPLING 0xF201000E ++#define F367_OFDM_TSRCFIFO_INVDATA 0xF2010001 ++ ++/* RCCFGL */ ++#define R367_OFDM_RCCFGL 0xF202 ++#define F367_OFDM_TSRCFIFO_BCLKDEL1CK 0xF20200C0 ++#define F367_OFDM_RCCFGL_5 0xF2020020 ++#define F367_OFDM_TSRCFIFO_DUTY50 0xF2020010 ++#define F367_OFDM_TSRCFIFO_NSGNL2DATA 0xF2020008 ++#define F367_OFDM_TSRCFIFO_DISSERMUX 0xF2020004 ++#define F367_OFDM_RCCFGL_1 0xF2020002 ++#define F367_OFDM_TSRCFIFO_STOPCKDIS 0xF2020001 ++ ++/* RCINSDELH */ ++#define R367_OFDM_RCINSDELH 0xF203 ++#define F367_OFDM_TSRCDEL_SYNCBYTE 0xF2030080 ++#define F367_OFDM_TSRCDEL_XXHEADER 0xF2030040 ++#define F367_OFDM_TSRCDEL_BBHEADER 0xF2030020 ++#define F367_OFDM_TSRCDEL_DATAFIELD 0xF2030010 ++#define F367_OFDM_TSRCINSDEL_ISCR 0xF2030008 ++#define F367_OFDM_TSRCINSDEL_NPD 0xF2030004 ++#define F367_OFDM_TSRCINSDEL_RSPARITY 0xF2030002 ++#define F367_OFDM_TSRCINSDEL_CRC8 0xF2030001 ++ ++/* RCINSDELM */ ++#define R367_OFDM_RCINSDELM 0xF204 ++#define F367_OFDM_TSRCINS_BBPADDING 0xF2040080 ++#define F367_OFDM_TSRCINS_BCHFEC 0xF2040040 ++#define F367_OFDM_TSRCINS_LDPCFEC 0xF2040020 ++#define F367_OFDM_TSRCINS_EMODCOD 0xF2040010 ++#define F367_OFDM_TSRCINS_TOKEN 0xF2040008 ++#define F367_OFDM_TSRCINS_XXXERR 0xF2040004 ++#define F367_OFDM_TSRCINS_MATYPE 0xF2040002 ++#define F367_OFDM_TSRCINS_UPL 0xF2040001 ++ ++/* RCINSDELL */ ++#define R367_OFDM_RCINSDELL 0xF205 ++#define F367_OFDM_TSRCINS_DFL 0xF2050080 ++#define F367_OFDM_TSRCINS_SYNCD 0xF2050040 ++#define F367_OFDM_TSRCINS_BLOCLEN 0xF2050020 ++#define F367_OFDM_TSRCINS_SIGPCOUNT 0xF2050010 ++#define F367_OFDM_TSRCINS_FIFO 0xF2050008 ++#define F367_OFDM_TSRCINS_REALPACK 0xF2050004 ++#define F367_OFDM_TSRCINS_TSCONFIG 0xF2050002 ++#define F367_OFDM_TSRCINS_LATENCY 0xF2050001 ++ ++/* RCSTATUS */ ++#define R367_OFDM_RCSTATUS 0xF206 ++#define F367_OFDM_TSRCFIFO_LINEOK 0xF2060080 ++#define F367_OFDM_TSRCFIFO_ERROR 0xF2060040 ++#define F367_OFDM_TSRCFIFO_DATA7 0xF2060020 ++#define F367_OFDM_RCSTATUS_4 0xF2060010 ++#define F367_OFDM_TSRCFIFO_DEMODSEL 0xF2060008 ++#define F367_OFDM_TSRC1FIFOSPEED_STORE 0xF2060004 ++#define F367_OFDM_RCSTATUS_1 0xF2060002 ++#define F367_OFDM_TSRCSERIAL_IMPOSSIBLE 0xF2060001 ++ ++/* RCSPEED */ ++#define R367_OFDM_RCSPEED 0xF207 ++#define F367_OFDM_TSRCFIFO_OUTSPEED 0xF20700FF ++ ++/* RCDEBUGM */ ++#define R367_OFDM_RCDEBUGM 0xF208 ++#define F367_OFDM_SD_UNSYNC 0xF2080080 ++#define F367_OFDM_ULFLOCK_DETECTM 0xF2080040 ++#define F367_OFDM_SUL_SELECTOS 0xF2080020 ++#define F367_OFDM_DILUL_NOSCRBLE 0xF2080010 ++#define F367_OFDM_NUL_SCRB 0xF2080008 ++#define F367_OFDM_UL_SCRB 0xF2080004 ++#define F367_OFDM_SCRAULBAD 0xF2080002 ++#define F367_OFDM_SCRAUL_UNSYNC 0xF2080001 ++ ++/* RCDEBUGL */ ++#define R367_OFDM_RCDEBUGL 0xF209 ++#define F367_OFDM_RS_ERR 0xF2090080 ++#define F367_OFDM_LLFLOCK_DETECTM 0xF2090040 ++#define F367_OFDM_NOT_SUL_SELECTOS 0xF2090020 ++#define F367_OFDM_DILLL_NOSCRBLE 0xF2090010 ++#define F367_OFDM_NLL_SCRB 0xF2090008 ++#define F367_OFDM_LL_SCRB 0xF2090004 ++#define F367_OFDM_SCRALLBAD 0xF2090002 ++#define F367_OFDM_SCRALL_UNSYNC 0xF2090001 ++ ++/* RCOBSCFG */ ++#define R367_OFDM_RCOBSCFG 0xF20A ++#define F367_OFDM_TSRCFIFO_OBSCFG 0xF20A00FF ++ ++/* RCOBSM */ ++#define R367_OFDM_RCOBSM 0xF20B ++#define F367_OFDM_TSRCFIFO_OBSDATA_HI 0xF20B00FF ++ ++/* RCOBSL */ ++#define R367_OFDM_RCOBSL 0xF20C ++#define F367_OFDM_TSRCFIFO_OBSDATA_LO 0xF20C00FF ++ ++/* RCFECSPY */ ++#define R367_OFDM_RCFECSPY 0xF210 ++#define F367_OFDM_SPYRC_ENABLE 0xF2100080 ++#define F367_OFDM_RCNO_SYNCBYTE 0xF2100040 ++#define F367_OFDM_RCSERIAL_MODE 0xF2100020 ++#define F367_OFDM_RCUNUSUAL_PACKET 0xF2100010 ++#define F367_OFDM_BERRCMETER_DATAMODE 0xF210000C ++#define F367_OFDM_BERRCMETER_LMODE 0xF2100002 ++#define F367_OFDM_BERRCMETER_RESET 0xF2100001 ++ ++/* RCFSPYCFG */ ++#define R367_OFDM_RCFSPYCFG 0xF211 ++#define F367_OFDM_FECSPYRC_INPUT 0xF21100C0 ++#define F367_OFDM_RCRST_ON_ERROR 0xF2110020 ++#define F367_OFDM_RCONE_SHOT 0xF2110010 ++#define F367_OFDM_RCI2C_MODE 0xF211000C ++#define F367_OFDM_SPYRC_HSTERESIS 0xF2110003 ++ ++/* RCFSPYDATA */ ++#define R367_OFDM_RCFSPYDATA 0xF212 ++#define F367_OFDM_SPYRC_STUFFING 0xF2120080 ++#define F367_OFDM_RCNOERR_PKTJITTER 0xF2120040 ++#define F367_OFDM_SPYRC_CNULLPKT 0xF2120020 ++#define F367_OFDM_SPYRC_OUTDATA_MODE 0xF212001F ++ ++/* RCFSPYOUT */ ++#define R367_OFDM_RCFSPYOUT 0xF213 ++#define F367_OFDM_FSPYRC_DIRECT 0xF2130080 ++#define F367_OFDM_RCFSPYOUT_6 0xF2130040 ++#define F367_OFDM_SPYRC_OUTDATA_BUS 0xF2130038 ++#define F367_OFDM_RCSTUFF_MODE 0xF2130007 ++ ++/* RCFSTATUS */ ++#define R367_OFDM_RCFSTATUS 0xF214 ++#define F367_OFDM_SPYRC_ENDSIM 0xF2140080 ++#define F367_OFDM_RCVALID_SIM 0xF2140040 ++#define F367_OFDM_RCFOUND_SIGNAL 0xF2140020 ++#define F367_OFDM_RCDSS_SYNCBYTE 0xF2140010 ++#define F367_OFDM_RCRESULT_STATE 0xF214000F ++ ++/* RCFGOODPACK */ ++#define R367_OFDM_RCFGOODPACK 0xF215 ++#define F367_OFDM_RCGOOD_PACKET 0xF21500FF ++ ++/* RCFPACKCNT */ ++#define R367_OFDM_RCFPACKCNT 0xF216 ++#define F367_OFDM_RCPACKET_COUNTER 0xF21600FF ++ ++/* RCFSPYMISC */ ++#define R367_OFDM_RCFSPYMISC 0xF217 ++#define F367_OFDM_RCLABEL_COUNTER 0xF21700FF ++ ++/* RCFBERCPT4 */ ++#define R367_OFDM_RCFBERCPT4 0xF218 ++#define F367_OFDM_FBERRCMETER_CPT_MMMMSB 0xF21800FF ++ ++/* RCFBERCPT3 */ ++#define R367_OFDM_RCFBERCPT3 0xF219 ++#define F367_OFDM_FBERRCMETER_CPT_MMMSB 0xF21900FF ++ ++/* RCFBERCPT2 */ ++#define R367_OFDM_RCFBERCPT2 0xF21A ++#define F367_OFDM_FBERRCMETER_CPT_MMSB 0xF21A00FF ++ ++/* RCFBERCPT1 */ ++#define R367_OFDM_RCFBERCPT1 0xF21B ++#define F367_OFDM_FBERRCMETER_CPT_MSB 0xF21B00FF ++ ++/* RCFBERCPT0 */ ++#define R367_OFDM_RCFBERCPT0 0xF21C ++#define F367_OFDM_FBERRCMETER_CPT_LSB 0xF21C00FF ++ ++/* RCFBERERR2 */ ++#define R367_OFDM_RCFBERERR2 0xF21D ++#define F367_OFDM_FBERRCMETER_ERR_HI 0xF21D00FF ++ ++/* RCFBERERR1 */ ++#define R367_OFDM_RCFBERERR1 0xF21E ++#define F367_OFDM_FBERRCMETER_ERR 0xF21E00FF ++ ++/* RCFBERERR0 */ ++#define R367_OFDM_RCFBERERR0 0xF21F ++#define F367_OFDM_FBERRCMETER_ERR_LO 0xF21F00FF ++ ++/* RCFSTATESM */ ++#define R367_OFDM_RCFSTATESM 0xF220 ++#define F367_OFDM_RCRSTATE_F 0xF2200080 ++#define F367_OFDM_RCRSTATE_E 0xF2200040 ++#define F367_OFDM_RCRSTATE_D 0xF2200020 ++#define F367_OFDM_RCRSTATE_C 0xF2200010 ++#define F367_OFDM_RCRSTATE_B 0xF2200008 ++#define F367_OFDM_RCRSTATE_A 0xF2200004 ++#define F367_OFDM_RCRSTATE_9 0xF2200002 ++#define F367_OFDM_RCRSTATE_8 0xF2200001 ++ ++/* RCFSTATESL */ ++#define R367_OFDM_RCFSTATESL 0xF221 ++#define F367_OFDM_RCRSTATE_7 0xF2210080 ++#define F367_OFDM_RCRSTATE_6 0xF2210040 ++#define F367_OFDM_RCRSTATE_5 0xF2210020 ++#define F367_OFDM_RCRSTATE_4 0xF2210010 ++#define F367_OFDM_RCRSTATE_3 0xF2210008 ++#define F367_OFDM_RCRSTATE_2 0xF2210004 ++#define F367_OFDM_RCRSTATE_1 0xF2210002 ++#define F367_OFDM_RCRSTATE_0 0xF2210001 ++ ++/* RCFSPYBER */ ++#define R367_OFDM_RCFSPYBER 0xF222 ++#define F367_OFDM_RCFSPYBER_7 0xF2220080 ++#define F367_OFDM_SPYRCOBS_XORREAD 0xF2220040 ++#define F367_OFDM_FSPYRCBER_OBSMODE 0xF2220020 ++#define F367_OFDM_FSPYRCBER_SYNCBYT 0xF2220010 ++#define F367_OFDM_FSPYRCBER_UNSYNC 0xF2220008 ++#define F367_OFDM_FSPYRCBER_CTIME 0xF2220007 ++ ++/* RCFSPYDISTM */ ++#define R367_OFDM_RCFSPYDISTM 0xF223 ++#define F367_OFDM_RCPKTTIME_DISTANCE_HI 0xF22300FF ++ ++/* RCFSPYDISTL */ ++#define R367_OFDM_RCFSPYDISTL 0xF224 ++#define F367_OFDM_RCPKTTIME_DISTANCE_LO 0xF22400FF ++ ++/* RCFSPYOBS7 */ ++#define R367_OFDM_RCFSPYOBS7 0xF228 ++#define F367_OFDM_RCSPYOBS_SPYFAIL 0xF2280080 ++#define F367_OFDM_RCSPYOBS_SPYFAIL1 0xF2280040 ++#define F367_OFDM_RCSPYOBS_ERROR 0xF2280020 ++#define F367_OFDM_RCSPYOBS_STROUT 0xF2280010 ++#define F367_OFDM_RCSPYOBS_RESULTSTATE1 0xF228000F ++ ++/* RCFSPYOBS6 */ ++#define R367_OFDM_RCFSPYOBS6 0xF229 ++#define F367_OFDM_RCSPYOBS_RESULTSTATE0 0xF22900F0 ++#define F367_OFDM_RCSPYOBS_RESULTSTATEM1 0xF229000F ++ ++/* RCFSPYOBS5 */ ++#define R367_OFDM_RCFSPYOBS5 0xF22A ++#define F367_OFDM_RCSPYOBS_BYTEOFPACKET1 0xF22A00FF ++ ++/* RCFSPYOBS4 */ ++#define R367_OFDM_RCFSPYOBS4 0xF22B ++#define F367_OFDM_RCSPYOBS_BYTEVALUE1 0xF22B00FF ++ ++/* RCFSPYOBS3 */ ++#define R367_OFDM_RCFSPYOBS3 0xF22C ++#define F367_OFDM_RCSPYOBS_DATA1 0xF22C00FF ++ ++/* RCFSPYOBS2 */ ++#define R367_OFDM_RCFSPYOBS2 0xF22D ++#define F367_OFDM_RCSPYOBS_DATA0 0xF22D00FF ++ ++/* RCFSPYOBS1 */ ++#define R367_OFDM_RCFSPYOBS1 0xF22E ++#define F367_OFDM_RCSPYOBS_DATAM1 0xF22E00FF ++ ++/* RCFSPYOBS0 */ ++#define R367_OFDM_RCFSPYOBS0 0xF22F ++#define F367_OFDM_RCSPYOBS_DATAM2 0xF22F00FF ++ ++/* TSGENERAL */ ++#define R367_TSGENERAL 0xF230 ++#define F367_TSGENERAL_7 0xF2300080 ++#define F367_TSGENERAL_6 0xF2300040 ++#define F367_TSFIFO_BCLK1ALL 0xF2300020 ++#define F367_TSGENERAL_4 0xF2300010 ++#define F367_MUXSTREAM_OUTMODE 0xF2300008 ++#define F367_TSFIFO_PERMPARAL 0xF2300006 ++#define F367_RST_REEDSOLO 0xF2300001 ++ ++/* RC1SPEED */ ++#define R367_RC1SPEED 0xF231 ++#define F367_TSRCFIFO1_OUTSPEED 0xF23100FF ++ ++/* TSGSTATUS */ ++#define R367_TSGSTATUS 0xF232 ++#define F367_TSGSTATUS_7 0xF2320080 ++#define F367_TSGSTATUS_6 0xF2320040 ++#define F367_RSMEM_FULL 0xF2320020 ++#define F367_RS_MULTCALC 0xF2320010 ++#define F367_RSIN_OVERTIME 0xF2320008 ++#define F367_TSFIFO3_DEMODSEL 0xF2320004 ++#define F367_TSFIFO2_DEMODSEL 0xF2320002 ++#define F367_TSFIFO1_DEMODSEL 0xF2320001 ++ ++ ++/* FECM */ ++#define R367_OFDM_FECM 0xF233 ++#define F367_OFDM_DSS_DVB 0xF2330080 ++#define F367_OFDM_DEMOD_BYPASS 0xF2330040 ++#define F367_OFDM_CMP_SLOWMODE 0xF2330020 ++#define F367_OFDM_DSS_SRCH 0xF2330010 ++#define F367_OFDM_FECM_3 0xF2330008 ++#define F367_OFDM_DIFF_MODEVIT 0xF2330004 ++#define F367_OFDM_SYNCVIT 0xF2330002 ++#define F367_OFDM_I2CSYM 0xF2330001 ++ ++/* VTH12 */ ++#define R367_OFDM_VTH12 0xF234 ++#define F367_OFDM_VTH_12 0xF23400FF ++ ++/* VTH23 */ ++#define R367_OFDM_VTH23 0xF235 ++#define F367_OFDM_VTH_23 0xF23500FF ++ ++/* VTH34 */ ++#define R367_OFDM_VTH34 0xF236 ++#define F367_OFDM_VTH_34 0xF23600FF ++ ++/* VTH56 */ ++#define R367_OFDM_VTH56 0xF237 ++#define F367_OFDM_VTH_56 0xF23700FF ++ ++/* VTH67 */ ++#define R367_OFDM_VTH67 0xF238 ++#define F367_OFDM_VTH_67 0xF23800FF ++ ++/* VTH78 */ ++#define R367_OFDM_VTH78 0xF239 ++#define F367_OFDM_VTH_78 0xF23900FF ++ ++/* VITCURPUN */ ++#define R367_OFDM_VITCURPUN 0xF23A ++#define F367_OFDM_VIT_MAPPING 0xF23A00E0 ++#define F367_OFDM_VIT_CURPUN 0xF23A001F ++ ++/* VERROR */ ++#define R367_OFDM_VERROR 0xF23B ++#define F367_OFDM_REGERR_VIT 0xF23B00FF ++ ++/* PRVIT */ ++#define R367_OFDM_PRVIT 0xF23C ++#define F367_OFDM_PRVIT_7 0xF23C0080 ++#define F367_OFDM_DIS_VTHLOCK 0xF23C0040 ++#define F367_OFDM_E7_8VIT 0xF23C0020 ++#define F367_OFDM_E6_7VIT 0xF23C0010 ++#define F367_OFDM_E5_6VIT 0xF23C0008 ++#define F367_OFDM_E3_4VIT 0xF23C0004 ++#define F367_OFDM_E2_3VIT 0xF23C0002 ++#define F367_OFDM_E1_2VIT 0xF23C0001 ++ ++/* VAVSRVIT */ ++#define R367_OFDM_VAVSRVIT 0xF23D ++#define F367_OFDM_AMVIT 0xF23D0080 ++#define F367_OFDM_FROZENVIT 0xF23D0040 ++#define F367_OFDM_SNVIT 0xF23D0030 ++#define F367_OFDM_TOVVIT 0xF23D000C ++#define F367_OFDM_HYPVIT 0xF23D0003 ++ ++/* VSTATUSVIT */ ++#define R367_OFDM_VSTATUSVIT 0xF23E ++#define F367_OFDM_VITERBI_ON 0xF23E0080 ++#define F367_OFDM_END_LOOPVIT 0xF23E0040 ++#define F367_OFDM_VITERBI_DEPRF 0xF23E0020 ++#define F367_OFDM_PRFVIT 0xF23E0010 ++#define F367_OFDM_LOCKEDVIT 0xF23E0008 ++#define F367_OFDM_VITERBI_DELOCK 0xF23E0004 ++#define F367_OFDM_VIT_DEMODSEL 0xF23E0002 ++#define F367_OFDM_VITERBI_COMPOUT 0xF23E0001 ++ ++/* VTHINUSE */ ++#define R367_OFDM_VTHINUSE 0xF23F ++#define F367_OFDM_VIT_INUSE 0xF23F00FF ++ ++/* KDIV12 */ ++#define R367_OFDM_KDIV12 0xF240 ++#define F367_OFDM_KDIV12_MANUAL 0xF2400080 ++#define F367_OFDM_K_DIVIDER_12 0xF240007F ++ ++/* KDIV23 */ ++#define R367_OFDM_KDIV23 0xF241 ++#define F367_OFDM_KDIV23_MANUAL 0xF2410080 ++#define F367_OFDM_K_DIVIDER_23 0xF241007F ++ ++/* KDIV34 */ ++#define R367_OFDM_KDIV34 0xF242 ++#define F367_OFDM_KDIV34_MANUAL 0xF2420080 ++#define F367_OFDM_K_DIVIDER_34 0xF242007F ++ ++/* KDIV56 */ ++#define R367_OFDM_KDIV56 0xF243 ++#define F367_OFDM_KDIV56_MANUAL 0xF2430080 ++#define F367_OFDM_K_DIVIDER_56 0xF243007F ++ ++/* KDIV67 */ ++#define R367_OFDM_KDIV67 0xF244 ++#define F367_OFDM_KDIV67_MANUAL 0xF2440080 ++#define F367_OFDM_K_DIVIDER_67 0xF244007F ++ ++/* KDIV78 */ ++#define R367_OFDM_KDIV78 0xF245 ++#define F367_OFDM_KDIV78_MANUAL 0xF2450080 ++#define F367_OFDM_K_DIVIDER_78 0xF245007F ++ ++/* SIGPOWER */ ++#define R367_OFDM_SIGPOWER 0xF246 ++#define F367_OFDM_SIGPOWER_MANUAL 0xF2460080 ++#define F367_OFDM_SIG_POWER 0xF246007F ++ ++/* DEMAPVIT */ ++#define R367_OFDM_DEMAPVIT 0xF247 ++#define F367_OFDM_DEMAPVIT_7 0xF2470080 ++#define F367_OFDM_K_DIVIDER_VIT 0xF247007F ++ ++/* VITSCALE */ ++#define R367_OFDM_VITSCALE 0xF248 ++#define F367_OFDM_NVTH_NOSRANGE 0xF2480080 ++#define F367_OFDM_VERROR_MAXMODE 0xF2480040 ++#define F367_OFDM_KDIV_MODE 0xF2480030 ++#define F367_OFDM_NSLOWSN_LOCKED 0xF2480008 ++#define F367_OFDM_DELOCK_PRFLOSS 0xF2480004 ++#define F367_OFDM_DIS_RSFLOCK 0xF2480002 ++#define F367_OFDM_VITSCALE_0 0xF2480001 ++ ++/* FFEC1PRG */ ++#define R367_OFDM_FFEC1PRG 0xF249 ++#define F367_OFDM_FDSS_DVB 0xF2490080 ++#define F367_OFDM_FDSS_SRCH 0xF2490040 ++#define F367_OFDM_FFECPROG_5 0xF2490020 ++#define F367_OFDM_FFECPROG_4 0xF2490010 ++#define F367_OFDM_FFECPROG_3 0xF2490008 ++#define F367_OFDM_FFECPROG_2 0xF2490004 ++#define F367_OFDM_FTS1_DISABLE 0xF2490002 ++#define F367_OFDM_FTS2_DISABLE 0xF2490001 ++ ++/* FVITCURPUN */ ++#define R367_OFDM_FVITCURPUN 0xF24A ++#define F367_OFDM_FVIT_MAPPING 0xF24A00E0 ++#define F367_OFDM_FVIT_CURPUN 0xF24A001F ++ ++/* FVERROR */ ++#define R367_OFDM_FVERROR 0xF24B ++#define F367_OFDM_FREGERR_VIT 0xF24B00FF ++ ++/* FVSTATUSVIT */ ++#define R367_OFDM_FVSTATUSVIT 0xF24C ++#define F367_OFDM_FVITERBI_ON 0xF24C0080 ++#define F367_OFDM_F1END_LOOPVIT 0xF24C0040 ++#define F367_OFDM_FVITERBI_DEPRF 0xF24C0020 ++#define F367_OFDM_FPRFVIT 0xF24C0010 ++#define F367_OFDM_FLOCKEDVIT 0xF24C0008 ++#define F367_OFDM_FVITERBI_DELOCK 0xF24C0004 ++#define F367_OFDM_FVIT_DEMODSEL 0xF24C0002 ++#define F367_OFDM_FVITERBI_COMPOUT 0xF24C0001 ++ ++/* DEBUG_LT1 */ ++#define R367_OFDM_DEBUG_LT1 0xF24D ++#define F367_OFDM_DBG_LT1 0xF24D00FF ++ ++/* DEBUG_LT2 */ ++#define R367_OFDM_DEBUG_LT2 0xF24E ++#define F367_OFDM_DBG_LT2 0xF24E00FF ++ ++/* DEBUG_LT3 */ ++#define R367_OFDM_DEBUG_LT3 0xF24F ++#define F367_OFDM_DBG_LT3 0xF24F00FF ++ ++ /* TSTSFMET */ ++#define R367_OFDM_TSTSFMET 0xF250 ++#define F367_OFDM_TSTSFEC_METRIQUES 0xF25000FF ++ ++ /* SELOUT */ ++#define R367_OFDM_SELOUT 0xF252 ++#define F367_OFDM_EN_SYNC 0xF2520080 ++#define F367_OFDM_EN_TBUSDEMAP 0xF2520040 ++#define F367_OFDM_SELOUT_5 0xF2520020 ++#define F367_OFDM_SELOUT_4 0xF2520010 ++#define F367_OFDM_TSTSYNCHRO_MODE 0xF2520002 ++ ++ /* TSYNC */ ++#define R367_OFDM_TSYNC 0xF253 ++#define F367_OFDM_CURPUN_INCMODE 0xF2530080 ++#define F367_OFDM_CERR_TSTMODE 0xF2530040 ++#define F367_OFDM_SHIFTSOF_MODE 0xF2530030 ++#define F367_OFDM_SLOWPHA_MODE 0xF2530008 ++#define F367_OFDM_PXX_BYPALL 0xF2530004 ++#define F367_OFDM_FROTA45_FIRST 0xF2530002 ++#define F367_OFDM_TST_BCHERROR 0xF2530001 ++ ++ /* TSTERR */ ++#define R367_OFDM_TSTERR 0xF254 ++#define F367_OFDM_TST_LONGPKT 0xF2540080 ++#define F367_OFDM_TST_ISSYION 0xF2540040 ++#define F367_OFDM_TST_NPDON 0xF2540020 ++#define F367_OFDM_TSTERR_4 0xF2540010 ++#define F367_OFDM_TRACEBACK_MODE 0xF2540008 ++#define F367_OFDM_TST_RSPARITY 0xF2540004 ++#define F367_OFDM_METRIQUE_MODE 0xF2540003 ++ ++ /* TSFSYNC */ ++#define R367_OFDM_TSFSYNC 0xF255 ++#define F367_OFDM_EN_SFECSYNC 0xF2550080 ++#define F367_OFDM_EN_SFECDEMAP 0xF2550040 ++#define F367_OFDM_SFCERR_TSTMODE 0xF2550020 ++#define F367_OFDM_SFECPXX_BYPALL 0xF2550010 ++#define F367_OFDM_SFECTSTSYNCHRO_MODE 0xF255000F ++ ++ /* TSTSFERR */ ++#define R367_OFDM_TSTSFERR 0xF256 ++#define F367_OFDM_TSTSTERR_7 0xF2560080 ++#define F367_OFDM_TSTSTERR_6 0xF2560040 ++#define F367_OFDM_TSTSTERR_5 0xF2560020 ++#define F367_OFDM_TSTSTERR_4 0xF2560010 ++#define F367_OFDM_SFECTRACEBACK_MODE 0xF2560008 ++#define F367_OFDM_SFEC_NCONVPROG 0xF2560004 ++#define F367_OFDM_SFECMETRIQUE_MODE 0xF2560003 ++ ++ /* TSTTSSF1 */ ++#define R367_OFDM_TSTTSSF1 0xF258 ++#define F367_OFDM_TSTERSSF 0xF2580080 ++#define F367_OFDM_TSTTSSFEN 0xF2580040 ++#define F367_OFDM_SFEC_OUTMODE 0xF2580030 ++#define F367_OFDM_XLSF_NOFTHRESHOLD 0xF2580008 ++#define F367_OFDM_TSTTSSF_STACKSEL 0xF2580007 ++ ++ /* TSTTSSF2 */ ++#define R367_OFDM_TSTTSSF2 0xF259 ++#define F367_OFDM_DILSF_DBBHEADER 0xF2590080 ++#define F367_OFDM_TSTTSSF_DISBUG 0xF2590040 ++#define F367_OFDM_TSTTSSF_NOBADSTART 0xF2590020 ++#define F367_OFDM_TSTTSSF_SELECT 0xF259001F ++ ++ /* TSTTSSF3 */ ++#define R367_OFDM_TSTTSSF3 0xF25A ++#define F367_OFDM_TSTTSSF3_7 0xF25A0080 ++#define F367_OFDM_TSTTSSF3_6 0xF25A0040 ++#define F367_OFDM_TSTTSSF3_5 0xF25A0020 ++#define F367_OFDM_TSTTSSF3_4 0xF25A0010 ++#define F367_OFDM_TSTTSSF3_3 0xF25A0008 ++#define F367_OFDM_TSTTSSF3_2 0xF25A0004 ++#define F367_OFDM_TSTTSSF3_1 0xF25A0002 ++#define F367_OFDM_DISSF_CLKENABLE 0xF25A0001 ++ ++ /* TSTTS1 */ ++#define R367_OFDM_TSTTS1 0xF25C ++#define F367_OFDM_TSTERS 0xF25C0080 ++#define F367_OFDM_TSFIFO_DSSSYNCB 0xF25C0040 ++#define F367_OFDM_TSTTS_FSPYBEFRS 0xF25C0020 ++#define F367_OFDM_NFORCE_SYNCBYTE 0xF25C0010 ++#define F367_OFDM_XL_NOFTHRESHOLD 0xF25C0008 ++#define F367_OFDM_TSTTS_FRFORCEPKT 0xF25C0004 ++#define F367_OFDM_DESCR_NOTAUTO 0xF25C0002 ++#define F367_OFDM_TSTTSEN 0xF25C0001 ++ ++ /* TSTTS2 */ ++#define R367_OFDM_TSTTS2 0xF25D ++#define F367_OFDM_DIL_DBBHEADER 0xF25D0080 ++#define F367_OFDM_TSTTS_NOBADXXX 0xF25D0040 ++#define F367_OFDM_TSFIFO_DELSPEEDUP 0xF25D0020 ++#define F367_OFDM_TSTTS_SELECT 0xF25D001F ++ ++ /* TSTTS3 */ ++#define R367_OFDM_TSTTS3 0xF25E ++#define F367_OFDM_TSTTS_NOPKTGAIN 0xF25E0080 ++#define F367_OFDM_TSTTS_NOPKTENE 0xF25E0040 ++#define F367_OFDM_TSTTS_ISOLATION 0xF25E0020 ++#define F367_OFDM_TSTTS_DISBUG 0xF25E0010 ++#define F367_OFDM_TSTTS_NOBADSTART 0xF25E0008 ++#define F367_OFDM_TSTTS_STACKSEL 0xF25E0007 ++ ++ /* TSTTS4 */ ++#define R367_OFDM_TSTTS4 0xF25F ++#define F367_OFDM_TSTTS4_7 0xF25F0080 ++#define F367_OFDM_TSTTS4_6 0xF25F0040 ++#define F367_OFDM_TSTTS4_5 0xF25F0020 ++#define F367_OFDM_TSTTS_DISDSTATE 0xF25F0010 ++#define F367_OFDM_TSTTS_FASTNOSYNC 0xF25F0008 ++#define F367_OFDM_EXT_FECSPYIN 0xF25F0004 ++#define F367_OFDM_TSTTS_NODPZERO 0xF25F0002 ++#define F367_OFDM_TSTTS_NODIV3 0xF25F0001 ++ ++ /* TSTTSRC */ ++#define R367_OFDM_TSTTSRC 0xF26C ++#define F367_OFDM_TSTTSRC_7 0xF26C0080 ++#define F367_OFDM_TSRCFIFO_DSSSYNCB 0xF26C0040 ++#define F367_OFDM_TSRCFIFO_DPUNACTIVE 0xF26C0020 ++#define F367_OFDM_TSRCFIFO_DELSPEEDUP 0xF26C0010 ++#define F367_OFDM_TSTTSRC_NODIV3 0xF26C0008 ++#define F367_OFDM_TSTTSRC_FRFORCEPKT 0xF26C0004 ++#define F367_OFDM_SAT25_SDDORIGINE 0xF26C0002 ++#define F367_OFDM_TSTTSRC_INACTIVE 0xF26C0001 ++ ++ /* TSTTSRS */ ++#define R367_OFDM_TSTTSRS 0xF26D ++#define F367_OFDM_TSTTSRS_7 0xF26D0080 ++#define F367_OFDM_TSTTSRS_6 0xF26D0040 ++#define F367_OFDM_TSTTSRS_5 0xF26D0020 ++#define F367_OFDM_TSTTSRS_4 0xF26D0010 ++#define F367_OFDM_TSTTSRS_3 0xF26D0008 ++#define F367_OFDM_TSTTSRS_2 0xF26D0004 ++#define F367_OFDM_TSTRS_DISRS2 0xF26D0002 ++#define F367_OFDM_TSTRS_DISRS1 0xF26D0001 ++ ++/* TSSTATEM */ ++#define R367_OFDM_TSSTATEM 0xF270 ++#define F367_OFDM_TSDIL_ON 0xF2700080 ++#define F367_OFDM_TSSKIPRS_ON 0xF2700040 ++#define F367_OFDM_TSRS_ON 0xF2700020 ++#define F367_OFDM_TSDESCRAMB_ON 0xF2700010 ++#define F367_OFDM_TSFRAME_MODE 0xF2700008 ++#define F367_OFDM_TS_DISABLE 0xF2700004 ++#define F367_OFDM_TSACM_MODE 0xF2700002 ++#define F367_OFDM_TSOUT_NOSYNC 0xF2700001 ++ ++/* TSSTATEL */ ++#define R367_OFDM_TSSTATEL 0xF271 ++#define F367_OFDM_TSNOSYNCBYTE 0xF2710080 ++#define F367_OFDM_TSPARITY_ON 0xF2710040 ++#define F367_OFDM_TSSYNCOUTRS_ON 0xF2710020 ++#define F367_OFDM_TSDVBS2_MODE 0xF2710010 ++#define F367_OFDM_TSISSYI_ON 0xF2710008 ++#define F367_OFDM_TSNPD_ON 0xF2710004 ++#define F367_OFDM_TSCRC8_ON 0xF2710002 ++#define F367_OFDM_TSDSS_PACKET 0xF2710001 ++ ++/* TSCFGH */ ++#define R367_OFDM_TSCFGH 0xF272 ++#define F367_OFDM_TSFIFO_DVBCI 0xF2720080 ++#define F367_OFDM_TSFIFO_SERIAL 0xF2720040 ++#define F367_OFDM_TSFIFO_TEIUPDATE 0xF2720020 ++#define F367_OFDM_TSFIFO_DUTY50 0xF2720010 ++#define F367_OFDM_TSFIFO_HSGNLOUT 0xF2720008 ++#define F367_OFDM_TSFIFO_ERRMODE 0xF2720006 ++#define F367_OFDM_RST_HWARE 0xF2720001 ++ ++/* TSCFGM */ ++#define R367_OFDM_TSCFGM 0xF273 ++#define F367_OFDM_TSFIFO_MANSPEED 0xF27300C0 ++#define F367_OFDM_TSFIFO_PERMDATA 0xF2730020 ++#define F367_OFDM_TSFIFO_NONEWSGNL 0xF2730010 ++#define F367_OFDM_TSFIFO_BITSPEED 0xF2730008 ++#define F367_OFDM_NPD_SPECDVBS2 0xF2730004 ++#define F367_OFDM_TSFIFO_STOPCKDIS 0xF2730002 ++#define F367_OFDM_TSFIFO_INVDATA 0xF2730001 ++ ++/* TSCFGL */ ++#define R367_OFDM_TSCFGL 0xF274 ++#define F367_OFDM_TSFIFO_BCLKDEL1CK 0xF27400C0 ++#define F367_OFDM_BCHERROR_MODE 0xF2740030 ++#define F367_OFDM_TSFIFO_NSGNL2DATA 0xF2740008 ++#define F367_OFDM_TSFIFO_EMBINDVB 0xF2740004 ++#define F367_OFDM_TSFIFO_DPUNACT 0xF2740002 ++#define F367_OFDM_TSFIFO_NPDOFF 0xF2740001 ++ ++/* TSSYNC */ ++#define R367_OFDM_TSSYNC 0xF275 ++#define F367_OFDM_TSFIFO_PERMUTE 0xF2750080 ++#define F367_OFDM_TSFIFO_FISCR3B 0xF2750060 ++#define F367_OFDM_TSFIFO_SYNCMODE 0xF2750018 ++#define F367_OFDM_TSFIFO_SYNCSEL 0xF2750007 ++ ++/* TSINSDELH */ ++#define R367_OFDM_TSINSDELH 0xF276 ++#define F367_OFDM_TSDEL_SYNCBYTE 0xF2760080 ++#define F367_OFDM_TSDEL_XXHEADER 0xF2760040 ++#define F367_OFDM_TSDEL_BBHEADER 0xF2760020 ++#define F367_OFDM_TSDEL_DATAFIELD 0xF2760010 ++#define F367_OFDM_TSINSDEL_ISCR 0xF2760008 ++#define F367_OFDM_TSINSDEL_NPD 0xF2760004 ++#define F367_OFDM_TSINSDEL_RSPARITY 0xF2760002 ++#define F367_OFDM_TSINSDEL_CRC8 0xF2760001 ++ ++/* TSINSDELM */ ++#define R367_OFDM_TSINSDELM 0xF277 ++#define F367_OFDM_TSINS_BBPADDING 0xF2770080 ++#define F367_OFDM_TSINS_BCHFEC 0xF2770040 ++#define F367_OFDM_TSINS_LDPCFEC 0xF2770020 ++#define F367_OFDM_TSINS_EMODCOD 0xF2770010 ++#define F367_OFDM_TSINS_TOKEN 0xF2770008 ++#define F367_OFDM_TSINS_XXXERR 0xF2770004 ++#define F367_OFDM_TSINS_MATYPE 0xF2770002 ++#define F367_OFDM_TSINS_UPL 0xF2770001 ++ ++/* TSINSDELL */ ++#define R367_OFDM_TSINSDELL 0xF278 ++#define F367_OFDM_TSINS_DFL 0xF2780080 ++#define F367_OFDM_TSINS_SYNCD 0xF2780040 ++#define F367_OFDM_TSINS_BLOCLEN 0xF2780020 ++#define F367_OFDM_TSINS_SIGPCOUNT 0xF2780010 ++#define F367_OFDM_TSINS_FIFO 0xF2780008 ++#define F367_OFDM_TSINS_REALPACK 0xF2780004 ++#define F367_OFDM_TSINS_TSCONFIG 0xF2780002 ++#define F367_OFDM_TSINS_LATENCY 0xF2780001 ++ ++/* TSDIVN */ ++#define R367_OFDM_TSDIVN 0xF279 ++#define F367_OFDM_TSFIFO_LOWSPEED 0xF2790080 ++#define F367_OFDM_BYTE_OVERSAMPLING 0xF2790070 ++#define F367_OFDM_TSMANUAL_PACKETNBR 0xF279000F ++ ++/* TSDIVPM */ ++#define R367_OFDM_TSDIVPM 0xF27A ++#define F367_OFDM_TSMANUAL_P_HI 0xF27A00FF ++ ++/* TSDIVPL */ ++#define R367_OFDM_TSDIVPL 0xF27B ++#define F367_OFDM_TSMANUAL_P_LO 0xF27B00FF ++ ++/* TSDIVQM */ ++#define R367_OFDM_TSDIVQM 0xF27C ++#define F367_OFDM_TSMANUAL_Q_HI 0xF27C00FF ++ ++/* TSDIVQL */ ++#define R367_OFDM_TSDIVQL 0xF27D ++#define F367_OFDM_TSMANUAL_Q_LO 0xF27D00FF ++ ++/* TSDILSTKM */ ++#define R367_OFDM_TSDILSTKM 0xF27E ++#define F367_OFDM_TSFIFO_DILSTK_HI 0xF27E00FF ++ ++/* TSDILSTKL */ ++#define R367_OFDM_TSDILSTKL 0xF27F ++#define F367_OFDM_TSFIFO_DILSTK_LO 0xF27F00FF ++ ++/* TSSPEED */ ++#define R367_OFDM_TSSPEED 0xF280 ++#define F367_OFDM_TSFIFO_OUTSPEED 0xF28000FF ++ ++/* TSSTATUS */ ++#define R367_OFDM_TSSTATUS 0xF281 ++#define F367_OFDM_TSFIFO_LINEOK 0xF2810080 ++#define F367_OFDM_TSFIFO_ERROR 0xF2810040 ++#define F367_OFDM_TSFIFO_DATA7 0xF2810020 ++#define F367_OFDM_TSFIFO_NOSYNC 0xF2810010 ++#define F367_OFDM_ISCR_INITIALIZED 0xF2810008 ++#define F367_OFDM_ISCR_UPDATED 0xF2810004 ++#define F367_OFDM_SOFFIFO_UNREGUL 0xF2810002 ++#define F367_OFDM_DIL_READY 0xF2810001 ++ ++/* TSSTATUS2 */ ++#define R367_OFDM_TSSTATUS2 0xF282 ++#define F367_OFDM_TSFIFO_DEMODSEL 0xF2820080 ++#define F367_OFDM_TSFIFOSPEED_STORE 0xF2820040 ++#define F367_OFDM_DILXX_RESET 0xF2820020 ++#define F367_OFDM_TSSERIAL_IMPOSSIBLE 0xF2820010 ++#define F367_OFDM_TSFIFO_UNDERSPEED 0xF2820008 ++#define F367_OFDM_BITSPEED_EVENT 0xF2820004 ++#define F367_OFDM_UL_SCRAMBDETECT 0xF2820002 ++#define F367_OFDM_ULDTV67_FALSELOCK 0xF2820001 ++ ++/* TSBITRATEM */ ++#define R367_OFDM_TSBITRATEM 0xF283 ++#define F367_OFDM_TSFIFO_BITRATE_HI 0xF28300FF ++ ++/* TSBITRATEL */ ++#define R367_OFDM_TSBITRATEL 0xF284 ++#define F367_OFDM_TSFIFO_BITRATE_LO 0xF28400FF ++ ++/* TSPACKLENM */ ++#define R367_OFDM_TSPACKLENM 0xF285 ++#define F367_OFDM_TSFIFO_PACKCPT 0xF28500E0 ++#define F367_OFDM_DIL_RPLEN_HI 0xF285001F ++ ++/* TSPACKLENL */ ++#define R367_OFDM_TSPACKLENL 0xF286 ++#define F367_OFDM_DIL_RPLEN_LO 0xF28600FF ++ ++/* TSBLOCLENM */ ++#define R367_OFDM_TSBLOCLENM 0xF287 ++#define F367_OFDM_TSFIFO_PFLEN_HI 0xF28700FF ++ ++/* TSBLOCLENL */ ++#define R367_OFDM_TSBLOCLENL 0xF288 ++#define F367_OFDM_TSFIFO_PFLEN_LO 0xF28800FF ++ ++/* TSDLYH */ ++#define R367_OFDM_TSDLYH 0xF289 ++#define F367_OFDM_SOFFIFO_TSTIMEVALID 0xF2890080 ++#define F367_OFDM_SOFFIFO_SPEEDUP 0xF2890040 ++#define F367_OFDM_SOFFIFO_STOP 0xF2890020 ++#define F367_OFDM_SOFFIFO_REGULATED 0xF2890010 ++#define F367_OFDM_SOFFIFO_REALSBOFF_HI 0xF289000F ++ ++/* TSDLYM */ ++#define R367_OFDM_TSDLYM 0xF28A ++#define F367_OFDM_SOFFIFO_REALSBOFF_MED 0xF28A00FF ++ ++/* TSDLYL */ ++#define R367_OFDM_TSDLYL 0xF28B ++#define F367_OFDM_SOFFIFO_REALSBOFF_LO 0xF28B00FF ++ ++/* TSNPDAV */ ++#define R367_OFDM_TSNPDAV 0xF28C ++#define F367_OFDM_TSNPD_AVERAGE 0xF28C00FF ++ ++/* TSBUFSTATH */ ++#define R367_OFDM_TSBUFSTATH 0xF28D ++#define F367_OFDM_TSISCR_3BYTES 0xF28D0080 ++#define F367_OFDM_TSISCR_NEWDATA 0xF28D0040 ++#define F367_OFDM_TSISCR_BUFSTAT_HI 0xF28D003F ++ ++/* TSBUFSTATM */ ++#define R367_OFDM_TSBUFSTATM 0xF28E ++#define F367_OFDM_TSISCR_BUFSTAT_MED 0xF28E00FF ++ ++/* TSBUFSTATL */ ++#define R367_OFDM_TSBUFSTATL 0xF28F ++#define F367_OFDM_TSISCR_BUFSTAT_LO 0xF28F00FF ++ ++/* TSDEBUGM */ ++#define R367_OFDM_TSDEBUGM 0xF290 ++#define F367_OFDM_TSFIFO_ILLPACKET 0xF2900080 ++#define F367_OFDM_DIL_NOSYNC 0xF2900040 ++#define F367_OFDM_DIL_ISCR 0xF2900020 ++#define F367_OFDM_DILOUT_BSYNCB 0xF2900010 ++#define F367_OFDM_TSFIFO_EMPTYPKT 0xF2900008 ++#define F367_OFDM_TSFIFO_EMPTYRD 0xF2900004 ++#define F367_OFDM_SOFFIFO_STOPM 0xF2900002 ++#define F367_OFDM_SOFFIFO_SPEEDUPM 0xF2900001 ++ ++/* TSDEBUGL */ ++#define R367_OFDM_TSDEBUGL 0xF291 ++#define F367_OFDM_TSFIFO_PACKLENFAIL 0xF2910080 ++#define F367_OFDM_TSFIFO_SYNCBFAIL 0xF2910040 ++#define F367_OFDM_TSFIFO_VITLIBRE 0xF2910020 ++#define F367_OFDM_TSFIFO_BOOSTSPEEDM 0xF2910010 ++#define F367_OFDM_TSFIFO_UNDERSPEEDM 0xF2910008 ++#define F367_OFDM_TSFIFO_ERROR_EVNT 0xF2910004 ++#define F367_OFDM_TSFIFO_FULL 0xF2910002 ++#define F367_OFDM_TSFIFO_OVERFLOWM 0xF2910001 ++ ++/* TSDLYSETH */ ++#define R367_OFDM_TSDLYSETH 0xF292 ++#define F367_OFDM_SOFFIFO_OFFSET 0xF29200E0 ++#define F367_OFDM_SOFFIFO_SYMBOFFSET_HI 0xF292001F ++ ++/* TSDLYSETM */ ++#define R367_OFDM_TSDLYSETM 0xF293 ++#define F367_OFDM_SOFFIFO_SYMBOFFSET_MED 0xF29300FF ++ ++/* TSDLYSETL */ ++#define R367_OFDM_TSDLYSETL 0xF294 ++#define F367_OFDM_SOFFIFO_SYMBOFFSET_LO 0xF29400FF ++ ++/* TSOBSCFG */ ++#define R367_OFDM_TSOBSCFG 0xF295 ++#define F367_OFDM_TSFIFO_OBSCFG 0xF29500FF ++ ++/* TSOBSM */ ++#define R367_OFDM_TSOBSM 0xF296 ++#define F367_OFDM_TSFIFO_OBSDATA_HI 0xF29600FF ++ ++/* TSOBSL */ ++#define R367_OFDM_TSOBSL 0xF297 ++#define F367_OFDM_TSFIFO_OBSDATA_LO 0xF29700FF ++ ++/* ERRCTRL1 */ ++#define R367_OFDM_ERRCTRL1 0xF298 ++#define F367_OFDM_ERR_SRC1 0xF29800F0 ++#define F367_OFDM_ERRCTRL1_3 0xF2980008 ++#define F367_OFDM_NUM_EVT1 0xF2980007 ++ ++/* ERRCNT1H */ ++#define R367_OFDM_ERRCNT1H 0xF299 ++#define F367_OFDM_ERRCNT1_OLDVALUE 0xF2990080 ++#define F367_OFDM_ERR_CNT1 0xF299007F ++ ++/* ERRCNT1M */ ++#define R367_OFDM_ERRCNT1M 0xF29A ++#define F367_OFDM_ERR_CNT1_HI 0xF29A00FF ++ ++/* ERRCNT1L */ ++#define R367_OFDM_ERRCNT1L 0xF29B ++#define F367_OFDM_ERR_CNT1_LO 0xF29B00FF ++ ++/* ERRCTRL2 */ ++#define R367_OFDM_ERRCTRL2 0xF29C ++#define F367_OFDM_ERR_SRC2 0xF29C00F0 ++#define F367_OFDM_ERRCTRL2_3 0xF29C0008 ++#define F367_OFDM_NUM_EVT2 0xF29C0007 ++ ++/* ERRCNT2H */ ++#define R367_OFDM_ERRCNT2H 0xF29D ++#define F367_OFDM_ERRCNT2_OLDVALUE 0xF29D0080 ++#define F367_OFDM_ERR_CNT2_HI 0xF29D007F ++ ++/* ERRCNT2M */ ++#define R367_OFDM_ERRCNT2M 0xF29E ++#define F367_OFDM_ERR_CNT2_MED 0xF29E00FF ++ ++/* ERRCNT2L */ ++#define R367_OFDM_ERRCNT2L 0xF29F ++#define F367_OFDM_ERR_CNT2_LO 0xF29F00FF ++ ++/* FECSPY */ ++#define R367_OFDM_FECSPY 0xF2A0 ++#define F367_OFDM_SPY_ENABLE 0xF2A00080 ++#define F367_OFDM_NO_SYNCBYTE 0xF2A00040 ++#define F367_OFDM_SERIAL_MODE 0xF2A00020 ++#define F367_OFDM_UNUSUAL_PACKET 0xF2A00010 ++#define F367_OFDM_BERMETER_DATAMODE 0xF2A0000C ++#define F367_OFDM_BERMETER_LMODE 0xF2A00002 ++#define F367_OFDM_BERMETER_RESET 0xF2A00001 ++ ++/* FSPYCFG */ ++#define R367_OFDM_FSPYCFG 0xF2A1 ++#define F367_OFDM_FECSPY_INPUT 0xF2A100C0 ++#define F367_OFDM_RST_ON_ERROR 0xF2A10020 ++#define F367_OFDM_ONE_SHOT 0xF2A10010 ++#define F367_OFDM_I2C_MOD 0xF2A1000C ++#define F367_OFDM_SPY_HYSTERESIS 0xF2A10003 ++ ++/* FSPYDATA */ ++#define R367_OFDM_FSPYDATA 0xF2A2 ++#define F367_OFDM_SPY_STUFFING 0xF2A20080 ++#define F367_OFDM_NOERROR_PKTJITTER 0xF2A20040 ++#define F367_OFDM_SPY_CNULLPKT 0xF2A20020 ++#define F367_OFDM_SPY_OUTDATA_MODE 0xF2A2001F ++ ++/* FSPYOUT */ ++#define R367_OFDM_FSPYOUT 0xF2A3 ++#define F367_OFDM_FSPY_DIRECT 0xF2A30080 ++#define F367_OFDM_FSPYOUT_6 0xF2A30040 ++#define F367_OFDM_SPY_OUTDATA_BUS 0xF2A30038 ++#define F367_OFDM_STUFF_MODE 0xF2A30007 ++ ++/* FSTATUS */ ++#define R367_OFDM_FSTATUS 0xF2A4 ++#define F367_OFDM_SPY_ENDSIM 0xF2A40080 ++#define F367_OFDM_VALID_SIM 0xF2A40040 ++#define F367_OFDM_FOUND_SIGNAL 0xF2A40020 ++#define F367_OFDM_DSS_SYNCBYTE 0xF2A40010 ++#define F367_OFDM_RESULT_STATE 0xF2A4000F ++ ++/* FGOODPACK */ ++#define R367_OFDM_FGOODPACK 0xF2A5 ++#define F367_OFDM_FGOOD_PACKET 0xF2A500FF ++ ++/* FPACKCNT */ ++#define R367_OFDM_FPACKCNT 0xF2A6 ++#define F367_OFDM_FPACKET_COUNTER 0xF2A600FF ++ ++/* FSPYMISC */ ++#define R367_OFDM_FSPYMISC 0xF2A7 ++#define F367_OFDM_FLABEL_COUNTER 0xF2A700FF ++ ++/* FBERCPT4 */ ++#define R367_OFDM_FBERCPT4 0xF2A8 ++#define F367_OFDM_FBERMETER_CPT5 0xF2A800FF ++ ++/* FBERCPT3 */ ++#define R367_OFDM_FBERCPT3 0xF2A9 ++#define F367_OFDM_FBERMETER_CPT4 0xF2A900FF ++ ++/* FBERCPT2 */ ++#define R367_OFDM_FBERCPT2 0xF2AA ++#define F367_OFDM_FBERMETER_CPT3 0xF2AA00FF ++ ++/* FBERCPT1 */ ++#define R367_OFDM_FBERCPT1 0xF2AB ++#define F367_OFDM_FBERMETER_CPT2 0xF2AB00FF ++ ++/* FBERCPT0 */ ++#define R367_OFDM_FBERCPT0 0xF2AC ++#define F367_OFDM_FBERMETER_CPT1 0xF2AC00FF ++ ++/* FBERERR2 */ ++#define R367_OFDM_FBERERR2 0xF2AD ++#define F367_OFDM_FBERMETER_ERR_HI 0xF2AD00FF ++ ++/* FBERERR1 */ ++#define R367_OFDM_FBERERR1 0xF2AE ++#define F367_OFDM_FBERMETER_ERR_MED 0xF2AE00FF ++ ++/* FBERERR0 */ ++#define R367_OFDM_FBERERR0 0xF2AF ++#define F367_OFDM_FBERMETER_ERR_LO 0xF2AF00FF ++ ++/* FSTATESM */ ++#define R367_OFDM_FSTATESM 0xF2B0 ++#define F367_OFDM_RSTATE_F 0xF2B00080 ++#define F367_OFDM_RSTATE_E 0xF2B00040 ++#define F367_OFDM_RSTATE_D 0xF2B00020 ++#define F367_OFDM_RSTATE_C 0xF2B00010 ++#define F367_OFDM_RSTATE_B 0xF2B00008 ++#define F367_OFDM_RSTATE_A 0xF2B00004 ++#define F367_OFDM_RSTATE_9 0xF2B00002 ++#define F367_OFDM_RSTATE_8 0xF2B00001 ++ ++/* FSTATESL */ ++#define R367_OFDM_FSTATESL 0xF2B1 ++#define F367_OFDM_RSTATE_7 0xF2B10080 ++#define F367_OFDM_RSTATE_6 0xF2B10040 ++#define F367_OFDM_RSTATE_5 0xF2B10020 ++#define F367_OFDM_RSTATE_4 0xF2B10010 ++#define F367_OFDM_RSTATE_3 0xF2B10008 ++#define F367_OFDM_RSTATE_2 0xF2B10004 ++#define F367_OFDM_RSTATE_1 0xF2B10002 ++#define F367_OFDM_RSTATE_0 0xF2B10001 ++ ++/* FSPYBER */ ++#define R367_OFDM_FSPYBER 0xF2B2 ++#define F367_OFDM_FSPYBER_7 0xF2B20080 ++#define F367_OFDM_FSPYOBS_XORREAD 0xF2B20040 ++#define F367_OFDM_FSPYBER_OBSMODE 0xF2B20020 ++#define F367_OFDM_FSPYBER_SYNCBYTE 0xF2B20010 ++#define F367_OFDM_FSPYBER_UNSYNC 0xF2B20008 ++#define F367_OFDM_FSPYBER_CTIME 0xF2B20007 ++ ++/* FSPYDISTM */ ++#define R367_OFDM_FSPYDISTM 0xF2B3 ++#define F367_OFDM_PKTTIME_DISTANCE_HI 0xF2B300FF ++ ++/* FSPYDISTL */ ++#define R367_OFDM_FSPYDISTL 0xF2B4 ++#define F367_OFDM_PKTTIME_DISTANCE_LO 0xF2B400FF ++ ++/* FSPYOBS7 */ ++#define R367_OFDM_FSPYOBS7 0xF2B8 ++#define F367_OFDM_FSPYOBS_SPYFAIL 0xF2B80080 ++#define F367_OFDM_FSPYOBS_SPYFAIL1 0xF2B80040 ++#define F367_OFDM_FSPYOBS_ERROR 0xF2B80020 ++#define F367_OFDM_FSPYOBS_STROUT 0xF2B80010 ++#define F367_OFDM_FSPYOBS_RESULTSTATE1 0xF2B8000F ++ ++/* FSPYOBS6 */ ++#define R367_OFDM_FSPYOBS6 0xF2B9 ++#define F367_OFDM_FSPYOBS_RESULTSTATE0 0xF2B900F0 ++#define F367_OFDM_FSPYOBS_RESULTSTATEM1 0xF2B9000F ++ ++/* FSPYOBS5 */ ++#define R367_OFDM_FSPYOBS5 0xF2BA ++#define F367_OFDM_FSPYOBS_BYTEOFPACKET1 0xF2BA00FF ++ ++/* FSPYOBS4 */ ++#define R367_OFDM_FSPYOBS4 0xF2BB ++#define F367_OFDM_FSPYOBS_BYTEVALUE1 0xF2BB00FF ++ ++/* FSPYOBS3 */ ++#define R367_OFDM_FSPYOBS3 0xF2BC ++#define F367_OFDM_FSPYOBS_DATA1 0xF2BC00FF ++ ++/* FSPYOBS2 */ ++#define R367_OFDM_FSPYOBS2 0xF2BD ++#define F367_OFDM_FSPYOBS_DATA0 0xF2BD00FF ++ ++/* FSPYOBS1 */ ++#define R367_OFDM_FSPYOBS1 0xF2BE ++#define F367_OFDM_FSPYOBS_DATAM1 0xF2BE00FF ++ ++/* FSPYOBS0 */ ++#define R367_OFDM_FSPYOBS0 0xF2BF ++#define F367_OFDM_FSPYOBS_DATAM2 0xF2BF00FF ++ ++/* SFDEMAP */ ++#define R367_OFDM_SFDEMAP 0xF2C0 ++#define F367_OFDM_SFDEMAP_7 0xF2C00080 ++#define F367_OFDM_SFEC_K_DIVIDER_VIT 0xF2C0007F ++ ++/* SFERROR */ ++#define R367_OFDM_SFERROR 0xF2C1 ++#define F367_OFDM_SFEC_REGERR_VIT 0xF2C100FF ++ ++/* SFAVSR */ ++#define R367_OFDM_SFAVSR 0xF2C2 ++#define F367_OFDM_SFEC_SUMERRORS 0xF2C20080 ++#define F367_OFDM_SERROR_MAXMODE 0xF2C20040 ++#define F367_OFDM_SN_SFEC 0xF2C20030 ++#define F367_OFDM_KDIV_MODE_SFEC 0xF2C2000C ++#define F367_OFDM_SFAVSR_1 0xF2C20002 ++#define F367_OFDM_SFAVSR_0 0xF2C20001 ++ ++/* SFECSTATUS */ ++#define R367_OFDM_SFECSTATUS 0xF2C3 ++#define F367_OFDM_SFEC_ON 0xF2C30080 ++#define F367_OFDM_SFSTATUS_6 0xF2C30040 ++#define F367_OFDM_SFSTATUS_5 0xF2C30020 ++#define F367_OFDM_SFSTATUS_4 0xF2C30010 ++#define F367_OFDM_LOCKEDSFEC 0xF2C30008 ++#define F367_OFDM_SFEC_DELOCK 0xF2C30004 ++#define F367_OFDM_SFEC_DEMODSEL1 0xF2C30002 ++#define F367_OFDM_SFEC_OVFON 0xF2C30001 ++ ++/* SFKDIV12 */ ++#define R367_OFDM_SFKDIV12 0xF2C4 ++#define F367_OFDM_SFECKDIV12_MAN 0xF2C40080 ++#define F367_OFDM_SFEC_K_DIVIDER_12 0xF2C4007F ++ ++/* SFKDIV23 */ ++#define R367_OFDM_SFKDIV23 0xF2C5 ++#define F367_OFDM_SFECKDIV23_MAN 0xF2C50080 ++#define F367_OFDM_SFEC_K_DIVIDER_23 0xF2C5007F ++ ++/* SFKDIV34 */ ++#define R367_OFDM_SFKDIV34 0xF2C6 ++#define F367_OFDM_SFECKDIV34_MAN 0xF2C60080 ++#define F367_OFDM_SFEC_K_DIVIDER_34 0xF2C6007F ++ ++/* SFKDIV56 */ ++#define R367_OFDM_SFKDIV56 0xF2C7 ++#define F367_OFDM_SFECKDIV56_MAN 0xF2C70080 ++#define F367_OFDM_SFEC_K_DIVIDER_56 0xF2C7007F ++ ++/* SFKDIV67 */ ++#define R367_OFDM_SFKDIV67 0xF2C8 ++#define F367_OFDM_SFECKDIV67_MAN 0xF2C80080 ++#define F367_OFDM_SFEC_K_DIVIDER_67 0xF2C8007F ++ ++/* SFKDIV78 */ ++#define R367_OFDM_SFKDIV78 0xF2C9 ++#define F367_OFDM_SFECKDIV78_MAN 0xF2C90080 ++#define F367_OFDM_SFEC_K_DIVIDER_78 0xF2C9007F ++ ++/* SFDILSTKM */ ++#define R367_OFDM_SFDILSTKM 0xF2CA ++#define F367_OFDM_SFEC_PACKCPT 0xF2CA00E0 ++#define F367_OFDM_SFEC_DILSTK_HI 0xF2CA001F ++ ++/* SFDILSTKL */ ++#define R367_OFDM_SFDILSTKL 0xF2CB ++#define F367_OFDM_SFEC_DILSTK_LO 0xF2CB00FF ++ ++/* SFSTATUS */ ++#define R367_OFDM_SFSTATUS 0xF2CC ++#define F367_OFDM_SFEC_LINEOK 0xF2CC0080 ++#define F367_OFDM_SFEC_ERROR 0xF2CC0040 ++#define F367_OFDM_SFEC_DATA7 0xF2CC0020 ++#define F367_OFDM_SFEC_OVERFLOW 0xF2CC0010 ++#define F367_OFDM_SFEC_DEMODSEL2 0xF2CC0008 ++#define F367_OFDM_SFEC_NOSYNC 0xF2CC0004 ++#define F367_OFDM_SFEC_UNREGULA 0xF2CC0002 ++#define F367_OFDM_SFEC_READY 0xF2CC0001 ++ ++/* SFDLYH */ ++#define R367_OFDM_SFDLYH 0xF2CD ++#define F367_OFDM_SFEC_TSTIMEVALID 0xF2CD0080 ++#define F367_OFDM_SFEC_SPEEDUP 0xF2CD0040 ++#define F367_OFDM_SFEC_STOP 0xF2CD0020 ++#define F367_OFDM_SFEC_REGULATED 0xF2CD0010 ++#define F367_OFDM_SFEC_REALSYMBOFFSET 0xF2CD000F ++ ++/* SFDLYM */ ++#define R367_OFDM_SFDLYM 0xF2CE ++#define F367_OFDM_SFEC_REALSYMBOFFSET_HI 0xF2CE00FF ++ ++/* SFDLYL */ ++#define R367_OFDM_SFDLYL 0xF2CF ++#define F367_OFDM_SFEC_REALSYMBOFFSET_LO 0xF2CF00FF ++ ++/* SFDLYSETH */ ++#define R367_OFDM_SFDLYSETH 0xF2D0 ++#define F367_OFDM_SFEC_OFFSET 0xF2D000E0 ++#define F367_OFDM_SFECDLYSETH_4 0xF2D00010 ++#define F367_OFDM_RST_SFEC 0xF2D00008 ++#define F367_OFDM_SFECDLYSETH_2 0xF2D00004 ++#define F367_OFDM_SFEC_DISABLE 0xF2D00002 ++#define F367_OFDM_SFEC_UNREGUL 0xF2D00001 ++ ++/* SFDLYSETM */ ++#define R367_OFDM_SFDLYSETM 0xF2D1 ++#define F367_OFDM_SFECDLYSETM_7 0xF2D10080 ++#define F367_OFDM_SFEC_SYMBOFFSET_HI 0xF2D1007F ++ ++/* SFDLYSETL */ ++#define R367_OFDM_SFDLYSETL 0xF2D2 ++#define F367_OFDM_SFEC_SYMBOFFSET_LO 0xF2D200FF ++ ++/* SFOBSCFG */ ++#define R367_OFDM_SFOBSCFG 0xF2D3 ++#define F367_OFDM_SFEC_OBSCFG 0xF2D300FF ++ ++/* SFOBSM */ ++#define R367_OFDM_SFOBSM 0xF2D4 ++#define F367_OFDM_SFEC_OBSDATA_HI 0xF2D400FF ++ ++/* SFOBSL */ ++#define R367_OFDM_SFOBSL 0xF2D5 ++#define F367_OFDM_SFEC_OBSDATA_LO 0xF2D500FF ++ ++/* SFECINFO */ ++#define R367_OFDM_SFECINFO 0xF2D6 ++#define F367_OFDM_SFECINFO_7 0xF2D60080 ++#define F367_OFDM_SFEC_SYNCDLSB 0xF2D60070 ++#define F367_OFDM_SFCE_S1CPHASE 0xF2D6000F ++ ++/* SFERRCTRL */ ++#define R367_OFDM_SFERRCTRL 0xF2D8 ++#define F367_OFDM_SFEC_ERR_SOURCE 0xF2D800F0 ++#define F367_OFDM_SFERRCTRL_3 0xF2D80008 ++#define F367_OFDM_SFEC_NUM_EVENT 0xF2D80007 ++ ++/* SFERRCNTH */ ++#define R367_OFDM_SFERRCNTH 0xF2D9 ++#define F367_OFDM_SFERRC_OLDVALUE 0xF2D90080 ++#define F367_OFDM_SFEC_ERR_CNT 0xF2D9007F ++ ++/* SFERRCNTM */ ++#define R367_OFDM_SFERRCNTM 0xF2DA ++#define F367_OFDM_SFEC_ERR_CNT_HI 0xF2DA00FF ++ ++/* SFERRCNTL */ ++#define R367_OFDM_SFERRCNTL 0xF2DB ++#define F367_OFDM_SFEC_ERR_CNT_LO 0xF2DB00FF ++ ++/* SYMBRATEM */ ++#define R367_OFDM_SYMBRATEM 0xF2E0 ++#define F367_OFDM_DEFGEN_SYMBRATE_HI 0xF2E000FF ++ ++/* SYMBRATEL */ ++#define R367_OFDM_SYMBRATEL 0xF2E1 ++#define F367_OFDM_DEFGEN_SYMBRATE_LO 0xF2E100FF ++ ++/* SYMBSTATUS */ ++#define R367_OFDM_SYMBSTATUS 0xF2E2 ++#define F367_OFDM_SYMBDLINE2_OFF 0xF2E20080 ++#define F367_OFDM_SDDL_REINIT1 0xF2E20040 ++#define F367_OFDM_SDD_REINIT1 0xF2E20020 ++#define F367_OFDM_TOKENID_ERROR 0xF2E20010 ++#define F367_OFDM_SYMBRATE_OVERFLOW 0xF2E20008 ++#define F367_OFDM_SYMBRATE_UNDERFLOW 0xF2E20004 ++#define F367_OFDM_TOKENID_RSTEVENT 0xF2E20002 ++#define F367_OFDM_TOKENID_RESET1 0xF2E20001 ++ ++/* SYMBCFG */ ++#define R367_OFDM_SYMBCFG 0xF2E3 ++#define F367_OFDM_SYMBCFG_7 0xF2E30080 ++#define F367_OFDM_SYMBCFG_6 0xF2E30040 ++#define F367_OFDM_SYMBCFG_5 0xF2E30020 ++#define F367_OFDM_SYMBCFG_4 0xF2E30010 ++#define F367_OFDM_SYMRATE_FSPEED 0xF2E3000C ++#define F367_OFDM_SYMRATE_SSPEED 0xF2E30003 ++ ++/* SYMBFIFOM */ ++#define R367_OFDM_SYMBFIFOM 0xF2E4 ++#define F367_OFDM_SYMBFIFOM_7 0xF2E40080 ++#define F367_OFDM_SYMBFIFOM_6 0xF2E40040 ++#define F367_OFDM_DEFGEN_SYMFIFO_HI 0xF2E4003F ++ ++/* SYMBFIFOL */ ++#define R367_OFDM_SYMBFIFOL 0xF2E5 ++#define F367_OFDM_DEFGEN_SYMFIFO_LO 0xF2E500FF ++ ++/* SYMBOFFSM */ ++#define R367_OFDM_SYMBOFFSM 0xF2E6 ++#define F367_OFDM_TOKENID_RESET2 0xF2E60080 ++#define F367_OFDM_SDDL_REINIT2 0xF2E60040 ++#define F367_OFDM_SDD_REINIT2 0xF2E60020 ++#define F367_OFDM_SYMBOFFSM_4 0xF2E60010 ++#define F367_OFDM_SYMBOFFSM_3 0xF2E60008 ++#define F367_OFDM_DEFGEN_SYMBOFFSET_HI 0xF2E60007 ++ ++/* SYMBOFFSL */ ++#define R367_OFDM_SYMBOFFSL 0xF2E7 ++#define F367_OFDM_DEFGEN_SYMBOFFSET_LO 0xF2E700FF ++ ++/* DEBUG_LT4 */ ++#define R367_DEBUG_LT4 0xF400 ++#define F367_F_DEBUG_LT4 0xF40000FF ++ ++/* DEBUG_LT5 */ ++#define R367_DEBUG_LT5 0xF401 ++#define F367_F_DEBUG_LT5 0xF40100FF ++ ++/* DEBUG_LT6 */ ++#define R367_DEBUG_LT6 0xF402 ++#define F367_F_DEBUG_LT6 0xF40200FF ++ ++/* DEBUG_LT7 */ ++#define R367_DEBUG_LT7 0xF403 ++#define F367_F_DEBUG_LT7 0xF40300FF ++ ++/* DEBUG_LT8 */ ++#define R367_DEBUG_LT8 0xF404 ++#define F367_F_DEBUG_LT8 0xF40400FF ++ ++/* DEBUG_LT9 */ ++#define R367_DEBUG_LT9 0xF405 ++#define F367_F_DEBUG_LT9 0xF40500FF ++ ++/* CTRL_1 */ ++#define R367_QAM_CTRL_1 0xF402 ++#define F367_QAM_SOFT_RST 0xF4020080 ++#define F367_QAM_EQU_RST 0xF4020008 ++#define F367_QAM_CRL_RST 0xF4020004 ++#define F367_QAM_TRL_RST 0xF4020002 ++#define F367_QAM_AGC_RST 0xF4020001 ++ ++/* CTRL_2 */ ++#define R367_QAM_CTRL_2 0xF403 ++#define F367_QAM_DEINT_RST 0xF4030008 ++#define F367_QAM_RS_RST 0xF4030004 ++ ++/* IT_STATUS1 */ ++#define R367_QAM_IT_STATUS1 0xF408 ++#define F367_QAM_SWEEP_OUT 0xF4080080 ++#define F367_QAM_FSM_CRL 0xF4080040 ++#define F367_QAM_CRL_LOCK 0xF4080020 ++#define F367_QAM_MFSM 0xF4080010 ++#define F367_QAM_TRL_LOCK 0xF4080008 ++#define F367_QAM_TRL_AGC_LIMIT 0xF4080004 ++#define F367_QAM_ADJ_AGC_LOCK 0xF4080002 ++#define F367_QAM_AGC_QAM_LOCK 0xF4080001 ++ ++/* IT_STATUS2 */ ++#define R367_QAM_IT_STATUS2 0xF409 ++#define F367_QAM_TSMF_CNT 0xF4090080 ++#define F367_QAM_TSMF_EOF 0xF4090040 ++#define F367_QAM_TSMF_RDY 0xF4090020 ++#define F367_QAM_FEC_NOCORR 0xF4090010 ++#define F367_QAM_SYNCSTATE 0xF4090008 ++#define F367_QAM_DEINT_LOCK 0xF4090004 ++#define F367_QAM_FADDING_FRZ 0xF4090002 ++#define F367_QAM_TAPMON_ALARM 0xF4090001 ++ ++/* IT_EN1 */ ++#define R367_QAM_IT_EN1 0xF40A ++#define F367_QAM_SWEEP_OUTE 0xF40A0080 ++#define F367_QAM_FSM_CRLE 0xF40A0040 ++#define F367_QAM_CRL_LOCKE 0xF40A0020 ++#define F367_QAM_MFSME 0xF40A0010 ++#define F367_QAM_TRL_LOCKE 0xF40A0008 ++#define F367_QAM_TRL_AGC_LIMITE 0xF40A0004 ++#define F367_QAM_ADJ_AGC_LOCKE 0xF40A0002 ++#define F367_QAM_AGC_LOCKE 0xF40A0001 ++ ++/* IT_EN2 */ ++#define R367_QAM_IT_EN2 0xF40B ++#define F367_QAM_TSMF_CNTE 0xF40B0080 ++#define F367_QAM_TSMF_EOFE 0xF40B0040 ++#define F367_QAM_TSMF_RDYE 0xF40B0020 ++#define F367_QAM_FEC_NOCORRE 0xF40B0010 ++#define F367_QAM_SYNCSTATEE 0xF40B0008 ++#define F367_QAM_DEINT_LOCKE 0xF40B0004 ++#define F367_QAM_FADDING_FRZE 0xF40B0002 ++#define F367_QAM_TAPMON_ALARME 0xF40B0001 ++ ++/* CTRL_STATUS */ ++#define R367_QAM_CTRL_STATUS 0xF40C ++#define F367_QAM_QAMFEC_LOCK 0xF40C0004 ++#define F367_QAM_TSMF_LOCK 0xF40C0002 ++#define F367_QAM_TSMF_ERROR 0xF40C0001 ++ ++/* TEST_CTL */ ++#define R367_QAM_TEST_CTL 0xF40F ++#define F367_QAM_TST_BLK_SEL 0xF40F0060 ++#define F367_QAM_TST_BUS_SEL 0xF40F001F ++ ++/* AGC_CTL */ ++#define R367_QAM_AGC_CTL 0xF410 ++#define F367_QAM_AGC_LCK_TH 0xF41000F0 ++#define F367_QAM_AGC_ACCUMRSTSEL 0xF4100007 ++ ++/* AGC_IF_CFG */ ++#define R367_QAM_AGC_IF_CFG 0xF411 ++#define F367_QAM_AGC_IF_BWSEL 0xF41100F0 ++#define F367_QAM_AGC_IF_FREEZE 0xF4110002 ++ ++/* AGC_RF_CFG */ ++#define R367_QAM_AGC_RF_CFG 0xF412 ++#define F367_QAM_AGC_RF_BWSEL 0xF4120070 ++#define F367_QAM_AGC_RF_FREEZE 0xF4120002 ++ ++/* AGC_PWM_CFG */ ++#define R367_QAM_AGC_PWM_CFG 0xF413 ++#define F367_QAM_AGC_RF_PWM_TST 0xF4130080 ++#define F367_QAM_AGC_RF_PWM_INV 0xF4130040 ++#define F367_QAM_AGC_IF_PWM_TST 0xF4130008 ++#define F367_QAM_AGC_IF_PWM_INV 0xF4130004 ++#define F367_QAM_AGC_PWM_CLKDIV 0xF4130003 ++ ++/* AGC_PWR_REF_L */ ++#define R367_QAM_AGC_PWR_REF_L 0xF414 ++#define F367_QAM_AGC_PWRREF_LO 0xF41400FF ++ ++/* AGC_PWR_REF_H */ ++#define R367_QAM_AGC_PWR_REF_H 0xF415 ++#define F367_QAM_AGC_PWRREF_HI 0xF4150003 ++ ++/* AGC_RF_TH_L */ ++#define R367_QAM_AGC_RF_TH_L 0xF416 ++#define F367_QAM_AGC_RF_TH_LO 0xF41600FF ++ ++/* AGC_RF_TH_H */ ++#define R367_QAM_AGC_RF_TH_H 0xF417 ++#define F367_QAM_AGC_RF_TH_HI 0xF417000F ++ ++/* AGC_IF_LTH_L */ ++#define R367_QAM_AGC_IF_LTH_L 0xF418 ++#define F367_QAM_AGC_IF_THLO_LO 0xF41800FF ++ ++/* AGC_IF_LTH_H */ ++#define R367_QAM_AGC_IF_LTH_H 0xF419 ++#define F367_QAM_AGC_IF_THLO_HI 0xF419000F ++ ++/* AGC_IF_HTH_L */ ++#define R367_QAM_AGC_IF_HTH_L 0xF41A ++#define F367_QAM_AGC_IF_THHI_LO 0xF41A00FF ++ ++/* AGC_IF_HTH_H */ ++#define R367_QAM_AGC_IF_HTH_H 0xF41B ++#define F367_QAM_AGC_IF_THHI_HI 0xF41B000F ++ ++/* AGC_PWR_RD_L */ ++#define R367_QAM_AGC_PWR_RD_L 0xF41C ++#define F367_QAM_AGC_PWR_WORD_LO 0xF41C00FF ++ ++/* AGC_PWR_RD_M */ ++#define R367_QAM_AGC_PWR_RD_M 0xF41D ++#define F367_QAM_AGC_PWR_WORD_ME 0xF41D00FF ++ ++/* AGC_PWR_RD_H */ ++#define R367_QAM_AGC_PWR_RD_H 0xF41E ++#define F367_QAM_AGC_PWR_WORD_HI 0xF41E0003 ++ ++/* AGC_PWM_IFCMD_L */ ++#define R367_QAM_AGC_PWM_IFCMD_L 0xF420 ++#define F367_QAM_AGC_IF_PWMCMD_LO 0xF42000FF ++ ++/* AGC_PWM_IFCMD_H */ ++#define R367_QAM_AGC_PWM_IFCMD_H 0xF421 ++#define F367_QAM_AGC_IF_PWMCMD_HI 0xF421000F ++ ++/* AGC_PWM_RFCMD_L */ ++#define R367_QAM_AGC_PWM_RFCMD_L 0xF422 ++#define F367_QAM_AGC_RF_PWMCMD_LO 0xF42200FF ++ ++/* AGC_PWM_RFCMD_H */ ++#define R367_QAM_AGC_PWM_RFCMD_H 0xF423 ++#define F367_QAM_AGC_RF_PWMCMD_HI 0xF423000F ++ ++/* IQDEM_CFG */ ++#define R367_QAM_IQDEM_CFG 0xF424 ++#define F367_QAM_IQDEM_CLK_SEL 0xF4240004 ++#define F367_QAM_IQDEM_INVIQ 0xF4240002 ++#define F367_QAM_IQDEM_A2DTYPE 0xF4240001 ++ ++/* MIX_NCO_LL */ ++#define R367_QAM_MIX_NCO_LL 0xF425 ++#define F367_QAM_MIX_NCO_INC_LL 0xF42500FF ++ ++/* MIX_NCO_HL */ ++#define R367_QAM_MIX_NCO_HL 0xF426 ++#define F367_QAM_MIX_NCO_INC_HL 0xF42600FF ++ ++/* MIX_NCO_HH */ ++#define R367_QAM_MIX_NCO_HH 0xF427 ++#define F367_QAM_MIX_NCO_INVCNST 0xF4270080 ++#define F367_QAM_MIX_NCO_INC_HH 0xF427007F ++ ++/* SRC_NCO_LL */ ++#define R367_QAM_SRC_NCO_LL 0xF428 ++#define F367_QAM_SRC_NCO_INC_LL 0xF42800FF ++ ++/* SRC_NCO_LH */ ++#define R367_QAM_SRC_NCO_LH 0xF429 ++#define F367_QAM_SRC_NCO_INC_LH 0xF42900FF ++ ++/* SRC_NCO_HL */ ++#define R367_QAM_SRC_NCO_HL 0xF42A ++#define F367_QAM_SRC_NCO_INC_HL 0xF42A00FF ++ ++/* SRC_NCO_HH */ ++#define R367_QAM_SRC_NCO_HH 0xF42B ++#define F367_QAM_SRC_NCO_INC_HH 0xF42B007F ++ ++/* IQDEM_GAIN_SRC_L */ ++#define R367_QAM_IQDEM_GAIN_SRC_L 0xF42C ++#define F367_QAM_GAIN_SRC_LO 0xF42C00FF ++ ++/* IQDEM_GAIN_SRC_H */ ++#define R367_QAM_IQDEM_GAIN_SRC_H 0xF42D ++#define F367_QAM_GAIN_SRC_HI 0xF42D0003 ++ ++/* IQDEM_DCRM_CFG_LL */ ++#define R367_QAM_IQDEM_DCRM_CFG_LL 0xF430 ++#define F367_QAM_DCRM0_DCIN_L 0xF43000FF ++ ++/* IQDEM_DCRM_CFG_LH */ ++#define R367_QAM_IQDEM_DCRM_CFG_LH 0xF431 ++#define F367_QAM_DCRM1_I_DCIN_L 0xF43100FC ++#define F367_QAM_DCRM0_DCIN_H 0xF4310003 ++ ++/* IQDEM_DCRM_CFG_HL */ ++#define R367_QAM_IQDEM_DCRM_CFG_HL 0xF432 ++#define F367_QAM_DCRM1_Q_DCIN_L 0xF43200F0 ++#define F367_QAM_DCRM1_I_DCIN_H 0xF432000F ++ ++/* IQDEM_DCRM_CFG_HH */ ++#define R367_QAM_IQDEM_DCRM_CFG_HH 0xF433 ++#define F367_QAM_DCRM1_FRZ 0xF4330080 ++#define F367_QAM_DCRM0_FRZ 0xF4330040 ++#define F367_QAM_DCRM1_Q_DCIN_H 0xF433003F ++ ++/* IQDEM_ADJ_COEFF0 */ ++#define R367_QAM_IQDEM_ADJ_COEFF0 0xF434 ++#define F367_QAM_ADJIIR_COEFF10_L 0xF43400FF ++ ++/* IQDEM_ADJ_COEFF1 */ ++#define R367_QAM_IQDEM_ADJ_COEFF1 0xF435 ++#define F367_QAM_ADJIIR_COEFF11_L 0xF43500FC ++#define F367_QAM_ADJIIR_COEFF10_H 0xF4350003 ++ ++/* IQDEM_ADJ_COEFF2 */ ++#define R367_QAM_IQDEM_ADJ_COEFF2 0xF436 ++#define F367_QAM_ADJIIR_COEFF12_L 0xF43600F0 ++#define F367_QAM_ADJIIR_COEFF11_H 0xF436000F ++ ++/* IQDEM_ADJ_COEFF3 */ ++#define R367_QAM_IQDEM_ADJ_COEFF3 0xF437 ++#define F367_QAM_ADJIIR_COEFF20_L 0xF43700C0 ++#define F367_QAM_ADJIIR_COEFF12_H 0xF437003F ++ ++/* IQDEM_ADJ_COEFF4 */ ++#define R367_QAM_IQDEM_ADJ_COEFF4 0xF438 ++#define F367_QAM_ADJIIR_COEFF20_H 0xF43800FF ++ ++/* IQDEM_ADJ_COEFF5 */ ++#define R367_QAM_IQDEM_ADJ_COEFF5 0xF439 ++#define F367_QAM_ADJIIR_COEFF21_L 0xF43900FF ++ ++/* IQDEM_ADJ_COEFF6 */ ++#define R367_QAM_IQDEM_ADJ_COEFF6 0xF43A ++#define F367_QAM_ADJIIR_COEFF22_L 0xF43A00FC ++#define F367_QAM_ADJIIR_COEFF21_H 0xF43A0003 ++ ++/* IQDEM_ADJ_COEFF7 */ ++#define R367_QAM_IQDEM_ADJ_COEFF7 0xF43B ++#define F367_QAM_ADJIIR_COEFF22_H 0xF43B000F ++ ++/* IQDEM_ADJ_EN */ ++#define R367_QAM_IQDEM_ADJ_EN 0xF43C ++#define F367_QAM_ALLPASSFILT_EN 0xF43C0008 ++#define F367_QAM_ADJ_AGC_EN 0xF43C0004 ++#define F367_QAM_ADJ_COEFF_FRZ 0xF43C0002 ++#define F367_QAM_ADJ_EN 0xF43C0001 ++ ++/* IQDEM_ADJ_AGC_REF */ ++#define R367_QAM_IQDEM_ADJ_AGC_REF 0xF43D ++#define F367_QAM_ADJ_AGC_REF 0xF43D00FF ++ ++/* ALLPASSFILT1 */ ++#define R367_QAM_ALLPASSFILT1 0xF440 ++#define F367_QAM_ALLPASSFILT_COEFF1_LO 0xF44000FF ++ ++/* ALLPASSFILT2 */ ++#define R367_QAM_ALLPASSFILT2 0xF441 ++#define F367_QAM_ALLPASSFILT_COEFF1_ME 0xF44100FF ++ ++/* ALLPASSFILT3 */ ++#define R367_QAM_ALLPASSFILT3 0xF442 ++#define F367_QAM_ALLPASSFILT_COEFF2_LO 0xF44200C0 ++#define F367_QAM_ALLPASSFILT_COEFF1_HI 0xF442003F ++ ++/* ALLPASSFILT4 */ ++#define R367_QAM_ALLPASSFILT4 0xF443 ++#define F367_QAM_ALLPASSFILT_COEFF2_MEL 0xF44300FF ++ ++/* ALLPASSFILT5 */ ++#define R367_QAM_ALLPASSFILT5 0xF444 ++#define F367_QAM_ALLPASSFILT_COEFF2_MEH 0xF44400FF ++ ++/* ALLPASSFILT6 */ ++#define R367_QAM_ALLPASSFILT6 0xF445 ++#define F367_QAM_ALLPASSFILT_COEFF3_LO 0xF44500F0 ++#define F367_QAM_ALLPASSFILT_COEFF2_HI 0xF445000F ++ ++/* ALLPASSFILT7 */ ++#define R367_QAM_ALLPASSFILT7 0xF446 ++#define F367_QAM_ALLPASSFILT_COEFF3_MEL 0xF44600FF ++ ++/* ALLPASSFILT8 */ ++#define R367_QAM_ALLPASSFILT8 0xF447 ++#define F367_QAM_ALLPASSFILT_COEFF3_MEH 0xF44700FF ++ ++/* ALLPASSFILT9 */ ++#define R367_QAM_ALLPASSFILT9 0xF448 ++#define F367_QAM_ALLPASSFILT_COEFF4_LO 0xF44800FC ++#define F367_QAM_ALLPASSFILT_COEFF3_HI 0xF4480003 ++ ++/* ALLPASSFILT10 */ ++#define R367_QAM_ALLPASSFILT10 0xF449 ++#define F367_QAM_ALLPASSFILT_COEFF4_ME 0xF44900FF ++ ++/* ALLPASSFILT11 */ ++#define R367_QAM_ALLPASSFILT11 0xF44A ++#define F367_QAM_ALLPASSFILT_COEFF4_HI 0xF44A00FF ++ ++/* TRL_AGC_CFG */ ++#define R367_QAM_TRL_AGC_CFG 0xF450 ++#define F367_QAM_TRL_AGC_FREEZE 0xF4500080 ++#define F367_QAM_TRL_AGC_REF 0xF450007F ++ ++/* TRL_LPF_CFG */ ++#define R367_QAM_TRL_LPF_CFG 0xF454 ++#define F367_QAM_NYQPOINT_INV 0xF4540040 ++#define F367_QAM_TRL_SHIFT 0xF4540030 ++#define F367_QAM_NYQ_COEFF_SEL 0xF454000C ++#define F367_QAM_TRL_LPF_FREEZE 0xF4540002 ++#define F367_QAM_TRL_LPF_CRT 0xF4540001 ++ ++/* TRL_LPF_ACQ_GAIN */ ++#define R367_QAM_TRL_LPF_ACQ_GAIN 0xF455 ++#define F367_QAM_TRL_GDIR_ACQ 0xF4550070 ++#define F367_QAM_TRL_GINT_ACQ 0xF4550007 ++ ++/* TRL_LPF_TRK_GAIN */ ++#define R367_QAM_TRL_LPF_TRK_GAIN 0xF456 ++#define F367_QAM_TRL_GDIR_TRK 0xF4560070 ++#define F367_QAM_TRL_GINT_TRK 0xF4560007 ++ ++/* TRL_LPF_OUT_GAIN */ ++#define R367_QAM_TRL_LPF_OUT_GAIN 0xF457 ++#define F367_QAM_TRL_GAIN_OUT 0xF4570007 ++ ++/* TRL_LOCKDET_LTH */ ++#define R367_QAM_TRL_LOCKDET_LTH 0xF458 ++#define F367_QAM_TRL_LCK_THLO 0xF4580007 ++ ++/* TRL_LOCKDET_HTH */ ++#define R367_QAM_TRL_LOCKDET_HTH 0xF459 ++#define F367_QAM_TRL_LCK_THHI 0xF45900FF ++ ++/* TRL_LOCKDET_TRGVAL */ ++#define R367_QAM_TRL_LOCKDET_TRGVAL 0xF45A ++#define F367_QAM_TRL_LCK_TRG 0xF45A00FF ++ ++/* IQ_QAM */ ++#define R367_QAM_IQ_QAM 0xF45C ++#define F367_QAM_IQ_INPUT 0xF45C0008 ++#define F367_QAM_DETECT_MODE 0xF45C0007 ++ ++/* FSM_STATE */ ++#define R367_QAM_FSM_STATE 0xF460 ++#define F367_QAM_CRL_DFE 0xF4600080 ++#define F367_QAM_DFE_START 0xF4600040 ++#define F367_QAM_CTRLG_START 0xF4600030 ++#define F367_QAM_FSM_FORCESTATE 0xF460000F ++ ++/* FSM_CTL */ ++#define R367_QAM_FSM_CTL 0xF461 ++#define F367_QAM_FEC2_EN 0xF4610040 ++#define F367_QAM_SIT_EN 0xF4610020 ++#define F367_QAM_TRL_AHEAD 0xF4610010 ++#define F367_QAM_TRL2_EN 0xF4610008 ++#define F367_QAM_FSM_EQA1_EN 0xF4610004 ++#define F367_QAM_FSM_BKP_DIS 0xF4610002 ++#define F367_QAM_FSM_FORCE_EN 0xF4610001 ++ ++/* FSM_STS */ ++#define R367_QAM_FSM_STS 0xF462 ++#define F367_QAM_FSM_STATUS 0xF462000F ++ ++/* FSM_SNR0_HTH */ ++#define R367_QAM_FSM_SNR0_HTH 0xF463 ++#define F367_QAM_SNR0_HTH 0xF46300FF ++ ++/* FSM_SNR1_HTH */ ++#define R367_QAM_FSM_SNR1_HTH 0xF464 ++#define F367_QAM_SNR1_HTH 0xF46400FF ++ ++/* FSM_SNR2_HTH */ ++#define R367_QAM_FSM_SNR2_HTH 0xF465 ++#define F367_QAM_SNR2_HTH 0xF46500FF ++ ++/* FSM_SNR0_LTH */ ++#define R367_QAM_FSM_SNR0_LTH 0xF466 ++#define F367_QAM_SNR0_LTH 0xF46600FF ++ ++/* FSM_SNR1_LTH */ ++#define R367_QAM_FSM_SNR1_LTH 0xF467 ++#define F367_QAM_SNR1_LTH 0xF46700FF ++ ++/* FSM_EQA1_HTH */ ++#define R367_QAM_FSM_EQA1_HTH 0xF468 ++#define F367_QAM_SNR3_HTH_LO 0xF46800F0 ++#define F367_QAM_EQA1_HTH 0xF468000F ++ ++/* FSM_TEMPO */ ++#define R367_QAM_FSM_TEMPO 0xF469 ++#define F367_QAM_SIT 0xF46900C0 ++#define F367_QAM_WST 0xF4690038 ++#define F367_QAM_ELT 0xF4690006 ++#define F367_QAM_SNR3_HTH_HI 0xF4690001 ++ ++/* FSM_CONFIG */ ++#define R367_QAM_FSM_CONFIG 0xF46A ++#define F367_QAM_FEC2_DFEOFF 0xF46A0004 ++#define F367_QAM_PRIT_STATE 0xF46A0002 ++#define F367_QAM_MODMAP_STATE 0xF46A0001 ++ ++/* EQU_I_TESTTAP_L */ ++#define R367_QAM_EQU_I_TESTTAP_L 0xF474 ++#define F367_QAM_I_TEST_TAP_L 0xF47400FF ++ ++/* EQU_I_TESTTAP_M */ ++#define R367_QAM_EQU_I_TESTTAP_M 0xF475 ++#define F367_QAM_I_TEST_TAP_M 0xF47500FF ++ ++/* EQU_I_TESTTAP_H */ ++#define R367_QAM_EQU_I_TESTTAP_H 0xF476 ++#define F367_QAM_I_TEST_TAP_H 0xF476001F ++ ++/* EQU_TESTAP_CFG */ ++#define R367_QAM_EQU_TESTAP_CFG 0xF477 ++#define F367_QAM_TEST_FFE_DFE_SEL 0xF4770040 ++#define F367_QAM_TEST_TAP_SELECT 0xF477003F ++ ++/* EQU_Q_TESTTAP_L */ ++#define R367_QAM_EQU_Q_TESTTAP_L 0xF478 ++#define F367_QAM_Q_TEST_TAP_L 0xF47800FF ++ ++/* EQU_Q_TESTTAP_M */ ++#define R367_QAM_EQU_Q_TESTTAP_M 0xF479 ++#define F367_QAM_Q_TEST_TAP_M 0xF47900FF ++ ++/* EQU_Q_TESTTAP_H */ ++#define R367_QAM_EQU_Q_TESTTAP_H 0xF47A ++#define F367_QAM_Q_TEST_TAP_H 0xF47A001F ++ ++/* EQU_TAP_CTRL */ ++#define R367_QAM_EQU_TAP_CTRL 0xF47B ++#define F367_QAM_MTAP_FRZ 0xF47B0010 ++#define F367_QAM_PRE_FREEZE 0xF47B0008 ++#define F367_QAM_DFE_TAPMON_EN 0xF47B0004 ++#define F367_QAM_FFE_TAPMON_EN 0xF47B0002 ++#define F367_QAM_MTAP_ONLY 0xF47B0001 ++ ++/* EQU_CTR_CRL_CONTROL_L */ ++#define R367_QAM_EQU_CTR_CRL_CONTROL_L 0xF47C ++#define F367_QAM_EQU_CTR_CRL_CONTROL_LO 0xF47C00FF ++ ++/* EQU_CTR_CRL_CONTROL_H */ ++#define R367_QAM_EQU_CTR_CRL_CONTROL_H 0xF47D ++#define F367_QAM_EQU_CTR_CRL_CONTROL_HI 0xF47D00FF ++ ++/* EQU_CTR_HIPOW_L */ ++#define R367_QAM_EQU_CTR_HIPOW_L 0xF47E ++#define F367_QAM_CTR_HIPOW_L 0xF47E00FF ++ ++/* EQU_CTR_HIPOW_H */ ++#define R367_QAM_EQU_CTR_HIPOW_H 0xF47F ++#define F367_QAM_CTR_HIPOW_H 0xF47F00FF ++ ++/* EQU_I_EQU_LO */ ++#define R367_QAM_EQU_I_EQU_LO 0xF480 ++#define F367_QAM_EQU_I_EQU_L 0xF48000FF ++ ++/* EQU_I_EQU_HI */ ++#define R367_QAM_EQU_I_EQU_HI 0xF481 ++#define F367_QAM_EQU_I_EQU_H 0xF4810003 ++ ++/* EQU_Q_EQU_LO */ ++#define R367_QAM_EQU_Q_EQU_LO 0xF482 ++#define F367_QAM_EQU_Q_EQU_L 0xF48200FF ++ ++/* EQU_Q_EQU_HI */ ++#define R367_QAM_EQU_Q_EQU_HI 0xF483 ++#define F367_QAM_EQU_Q_EQU_H 0xF4830003 ++ ++/* EQU_MAPPER */ ++#define R367_QAM_EQU_MAPPER 0xF484 ++#define F367_QAM_QUAD_AUTO 0xF4840080 ++#define F367_QAM_QUAD_INV 0xF4840040 ++#define F367_QAM_QAM_MODE 0xF4840007 ++ ++/* EQU_SWEEP_RATE */ ++#define R367_QAM_EQU_SWEEP_RATE 0xF485 ++#define F367_QAM_SNR_PER 0xF48500C0 ++#define F367_QAM_SWEEP_RATE 0xF485003F ++ ++/* EQU_SNR_LO */ ++#define R367_QAM_EQU_SNR_LO 0xF486 ++#define F367_QAM_SNR_LO 0xF48600FF ++ ++/* EQU_SNR_HI */ ++#define R367_QAM_EQU_SNR_HI 0xF487 ++#define F367_QAM_SNR_HI 0xF48700FF ++ ++/* EQU_GAMMA_LO */ ++#define R367_QAM_EQU_GAMMA_LO 0xF488 ++#define F367_QAM_GAMMA_LO 0xF48800FF ++ ++/* EQU_GAMMA_HI */ ++#define R367_QAM_EQU_GAMMA_HI 0xF489 ++#define F367_QAM_GAMMA_ME 0xF48900FF ++ ++/* EQU_ERR_GAIN */ ++#define R367_QAM_EQU_ERR_GAIN 0xF48A ++#define F367_QAM_EQA1MU 0xF48A0070 ++#define F367_QAM_CRL2MU 0xF48A000E ++#define F367_QAM_GAMMA_HI 0xF48A0001 ++ ++/* EQU_RADIUS */ ++#define R367_QAM_EQU_RADIUS 0xF48B ++#define F367_QAM_RADIUS 0xF48B00FF ++ ++/* EQU_FFE_MAINTAP */ ++#define R367_QAM_EQU_FFE_MAINTAP 0xF48C ++#define F367_QAM_FFE_MAINTAP_INIT 0xF48C00FF ++ ++/* EQU_FFE_LEAKAGE */ ++#define R367_QAM_EQU_FFE_LEAKAGE 0xF48E ++#define F367_QAM_LEAK_PER 0xF48E00F0 ++#define F367_QAM_EQU_OUTSEL 0xF48E0002 ++#define F367_QAM_PNT2DFE 0xF48E0001 ++ ++/* EQU_FFE_MAINTAP_POS */ ++#define R367_QAM_EQU_FFE_MAINTAP_POS 0xF48F ++#define F367_QAM_FFE_LEAK_EN 0xF48F0080 ++#define F367_QAM_DFE_LEAK_EN 0xF48F0040 ++#define F367_QAM_FFE_MAINTAP_POS 0xF48F003F ++ ++/* EQU_GAIN_WIDE */ ++#define R367_QAM_EQU_GAIN_WIDE 0xF490 ++#define F367_QAM_DFE_GAIN_WIDE 0xF49000F0 ++#define F367_QAM_FFE_GAIN_WIDE 0xF490000F ++ ++/* EQU_GAIN_NARROW */ ++#define R367_QAM_EQU_GAIN_NARROW 0xF491 ++#define F367_QAM_DFE_GAIN_NARROW 0xF49100F0 ++#define F367_QAM_FFE_GAIN_NARROW 0xF491000F ++ ++/* EQU_CTR_LPF_GAIN */ ++#define R367_QAM_EQU_CTR_LPF_GAIN 0xF492 ++#define F367_QAM_CTR_GTO 0xF4920080 ++#define F367_QAM_CTR_GDIR 0xF4920070 ++#define F367_QAM_SWEEP_EN 0xF4920008 ++#define F367_QAM_CTR_GINT 0xF4920007 ++ ++/* EQU_CRL_LPF_GAIN */ ++#define R367_QAM_EQU_CRL_LPF_GAIN 0xF493 ++#define F367_QAM_CRL_GTO 0xF4930080 ++#define F367_QAM_CRL_GDIR 0xF4930070 ++#define F367_QAM_SWEEP_DIR 0xF4930008 ++#define F367_QAM_CRL_GINT 0xF4930007 ++ ++/* EQU_GLOBAL_GAIN */ ++#define R367_QAM_EQU_GLOBAL_GAIN 0xF494 ++#define F367_QAM_CRL_GAIN 0xF49400F8 ++#define F367_QAM_CTR_INC_GAIN 0xF4940004 ++#define F367_QAM_CTR_FRAC 0xF4940003 ++ ++/* EQU_CRL_LD_SEN */ ++#define R367_QAM_EQU_CRL_LD_SEN 0xF495 ++#define F367_QAM_CTR_BADPOINT_EN 0xF4950080 ++#define F367_QAM_CTR_GAIN 0xF4950070 ++#define F367_QAM_LIMANEN 0xF4950008 ++#define F367_QAM_CRL_LD_SEN 0xF4950007 ++ ++/* EQU_CRL_LD_VAL */ ++#define R367_QAM_EQU_CRL_LD_VAL 0xF496 ++#define F367_QAM_CRL_BISTH_LIMIT 0xF4960080 ++#define F367_QAM_CARE_EN 0xF4960040 ++#define F367_QAM_CRL_LD_PER 0xF4960030 ++#define F367_QAM_CRL_LD_WST 0xF496000C ++#define F367_QAM_CRL_LD_TFS 0xF4960003 ++ ++/* EQU_CRL_TFR */ ++#define R367_QAM_EQU_CRL_TFR 0xF497 ++#define F367_QAM_CRL_LD_TFR 0xF49700FF ++ ++/* EQU_CRL_BISTH_LO */ ++#define R367_QAM_EQU_CRL_BISTH_LO 0xF498 ++#define F367_QAM_CRL_BISTH_LO 0xF49800FF ++ ++/* EQU_CRL_BISTH_HI */ ++#define R367_QAM_EQU_CRL_BISTH_HI 0xF499 ++#define F367_QAM_CRL_BISTH_HI 0xF49900FF ++ ++/* EQU_SWEEP_RANGE_LO */ ++#define R367_QAM_EQU_SWEEP_RANGE_LO 0xF49A ++#define F367_QAM_SWEEP_RANGE_LO 0xF49A00FF ++ ++/* EQU_SWEEP_RANGE_HI */ ++#define R367_QAM_EQU_SWEEP_RANGE_HI 0xF49B ++#define F367_QAM_SWEEP_RANGE_HI 0xF49B00FF ++ ++/* EQU_CRL_LIMITER */ ++#define R367_QAM_EQU_CRL_LIMITER 0xF49C ++#define F367_QAM_BISECTOR_EN 0xF49C0080 ++#define F367_QAM_PHEST128_EN 0xF49C0040 ++#define F367_QAM_CRL_LIM 0xF49C003F ++ ++/* EQU_MODULUS_MAP */ ++#define R367_QAM_EQU_MODULUS_MAP 0xF49D ++#define F367_QAM_PNT_DEPTH 0xF49D00E0 ++#define F367_QAM_MODULUS_CMP 0xF49D001F ++ ++/* EQU_PNT_GAIN */ ++#define R367_QAM_EQU_PNT_GAIN 0xF49E ++#define F367_QAM_PNT_EN 0xF49E0080 ++#define F367_QAM_MODULUSMAP_EN 0xF49E0040 ++#define F367_QAM_PNT_GAIN 0xF49E003F ++ ++/* FEC_AC_CTR_0 */ ++#define R367_QAM_FEC_AC_CTR_0 0xF4A8 ++#define F367_QAM_BE_BYPASS 0xF4A80020 ++#define F367_QAM_REFRESH47 0xF4A80010 ++#define F367_QAM_CT_NBST 0xF4A80008 ++#define F367_QAM_TEI_ENA 0xF4A80004 ++#define F367_QAM_DS_ENA 0xF4A80002 ++#define F367_QAM_TSMF_EN 0xF4A80001 ++ ++/* FEC_AC_CTR_1 */ ++#define R367_QAM_FEC_AC_CTR_1 0xF4A9 ++#define F367_QAM_DEINT_DEPTH 0xF4A900FF ++ ++/* FEC_AC_CTR_2 */ ++#define R367_QAM_FEC_AC_CTR_2 0xF4AA ++#define F367_QAM_DEINT_M 0xF4AA00F8 ++#define F367_QAM_DIS_UNLOCK 0xF4AA0004 ++#define F367_QAM_DESCR_MODE 0xF4AA0003 ++ ++/* FEC_AC_CTR_3 */ ++#define R367_QAM_FEC_AC_CTR_3 0xF4AB ++#define F367_QAM_DI_UNLOCK 0xF4AB0080 ++#define F367_QAM_DI_FREEZE 0xF4AB0040 ++#define F367_QAM_MISMATCH 0xF4AB0030 ++#define F367_QAM_ACQ_MODE 0xF4AB000C ++#define F367_QAM_TRK_MODE 0xF4AB0003 ++ ++/* FEC_STATUS */ ++#define R367_QAM_FEC_STATUS 0xF4AC ++#define F367_QAM_DEINT_SMCNTR 0xF4AC00E0 ++#define F367_QAM_DEINT_SYNCSTATE 0xF4AC0018 ++#define F367_QAM_DEINT_SYNLOST 0xF4AC0004 ++#define F367_QAM_DESCR_SYNCSTATE 0xF4AC0002 ++ ++/* RS_COUNTER_0 */ ++#define R367_QAM_RS_COUNTER_0 0xF4AE ++#define F367_QAM_BK_CT_L 0xF4AE00FF ++ ++/* RS_COUNTER_1 */ ++#define R367_QAM_RS_COUNTER_1 0xF4AF ++#define F367_QAM_BK_CT_H 0xF4AF00FF ++ ++/* RS_COUNTER_2 */ ++#define R367_QAM_RS_COUNTER_2 0xF4B0 ++#define F367_QAM_CORR_CT_L 0xF4B000FF ++ ++/* RS_COUNTER_3 */ ++#define R367_QAM_RS_COUNTER_3 0xF4B1 ++#define F367_QAM_CORR_CT_H 0xF4B100FF ++ ++/* RS_COUNTER_4 */ ++#define R367_QAM_RS_COUNTER_4 0xF4B2 ++#define F367_QAM_UNCORR_CT_L 0xF4B200FF ++ ++/* RS_COUNTER_5 */ ++#define R367_QAM_RS_COUNTER_5 0xF4B3 ++#define F367_QAM_UNCORR_CT_H 0xF4B300FF ++ ++/* BERT_0 */ ++#define R367_QAM_BERT_0 0xF4B4 ++#define F367_QAM_RS_NOCORR 0xF4B40004 ++#define F367_QAM_CT_HOLD 0xF4B40002 ++#define F367_QAM_CT_CLEAR 0xF4B40001 ++ ++/* BERT_1 */ ++#define R367_QAM_BERT_1 0xF4B5 ++#define F367_QAM_BERT_ON 0xF4B50020 ++#define F367_QAM_BERT_ERR_SRC 0xF4B50010 ++#define F367_QAM_BERT_ERR_MODE 0xF4B50008 ++#define F367_QAM_BERT_NBYTE 0xF4B50007 ++ ++/* BERT_2 */ ++#define R367_QAM_BERT_2 0xF4B6 ++#define F367_QAM_BERT_ERRCOUNT_L 0xF4B600FF ++ ++/* BERT_3 */ ++#define R367_QAM_BERT_3 0xF4B7 ++#define F367_QAM_BERT_ERRCOUNT_H 0xF4B700FF ++ ++/* OUTFORMAT_0 */ ++#define R367_QAM_OUTFORMAT_0 0xF4B8 ++#define F367_QAM_CLK_POLARITY 0xF4B80080 ++#define F367_QAM_FEC_TYPE 0xF4B80040 ++#define F367_QAM_SYNC_STRIP 0xF4B80008 ++#define F367_QAM_TS_SWAP 0xF4B80004 ++#define F367_QAM_OUTFORMAT 0xF4B80003 ++ ++/* OUTFORMAT_1 */ ++#define R367_QAM_OUTFORMAT_1 0xF4B9 ++#define F367_QAM_CI_DIVRANGE 0xF4B900FF ++ ++/* SMOOTHER_2 */ ++#define R367_QAM_SMOOTHER_2 0xF4BE ++#define F367_QAM_FIFO_BYPASS 0xF4BE0020 ++ ++/* TSMF_CTRL_0 */ ++#define R367_QAM_TSMF_CTRL_0 0xF4C0 ++#define F367_QAM_TS_NUMBER 0xF4C0001E ++#define F367_QAM_SEL_MODE 0xF4C00001 ++ ++/* TSMF_CTRL_1 */ ++#define R367_QAM_TSMF_CTRL_1 0xF4C1 ++#define F367_QAM_CHECK_ERROR_BIT 0xF4C10080 ++#define F367_QAM_CHCK_F_SYNC 0xF4C10040 ++#define F367_QAM_H_MODE 0xF4C10008 ++#define F367_QAM_D_V_MODE 0xF4C10004 ++#define F367_QAM_MODE 0xF4C10003 ++ ++/* TSMF_CTRL_3 */ ++#define R367_QAM_TSMF_CTRL_3 0xF4C3 ++#define F367_QAM_SYNC_IN_COUNT 0xF4C300F0 ++#define F367_QAM_SYNC_OUT_COUNT 0xF4C3000F ++ ++/* TS_ON_ID_0 */ ++#define R367_QAM_TS_ON_ID_0 0xF4C4 ++#define F367_QAM_TS_ID_L 0xF4C400FF ++ ++/* TS_ON_ID_1 */ ++#define R367_QAM_TS_ON_ID_1 0xF4C5 ++#define F367_QAM_TS_ID_H 0xF4C500FF ++ ++/* TS_ON_ID_2 */ ++#define R367_QAM_TS_ON_ID_2 0xF4C6 ++#define F367_QAM_ON_ID_L 0xF4C600FF ++ ++/* TS_ON_ID_3 */ ++#define R367_QAM_TS_ON_ID_3 0xF4C7 ++#define F367_QAM_ON_ID_H 0xF4C700FF ++ ++/* RE_STATUS_0 */ ++#define R367_QAM_RE_STATUS_0 0xF4C8 ++#define F367_QAM_RECEIVE_STATUS_L 0xF4C800FF ++ ++/* RE_STATUS_1 */ ++#define R367_QAM_RE_STATUS_1 0xF4C9 ++#define F367_QAM_RECEIVE_STATUS_LH 0xF4C900FF ++ ++/* RE_STATUS_2 */ ++#define R367_QAM_RE_STATUS_2 0xF4CA ++#define F367_QAM_RECEIVE_STATUS_HL 0xF4CA00FF ++ ++/* RE_STATUS_3 */ ++#define R367_QAM_RE_STATUS_3 0xF4CB ++#define F367_QAM_RECEIVE_STATUS_HH 0xF4CB003F ++ ++/* TS_STATUS_0 */ ++#define R367_QAM_TS_STATUS_0 0xF4CC ++#define F367_QAM_TS_STATUS_L 0xF4CC00FF ++ ++/* TS_STATUS_1 */ ++#define R367_QAM_TS_STATUS_1 0xF4CD ++#define F367_QAM_TS_STATUS_H 0xF4CD007F ++ ++/* TS_STATUS_2 */ ++#define R367_QAM_TS_STATUS_2 0xF4CE ++#define F367_QAM_ERROR 0xF4CE0080 ++#define F367_QAM_EMERGENCY 0xF4CE0040 ++#define F367_QAM_CRE_TS 0xF4CE0030 ++#define F367_QAM_VER 0xF4CE000E ++#define F367_QAM_M_LOCK 0xF4CE0001 ++ ++/* TS_STATUS_3 */ ++#define R367_QAM_TS_STATUS_3 0xF4CF ++#define F367_QAM_UPDATE_READY 0xF4CF0080 ++#define F367_QAM_END_FRAME_HEADER 0xF4CF0040 ++#define F367_QAM_CONTCNT 0xF4CF0020 ++#define F367_QAM_TS_IDENTIFIER_SEL 0xF4CF000F ++ ++/* T_O_ID_0 */ ++#define R367_QAM_T_O_ID_0 0xF4D0 ++#define F367_QAM_ON_ID_I_L 0xF4D000FF ++ ++/* T_O_ID_1 */ ++#define R367_QAM_T_O_ID_1 0xF4D1 ++#define F367_QAM_ON_ID_I_H 0xF4D100FF ++ ++/* T_O_ID_2 */ ++#define R367_QAM_T_O_ID_2 0xF4D2 ++#define F367_QAM_TS_ID_I_L 0xF4D200FF ++ ++/* T_O_ID_3 */ ++#define R367_QAM_T_O_ID_3 0xF4D3 ++#define F367_QAM_TS_ID_I_H 0xF4D300FF ++ +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 0b2a934..ba93e7b 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3562,6 +3562,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) + return 0; + } + ++#if 0 + static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) + { + struct stv090x_state *state = fe->demodulator_priv; +@@ -3612,6 +3613,27 @@ err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; + } ++#endif ++ ++static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv090x_state *state = fe->demodulator_priv; ++ u32 reg, h, m, l; ++ ++ /* Counter 1: S1: 0x75 BER, S2: 0x67 PER */ ++ reg = STV090x_READ_DEMOD(state, ERRCNT12); ++ h = STV090x_GETFIELD_Px(reg, ERR_CNT12_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT11); ++ m = STV090x_GETFIELD_Px(reg, ERR_CNT11_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT10); ++ l = STV090x_GETFIELD_Px(reg, ERR_CNT10_FIELD); ++ ++ *ber = ((h << 16) | (m << 8) | l); ++ ++ return 0; ++} + + static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) + { +@@ -3732,6 +3754,26 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + return 0; + } + ++static int stv090x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct stv090x_state *state = fe->demodulator_priv; ++ u32 reg, h, m, l; ++ ++ /* Counter 2: 0xc1 TS error count */ ++ reg = STV090x_READ_DEMOD(state, ERRCNT22); ++ h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT21); ++ m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT20); ++ l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); ++ ++ *ucblocks = ((h << 16) | (m << 8) | l); ++ ++ return 0; ++} ++ + static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) + { + struct stv090x_state *state = fe->demodulator_priv; +@@ -4914,9 +4956,10 @@ static struct dvb_frontend_ops stv090x_ops = { + + .search = stv090x_search, + .read_status = stv090x_read_status, +- .read_ber = stv090x_read_per, ++ .read_ber = stv090x_read_ber, + .read_signal_strength = stv090x_read_signal_strength, + .read_snr = stv090x_read_cnr, ++ .read_ucblocks = stv090x_read_ucblocks, + }; + + +diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c +new file mode 100644 +index 0000000..d247932 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0910.c +@@ -0,0 +1,1371 @@ ++/* ++ * Driver for the ST STV0910 DVB-S/S2 demodulator. ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "stv0910.h" ++#include "stv0910_regs.h" ++ ++ ++#define TUNING_DELAY 200 ++#define BER_SRC_S 0x20 ++#define BER_SRC_S2 0x20 ++ ++LIST_HEAD(stvlist); ++ ++enum ReceiveMode { Mode_None, Mode_DVBS, Mode_DVBS2, Mode_Auto }; ++ ++ ++enum DVBS2_FECType { DVBS2_64K, DVBS2_16K }; ++ ++enum DVBS2_ModCod { ++ DVBS2_DUMMY_PLF, DVBS2_QPSK_1_4, DVBS2_QPSK_1_3, DVBS2_QPSK_2_5, ++ DVBS2_QPSK_1_2, DVBS2_QPSK_3_5, DVBS2_QPSK_2_3, DVBS2_QPSK_3_4, ++ DVBS2_QPSK_4_5, DVBS2_QPSK_5_6, DVBS2_QPSK_8_9, DVBS2_QPSK_9_10, ++ DVBS2_8PSK_3_5, DVBS2_8PSK_2_3, DVBS2_8PSK_3_4, DVBS2_8PSK_5_6, ++ DVBS2_8PSK_8_9, DVBS2_8PSK_9_10, DVBS2_16APSK_2_3, DVBS2_16APSK_3_4, ++ DVBS2_16APSK_4_5, DVBS2_16APSK_5_6, DVBS2_16APSK_8_9, DVBS2_16APSK_9_10, ++ DVBS2_32APSK_3_4, DVBS2_32APSK_4_5, DVBS2_32APSK_5_6, DVBS2_32APSK_8_9, ++ DVBS2_32APSK_9_10 ++}; ++ ++enum FE_STV0910_ModCod { ++ FE_DUMMY_PLF, FE_QPSK_14, FE_QPSK_13, FE_QPSK_25, ++ FE_QPSK_12, FE_QPSK_35, FE_QPSK_23, FE_QPSK_34, ++ FE_QPSK_45, FE_QPSK_56, FE_QPSK_89, FE_QPSK_910, ++ FE_8PSK_35, FE_8PSK_23, FE_8PSK_34, FE_8PSK_56, ++ FE_8PSK_89, FE_8PSK_910, FE_16APSK_23, FE_16APSK_34, ++ FE_16APSK_45, FE_16APSK_56, FE_16APSK_89, FE_16APSK_910, ++ FE_32APSK_34, FE_32APSK_45, FE_32APSK_56, FE_32APSK_89, ++ FE_32APSK_910 ++}; ++ ++enum FE_STV0910_RollOff { FE_SAT_35, FE_SAT_25, FE_SAT_20, FE_SAT_15 }; ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++struct stv_base { ++ struct list_head stvlist; ++ ++ u8 adr; ++ struct i2c_adapter *i2c; ++ struct mutex i2c_lock; ++ struct mutex reg_lock; ++ int count; ++ ++ u32 extclk; ++ u32 mclk; ++}; ++ ++struct stv { ++ struct stv_base *base; ++ struct dvb_frontend fe; ++ int nr; ++ u16 regoff; ++ u8 i2crpt; ++ u8 tscfgh; ++ u8 tsspeed; ++ unsigned long tune_time; ++ ++ s32 SearchRange; ++ u32 Started; ++ u32 DemodLockTime; ++ enum ReceiveMode ReceiveMode; ++ u32 DemodTimeout; ++ u32 FecTimeout; ++ u32 FirstTimeLock; ++ u8 DEMOD; ++ u32 SymbolRate; ++ ++ u8 LastViterbiRate; ++ enum fe_code_rate PunctureRate; ++ enum FE_STV0910_ModCod ModCod; ++ enum DVBS2_FECType FECType; ++ u32 Pilots; ++ enum FE_STV0910_RollOff FERollOff; ++ ++ u32 LastBERNumerator; ++ u32 LastBERDenominator; ++ u8 BERScale; ++}; ++ ++struct SInitTable { ++ u16 Address; ++ u8 Data; ++}; ++ ++struct SLookupSNTable { ++ s16 SignalToNoise; ++ u16 RefValue; ++}; ++ ++static inline int i2c_write(struct i2c_adapter *adap, u8 adr, ++ u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, u16 reg, u8 val) ++{ ++ u8 msg[3] = {reg >> 8, reg & 0xff, val}; ++ ++ return i2c_write(adap, adr, msg, 3); ++} ++ ++static int write_reg(struct stv *state, u16 reg, u8 val) ++{ ++ return i2c_write_reg16(state->base->i2c, state->base->adr, reg, val); ++} ++ ++static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int read_reg(struct stv *state, u16 reg, u8 *val) ++{ ++ return i2c_read_reg16(state->base->i2c, state->base->adr, reg, val); ++} ++ ++ ++static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val, int len) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int read_regs(struct stv *state, u16 reg, u8 *val, int len) ++{ ++ return i2c_read_regs16(state->base->i2c, state->base->adr, ++ reg, val, len); ++} ++ ++struct SLookupSNTable S1_SN_Lookup[] = { ++ { 0, 9242 }, /*C/N= 0dB*/ ++ { 05, 9105 }, /*C/N=0.5dB*/ ++ { 10, 8950 }, /*C/N=1.0dB*/ ++ { 15, 8780 }, /*C/N=1.5dB*/ ++ { 20, 8566 }, /*C/N=2.0dB*/ ++ { 25, 8366 }, /*C/N=2.5dB*/ ++ { 30, 8146 }, /*C/N=3.0dB*/ ++ { 35, 7908 }, /*C/N=3.5dB*/ ++ { 40, 7666 }, /*C/N=4.0dB*/ ++ { 45, 7405 }, /*C/N=4.5dB*/ ++ { 50, 7136 }, /*C/N=5.0dB*/ ++ { 55, 6861 }, /*C/N=5.5dB*/ ++ { 60, 6576 }, /*C/N=6.0dB*/ ++ { 65, 6330 }, /*C/N=6.5dB*/ ++ { 70, 6048 }, /*C/N=7.0dB*/ ++ { 75, 5768 }, /*C/N=7.5dB*/ ++ { 80, 5492 }, /*C/N=8.0dB*/ ++ { 85, 5224 }, /*C/N=8.5dB*/ ++ { 90, 4959 }, /*C/N=9.0dB*/ ++ { 95, 4709 }, /*C/N=9.5dB*/ ++ { 100, 4467 }, /*C/N=10.0dB*/ ++ { 105, 4236 }, /*C/N=10.5dB*/ ++ { 110, 4013 }, /*C/N=11.0dB*/ ++ { 115, 3800 }, /*C/N=11.5dB*/ ++ { 120, 3598 }, /*C/N=12.0dB*/ ++ { 125, 3406 }, /*C/N=12.5dB*/ ++ { 130, 3225 }, /*C/N=13.0dB*/ ++ { 135, 3052 }, /*C/N=13.5dB*/ ++ { 140, 2889 }, /*C/N=14.0dB*/ ++ { 145, 2733 }, /*C/N=14.5dB*/ ++ { 150, 2587 }, /*C/N=15.0dB*/ ++ { 160, 2318 }, /*C/N=16.0dB*/ ++ { 170, 2077 }, /*C/N=17.0dB*/ ++ { 180, 1862 }, /*C/N=18.0dB*/ ++ { 190, 1670 }, /*C/N=19.0dB*/ ++ { 200, 1499 }, /*C/N=20.0dB*/ ++ { 210, 1347 }, /*C/N=21.0dB*/ ++ { 220, 1213 }, /*C/N=22.0dB*/ ++ { 230, 1095 }, /*C/N=23.0dB*/ ++ { 240, 992 }, /*C/N=24.0dB*/ ++ { 250, 900 }, /*C/N=25.0dB*/ ++ { 260, 826 }, /*C/N=26.0dB*/ ++ { 270, 758 }, /*C/N=27.0dB*/ ++ { 280, 702 }, /*C/N=28.0dB*/ ++ { 290, 653 }, /*C/N=29.0dB*/ ++ { 300, 613 }, /*C/N=30.0dB*/ ++ { 310, 579 }, /*C/N=31.0dB*/ ++ { 320, 550 }, /*C/N=32.0dB*/ ++ { 330, 526 }, /*C/N=33.0dB*/ ++ { 350, 490 }, /*C/N=33.0dB*/ ++ { 400, 445 }, /*C/N=40.0dB*/ ++ { 450, 430 }, /*C/N=45.0dB*/ ++ { 500, 426 }, /*C/N=50.0dB*/ ++ { 510, 425 } /*C/N=51.0dB*/ ++}; ++ ++struct SLookupSNTable S2_SN_Lookup[] = { ++ { -30, 13950 }, /*C/N=-2.5dB*/ ++ { -25, 13580 }, /*C/N=-2.5dB*/ ++ { -20, 13150 }, /*C/N=-2.0dB*/ ++ { -15, 12760 }, /*C/N=-1.5dB*/ ++ { -10, 12345 }, /*C/N=-1.0dB*/ ++ { -05, 11900 }, /*C/N=-0.5dB*/ ++ { 0, 11520 }, /*C/N= 0dB*/ ++ { 05, 11080 }, /*C/N= 0.5dB*/ ++ { 10, 10630 }, /*C/N= 1.0dB*/ ++ { 15, 10210 }, /*C/N= 1.5dB*/ ++ { 20, 9790 }, /*C/N= 2.0dB*/ ++ { 25, 9390 }, /*C/N= 2.5dB*/ ++ { 30, 8970 }, /*C/N= 3.0dB*/ ++ { 35, 8575 }, /*C/N= 3.5dB*/ ++ { 40, 8180 }, /*C/N= 4.0dB*/ ++ { 45, 7800 }, /*C/N= 4.5dB*/ ++ { 50, 7430 }, /*C/N= 5.0dB*/ ++ { 55, 7080 }, /*C/N= 5.5dB*/ ++ { 60, 6720 }, /*C/N= 6.0dB*/ ++ { 65, 6320 }, /*C/N= 6.5dB*/ ++ { 70, 6060 }, /*C/N= 7.0dB*/ ++ { 75, 5760 }, /*C/N= 7.5dB*/ ++ { 80, 5480 }, /*C/N= 8.0dB*/ ++ { 85, 5200 }, /*C/N= 8.5dB*/ ++ { 90, 4930 }, /*C/N= 9.0dB*/ ++ { 95, 4680 }, /*C/N= 9.5dB*/ ++ { 100, 4425 }, /*C/N=10.0dB*/ ++ { 105, 4210 }, /*C/N=10.5dB*/ ++ { 110, 3980 }, /*C/N=11.0dB*/ ++ { 115, 3765 }, /*C/N=11.5dB*/ ++ { 120, 3570 }, /*C/N=12.0dB*/ ++ { 125, 3315 }, /*C/N=12.5dB*/ ++ { 130, 3140 }, /*C/N=13.0dB*/ ++ { 135, 2980 }, /*C/N=13.5dB*/ ++ { 140, 2820 }, /*C/N=14.0dB*/ ++ { 145, 2670 }, /*C/N=14.5dB*/ ++ { 150, 2535 }, /*C/N=15.0dB*/ ++ { 160, 2270 }, /*C/N=16.0dB*/ ++ { 170, 2035 }, /*C/N=17.0dB*/ ++ { 180, 1825 }, /*C/N=18.0dB*/ ++ { 190, 1650 }, /*C/N=19.0dB*/ ++ { 200, 1485 }, /*C/N=20.0dB*/ ++ { 210, 1340 }, /*C/N=21.0dB*/ ++ { 220, 1212 }, /*C/N=22.0dB*/ ++ { 230, 1100 }, /*C/N=23.0dB*/ ++ { 240, 1000 }, /*C/N=24.0dB*/ ++ { 250, 910 }, /*C/N=25.0dB*/ ++ { 260, 836 }, /*C/N=26.0dB*/ ++ { 270, 772 }, /*C/N=27.0dB*/ ++ { 280, 718 }, /*C/N=28.0dB*/ ++ { 290, 671 }, /*C/N=29.0dB*/ ++ { 300, 635 }, /*C/N=30.0dB*/ ++ { 310, 602 }, /*C/N=31.0dB*/ ++ { 320, 575 }, /*C/N=32.0dB*/ ++ { 330, 550 }, /*C/N=33.0dB*/ ++ { 350, 517 }, /*C/N=35.0dB*/ ++ { 400, 480 }, /*C/N=40.0dB*/ ++ { 450, 466 }, /*C/N=45.0dB*/ ++ { 500, 464 }, /*C/N=50.0dB*/ ++ { 510, 463 }, /*C/N=51.0dB*/ ++}; ++ ++/********************************************************************* ++Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame ++*********************************************************************/ ++static u8 S2CarLoop[] = { ++ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff ++ 20MPon 20MPoff 30MPon 30MPoff*/ ++ /* FE_QPSK_14 */ ++ 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x2A, 0x1C, 0x3A, 0x3B, ++ /* FE_QPSK_13 */ ++ 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, ++ /* FE_QPSK_25 */ ++ 0x1C, 0x3C, 0x1B, 0x3C, 0x3A, 0x1C, 0x3A, 0x3B, 0x3A, 0x2B, ++ /* FE_QPSK_12 */ ++ 0x0C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, ++ /* FE_QPSK_35 */ ++ 0x1C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, ++ /* FE_QPSK_23 */ ++ 0x2C, 0x2C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, ++ /* FE_QPSK_34 */ ++ 0x3C, 0x2C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, ++ /* FE_QPSK_45 */ ++ 0x0D, 0x3C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, ++ /* FE_QPSK_56 */ ++ 0x1D, 0x3C, 0x0C, 0x2C, 0x2B, 0x1C, 0x1B, 0x3B, 0x0B, 0x1B, ++ /* FE_QPSK_89 */ ++ 0x3D, 0x0D, 0x0C, 0x2C, 0x2B, 0x0C, 0x2B, 0x2B, 0x0B, 0x0B, ++ /* FE_QPSK_910 */ ++ 0x1E, 0x0D, 0x1C, 0x2C, 0x3B, 0x0C, 0x2B, 0x2B, 0x1B, 0x0B, ++ /* FE_8PSK_35 */ ++ 0x28, 0x09, 0x28, 0x09, 0x28, 0x09, 0x28, 0x08, 0x28, 0x27, ++ /* FE_8PSK_23 */ ++ 0x19, 0x29, 0x19, 0x29, 0x19, 0x29, 0x38, 0x19, 0x28, 0x09, ++ /* FE_8PSK_34 */ ++ 0x1A, 0x0B, 0x1A, 0x3A, 0x0A, 0x2A, 0x39, 0x2A, 0x39, 0x1A, ++ /* FE_8PSK_56 */ ++ 0x2B, 0x2B, 0x1B, 0x1B, 0x0B, 0x1B, 0x1A, 0x0B, 0x1A, 0x1A, ++ /* FE_8PSK_89 */ ++ 0x0C, 0x0C, 0x3B, 0x3B, 0x1B, 0x1B, 0x2A, 0x0B, 0x2A, 0x2A, ++ /* FE_8PSK_910 */ ++ 0x0C, 0x1C, 0x0C, 0x3B, 0x2B, 0x1B, 0x3A, 0x0B, 0x2A, 0x2A, ++ ++ /********************************************************************** ++ Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame ++ **********************************************************************/ ++ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon ++ 20MPoff 30MPon 30MPoff*/ ++ /* FE_16APSK_23 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x0A, 0x39, 0x0A, 0x29, 0x0A, ++ /* FE_16APSK_34 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0A, 0x2A, 0x0A, 0x1A, 0x0A, ++ /* FE_16APSK_45 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, ++ /* FE_16APSK_56 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, ++ /* FE_16APSK_89 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, ++ /* FE_16APSK_910 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, ++ /* FE_32APSK_34 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_45 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_56 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_89 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_910 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++}; ++ ++static u8 get_optim_cloop(struct stv *state, ++ enum FE_STV0910_ModCod ModCod, u32 Pilots) ++{ ++ int i = 0; ++ if (ModCod >= FE_32APSK_910) ++ i = ((int)FE_32APSK_910 - (int)FE_QPSK_14) * 10; ++ else if (ModCod >= FE_QPSK_14) ++ i = ((int)ModCod - (int)FE_QPSK_14) * 10; ++ ++ if (state->SymbolRate <= 3000000) ++ i += 0; ++ else if (state->SymbolRate <= 7000000) ++ i += 2; ++ else if (state->SymbolRate <= 15000000) ++ i += 4; ++ else if (state->SymbolRate <= 25000000) ++ i += 6; ++ else ++ i += 8; ++ ++ if (!Pilots) ++ i += 1; ++ ++ return S2CarLoop[i]; ++} ++ ++static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate) ++{ ++ int status = 0; ++ u8 SymbFreq0; ++ u8 SymbFreq1; ++ u8 SymbFreq2; ++ u8 SymbFreq3; ++ u8 TimOffs0; ++ u8 TimOffs1; ++ u8 TimOffs2; ++ u32 SymbolRate; ++ s32 TimingOffset; ++ ++ *pSymbolRate = 0; ++ if (!state->Started) ++ return status; ++ ++ read_reg(state, RSTV0910_P2_SFR3 + state->regoff, &SymbFreq3); ++ read_reg(state, RSTV0910_P2_SFR2 + state->regoff, &SymbFreq2); ++ read_reg(state, RSTV0910_P2_SFR1 + state->regoff, &SymbFreq1); ++ read_reg(state, RSTV0910_P2_SFR0 + state->regoff, &SymbFreq0); ++ read_reg(state, RSTV0910_P2_TMGREG2 + state->regoff, &TimOffs2); ++ read_reg(state, RSTV0910_P2_TMGREG1 + state->regoff, &TimOffs1); ++ read_reg(state, RSTV0910_P2_TMGREG0 + state->regoff, &TimOffs0); ++ ++ SymbolRate = ((u32) SymbFreq3 << 24) | ((u32) SymbFreq2 << 16) | ++ ((u32) SymbFreq1 << 8) | (u32) SymbFreq0; ++ TimingOffset = ((u32) TimOffs2 << 16) | ((u32) TimOffs1 << 8) | ++ (u32) TimOffs0; ++ ++ if ((TimingOffset & (1<<23)) != 0) ++ TimingOffset |= 0xFF000000; /* Sign extent */ ++ ++ SymbolRate = (u32) (((u64) SymbolRate * state->base->mclk) >> 32); ++ TimingOffset = (s32) (((s64) SymbolRate * (s64) TimingOffset) >> 29); ++ ++ *pSymbolRate = SymbolRate + TimingOffset; ++ ++ return 0; ++} ++ ++static int GetSignalParameters(struct stv *state) ++{ ++ if (!state->Started) ++ return -1; ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ u8 tmp; ++ u8 rolloff; ++ ++ read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); ++ state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2); ++ state->Pilots = (tmp & 0x01) != 0; ++ state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1); ++ ++ read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff); ++ rolloff = rolloff >> 6; ++ state->FERollOff = (enum FE_STV0910_RollOff) rolloff; ++ ++ } else if (state->ReceiveMode == Mode_DVBS) { ++ /* todo */ ++ } ++ return 0; ++} ++ ++static int TrackingOptimization(struct stv *state) ++{ ++ u32 SymbolRate = 0; ++ u8 tmp; ++ ++ GetCurSymbolRate(state, &SymbolRate); ++ read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, &tmp); ++ tmp &= ~0xC0; ++ ++ switch (state->ReceiveMode) { ++ case Mode_DVBS: ++ tmp |= 0x40; break; ++ case Mode_DVBS2: ++ tmp |= 0x80; break; ++ default: ++ tmp |= 0xC0; break; ++ } ++ write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp); ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ /* force to PRE BCH Rate */ ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ BER_SRC_S2 | state->BERScale); ++ ++ if (state->FECType == DVBS2_64K) { ++ u8 aclc = get_optim_cloop(state, state->ModCod, ++ state->Pilots); ++ ++ if (state->ModCod <= FE_QPSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, aclc); ++ } else if (state->ModCod <= FE_8PSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, 0x2a); ++ write_reg(state, RSTV0910_P2_ACLC2S28 + ++ state->regoff, aclc); ++ } else if (state->ModCod <= FE_16APSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, 0x2a); ++ write_reg(state, RSTV0910_P2_ACLC2S216A + ++ state->regoff, aclc); ++ } else if (state->ModCod <= FE_32APSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, 0x2a); ++ write_reg(state, RSTV0910_P2_ACLC2S232A + ++ state->regoff, aclc); ++ } ++ } ++ } ++ if (state->ReceiveMode == Mode_DVBS) { ++ u8 tmp; ++ ++ read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); ++ state->PunctureRate = FEC_NONE; ++ switch (tmp & 0x1F) { ++ case 0x0d: ++ state->PunctureRate = FEC_1_2; ++ break; ++ case 0x12: ++ state->PunctureRate = FEC_2_3; ++ break; ++ case 0x15: ++ state->PunctureRate = FEC_3_4; ++ break; ++ case 0x18: ++ state->PunctureRate = FEC_5_6; ++ break; ++ case 0x1A: ++ state->PunctureRate = FEC_7_8; ++ break; ++ } ++ } ++ return 0; ++} ++ ++static int GetSignalToNoise(struct stv *state, s32 *SignalToNoise) ++{ ++ int i; ++ u8 Data0; ++ u8 Data1; ++ u16 Data; ++ int nLookup; ++ struct SLookupSNTable *Lookup; ++ ++ *SignalToNoise = 0; ++ ++ if (!state->Started) ++ return 0; ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ read_reg(state, RSTV0910_P2_NNOSPLHT1 + state->regoff, &Data1); ++ read_reg(state, RSTV0910_P2_NNOSPLHT0 + state->regoff, &Data0); ++ nLookup = ARRAY_SIZE(S2_SN_Lookup); ++ Lookup = S2_SN_Lookup; ++ } else { ++ read_reg(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, &Data1); ++ read_reg(state, RSTV0910_P2_NNOSDATAT0 + state->regoff, &Data0); ++ nLookup = ARRAY_SIZE(S1_SN_Lookup); ++ Lookup = S1_SN_Lookup; ++ } ++ Data = (((u16)Data1) << 8) | (u16) Data0; ++ if (Data > Lookup[0].RefValue) { ++ *SignalToNoise = Lookup[0].SignalToNoise; ++ } else if (Data <= Lookup[nLookup-1].RefValue) { ++ *SignalToNoise = Lookup[nLookup-1].SignalToNoise; ++ } else { ++ for (i = 0; i < nLookup - 1; i += 1) { ++ if (Data <= Lookup[i].RefValue && ++ Data > Lookup[i+1].RefValue) { ++ *SignalToNoise = ++ (s32)(Lookup[i].SignalToNoise) + ++ ((s32)(Data - Lookup[i].RefValue) * ++ (s32)(Lookup[i+1].SignalToNoise - ++ Lookup[i].SignalToNoise)) / ++ ((s32)(Lookup[i+1].RefValue) - ++ (s32)(Lookup[i].RefValue)); ++ break; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int GetBitErrorRateS(struct stv *state, u32 *BERNumerator, ++ u32 *BERDenominator) ++{ ++ u8 Regs[3]; ++ ++ int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, ++ Regs, 3); ++ ++ if (status) ++ return -1; ++ ++ if ((Regs[0] & 0x80) == 0) { ++ state->LastBERDenominator = 1 << ((state->BERScale * 2) + ++ 10 + 3); ++ state->LastBERNumerator = ((u32) (Regs[0] & 0x7F) << 16) | ++ ((u32) Regs[1] << 8) | Regs[2]; ++ if (state->LastBERNumerator < 256 && state->BERScale < 6) { ++ state->BERScale += 1; ++ status = write_reg(state, RSTV0910_P2_ERRCTRL1 + ++ state->regoff, ++ 0x20 | state->BERScale); ++ } else if (state->LastBERNumerator > 1024 && ++ state->BERScale > 2) { ++ state->BERScale -= 1; ++ status = write_reg(state, RSTV0910_P2_ERRCTRL1 + ++ state->regoff, 0x20 | ++ state->BERScale); ++ } ++ } ++ *BERNumerator = state->LastBERNumerator; ++ *BERDenominator = state->LastBERDenominator; ++ return 0; ++} ++ ++static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType) ++{ ++ static u32 nBCH[][2] = { ++ {16200, 3240}, /* QPSK_1_4, */ ++ {21600, 5400}, /* QPSK_1_3, */ ++ {25920, 6480}, /* QPSK_2_5, */ ++ {32400, 7200}, /* QPSK_1_2, */ ++ {38880, 9720}, /* QPSK_3_5, */ ++ {43200, 10800}, /* QPSK_2_3, */ ++ {48600, 11880}, /* QPSK_3_4, */ ++ {51840, 12600}, /* QPSK_4_5, */ ++ {54000, 13320}, /* QPSK_5_6, */ ++ {57600, 14400}, /* QPSK_8_9, */ ++ {58320, 16000}, /* QPSK_9_10, */ ++ {43200, 9720}, /* 8PSK_3_5, */ ++ {48600, 10800}, /* 8PSK_2_3, */ ++ {51840, 11880}, /* 8PSK_3_4, */ ++ {54000, 13320}, /* 8PSK_5_6, */ ++ {57600, 14400}, /* 8PSK_8_9, */ ++ {58320, 16000}, /* 8PSK_9_10, */ ++ {43200, 10800}, /* 16APSK_2_3, */ ++ {48600, 11880}, /* 16APSK_3_4, */ ++ {51840, 12600}, /* 16APSK_4_5, */ ++ {54000, 13320}, /* 16APSK_5_6, */ ++ {57600, 14400}, /* 16APSK_8_9, */ ++ {58320, 16000}, /* 16APSK_9_10 */ ++ {48600, 11880}, /* 32APSK_3_4, */ ++ {51840, 12600}, /* 32APSK_4_5, */ ++ {54000, 13320}, /* 32APSK_5_6, */ ++ {57600, 14400}, /* 32APSK_8_9, */ ++ {58320, 16000}, /* 32APSK_9_10 */ ++ }; ++ ++ if (ModCod >= DVBS2_QPSK_1_4 && ++ ModCod <= DVBS2_32APSK_9_10 && FECType <= DVBS2_16K) ++ return nBCH[FECType][ModCod]; ++ return 64800; ++} ++ ++static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator, ++ u32 *BERDenominator) ++{ ++ u8 Regs[3]; ++ ++ int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, ++ Regs, 3); ++ ++ if (status) ++ return -1; ++ ++ if ((Regs[0] & 0x80) == 0) { ++ state->LastBERDenominator = ++ DVBS2_nBCH((enum DVBS2_ModCod) state->ModCod, ++ state->FECType) << ++ (state->BERScale * 2); ++ state->LastBERNumerator = (((u32) Regs[0] & 0x7F) << 16) | ++ ((u32) Regs[1] << 8) | Regs[2]; ++ if (state->LastBERNumerator < 256 && state->BERScale < 6) { ++ state->BERScale += 1; ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ 0x20 | state->BERScale); ++ } else if (state->LastBERNumerator > 1024 && ++ state->BERScale > 2) { ++ state->BERScale -= 1; ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ 0x20 | state->BERScale); ++ } ++ } ++ *BERNumerator = state->LastBERNumerator; ++ *BERDenominator = state->LastBERDenominator; ++ return status; ++} ++ ++static int GetBitErrorRate(struct stv *state, u32 *BERNumerator, ++ u32 *BERDenominator) ++{ ++ *BERNumerator = 0; ++ *BERDenominator = 1; ++ ++ switch (state->ReceiveMode) { ++ case Mode_DVBS: ++ return GetBitErrorRateS(state, BERNumerator, BERDenominator); ++ break; ++ case Mode_DVBS2: ++ return GetBitErrorRateS2(state, BERNumerator, BERDenominator); ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int init(struct dvb_frontend *fe) ++{ ++ return 0; ++} ++ ++static int set_mclock(struct stv *state, u32 MasterClock) ++{ ++ u32 idf = 1; ++ u32 odf = 4; ++ u32 quartz = state->base->extclk / 1000000; ++ u32 Fphi = MasterClock / 1000000; ++ u32 ndiv = (Fphi * odf * idf) / quartz; ++ u32 cp = 7; ++ u32 fvco; ++ ++ if (ndiv >= 7 && ndiv <= 71) ++ cp = 7; ++ else if (ndiv >= 72 && ndiv <= 79) ++ cp = 8; ++ else if (ndiv >= 80 && ndiv <= 87) ++ cp = 9; ++ else if (ndiv >= 88 && ndiv <= 95) ++ cp = 10; ++ else if (ndiv >= 96 && ndiv <= 103) ++ cp = 11; ++ else if (ndiv >= 104 && ndiv <= 111) ++ cp = 12; ++ else if (ndiv >= 112 && ndiv <= 119) ++ cp = 13; ++ else if (ndiv >= 120 && ndiv <= 127) ++ cp = 14; ++ else if (ndiv >= 128 && ndiv <= 135) ++ cp = 15; ++ else if (ndiv >= 136 && ndiv <= 143) ++ cp = 16; ++ else if (ndiv >= 144 && ndiv <= 151) ++ cp = 17; ++ else if (ndiv >= 152 && ndiv <= 159) ++ cp = 18; ++ else if (ndiv >= 160 && ndiv <= 167) ++ cp = 19; ++ else if (ndiv >= 168 && ndiv <= 175) ++ cp = 20; ++ else if (ndiv >= 176 && ndiv <= 183) ++ cp = 21; ++ else if (ndiv >= 184 && ndiv <= 191) ++ cp = 22; ++ else if (ndiv >= 192 && ndiv <= 199) ++ cp = 23; ++ else if (ndiv >= 200 && ndiv <= 207) ++ cp = 24; ++ else if (ndiv >= 208 && ndiv <= 215) ++ cp = 25; ++ else if (ndiv >= 216 && ndiv <= 223) ++ cp = 26; ++ else if (ndiv >= 224 && ndiv <= 225) ++ cp = 27; ++ ++ write_reg(state, RSTV0910_NCOARSE, (cp << 3) | idf); ++ write_reg(state, RSTV0910_NCOARSE2, odf); ++ write_reg(state, RSTV0910_NCOARSE1, ndiv); ++ ++ fvco = (quartz * 2 * ndiv) / idf; ++ state->base->mclk = fvco / (2 * odf) * 1000000; ++ ++ pr_info("ndiv = %d, MasterClock = %d\n", ndiv, state->base->mclk); ++ return 0; ++} ++ ++static int Stop(struct stv *state) ++{ ++ if (state->Started) { ++ u8 tmp; ++ ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh | 0x01); ++ read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); ++ tmp &= ~0x01; /*release reset DVBS2 packet delin*/ ++ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); ++ /* Blind optim*/ ++ write_reg(state, RSTV0910_P2_AGC2O + state->regoff, 0x5B); ++ /* Stop the demod */ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5c); ++ state->Started = 0; ++ } ++ state->ReceiveMode = Mode_None; ++ return 0; ++} ++ ++ ++static int Start(struct stv *state, struct dtv_frontend_properties *p) ++{ ++ s32 Freq; ++ u8 regDMDCFGMD; ++ u16 symb; ++ ++ if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) ++ return -EINVAL; ++ ++ state->ReceiveMode = Mode_None; ++ state->DemodLockTime = 0; ++ ++ /* Demod Stop*/ ++ if (state->Started) ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C); ++ ++ if (p->symbol_rate <= 1000000) { /*SR <=1Msps*/ ++ state->DemodTimeout = 3000; ++ state->FecTimeout = 2000; ++ } else if (p->symbol_rate <= 2000000) { /*1Msps < SR <=2Msps*/ ++ state->DemodTimeout = 2500; ++ state->FecTimeout = 1300; ++ } else if (p->symbol_rate <= 5000000) { /*2Msps< SR <=5Msps*/ ++ state->DemodTimeout = 1000; ++ state->FecTimeout = 650; ++ } else if (p->symbol_rate <= 10000000) { /*5Msps< SR <=10Msps*/ ++ state->DemodTimeout = 700; ++ state->FecTimeout = 350; ++ } else if (p->symbol_rate < 20000000) { /*10Msps< SR <=20Msps*/ ++ state->DemodTimeout = 400; ++ state->FecTimeout = 200; ++ } else { /*SR >=20Msps*/ ++ state->DemodTimeout = 300; ++ state->FecTimeout = 200; ++ } ++ ++ /* Set the Init Symbol rate*/ ++ symb = MulDiv32(p->symbol_rate, 65536, state->base->mclk); ++ write_reg(state, RSTV0910_P2_SFRINIT1 + state->regoff, ++ ((symb >> 8) & 0x7F)); ++ write_reg(state, RSTV0910_P2_SFRINIT0 + state->regoff, (symb & 0xFF)); ++ ++ pr_info("symb = %u\n", symb); ++ ++ state->DEMOD |= 0x80; ++ write_reg(state, RSTV0910_P2_DEMOD + state->regoff, state->DEMOD); ++ ++ /* FE_STV0910_SetSearchStandard */ ++ read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD); ++ write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ++ regDMDCFGMD |= 0xC0); ++ ++ /* Disable DSS */ ++ write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00); ++ write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F); ++ ++ /* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/ ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B); ++ write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A); ++ write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84); ++ write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84); ++ write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C); ++ /* Reset demod */ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); ++ ++ write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46); ++ ++ Freq = (state->SearchRange / 2000) + 600; ++ if (p->symbol_rate <= 5000000) ++ Freq -= (600 + 80); ++ Freq = (Freq << 16) / (state->base->mclk / 1000); ++ ++ write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff, ++ (Freq >> 8) & 0xff); ++ write_reg(state, RSTV0910_P2_CFRUP0 + state->regoff, (Freq & 0xff)); ++ /*CFR Low Setting*/ ++ Freq = -Freq; ++ write_reg(state, RSTV0910_P2_CFRLOW1 + state->regoff, ++ (Freq >> 8) & 0xff); ++ write_reg(state, RSTV0910_P2_CFRLOW0 + state->regoff, (Freq & 0xff)); ++ ++ /* init the demod frequency offset to 0 */ ++ write_reg(state, RSTV0910_P2_CFRINIT1 + state->regoff, 0); ++ write_reg(state, RSTV0910_P2_CFRINIT0 + state->regoff, 0); ++ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); ++ /* Trigger acq */ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x15); ++ ++ state->DemodLockTime += TUNING_DELAY; ++ state->Started = 1; ++ ++ return 0; ++} ++ ++static int init_diseqc(struct stv *state) ++{ ++ u16 offs = state->nr ? 0x40 : 0; /* Address offset */ ++ u8 Freq = ((state->base->mclk + 11000 * 32) / (22000 * 32)); ++ ++ /* Disable receiver */ ++ write_reg(state, RSTV0910_P1_DISRXCFG + offs, 0x00); ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0xBA); /* Reset = 1 */ ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); /* Reset = 0 */ ++ write_reg(state, RSTV0910_P1_DISTXF22 + offs, Freq); ++ return 0; ++} ++ ++static int probe(struct stv *state) ++{ ++ u8 id; ++ ++ state->ReceiveMode = Mode_None; ++ state->Started = 0; ++ ++ if (read_reg(state, RSTV0910_MID, &id) < 0) ++ return -1; ++ ++ if (id != 0x51) ++ return -EINVAL; ++ pr_info("Found STV0910 id=0x%02x\n", id); ++ ++ /* Configure the I2C repeater to off */ ++ write_reg(state, RSTV0910_P1_I2CRPT, 0x24); ++ /* Configure the I2C repeater to off */ ++ write_reg(state, RSTV0910_P2_I2CRPT, 0x24); ++ /* Set the I2C to oversampling ratio */ ++ write_reg(state, RSTV0910_I2CCFG, 0x88); ++ ++ write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */ ++ write_reg(state, RSTV0910_PADCFG, 0x05); /* RF AGC Pads Dev = 05 */ ++ write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ ++ write_reg(state, RSTV0910_TSGENERAL, 0x00); /* TSGENERAL */ ++ write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ ++ write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ ++ ++ ++ write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */ ++ write_reg(state, RSTV0910_TSTRES0, 0x00); ++ ++ set_mclock(state, 135000000); ++ ++ /* TS output */ ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh); ++ write_reg(state, RSTV0910_P1_TSCFGM , 0xC0); /* Manual speed */ ++ write_reg(state, RSTV0910_P1_TSCFGL , 0x20); ++ ++ /* Speed = 67.5 MHz */ ++ write_reg(state, RSTV0910_P1_TSSPEED , state->tsspeed); ++ ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh); ++ write_reg(state, RSTV0910_P2_TSCFGM , 0xC0); /* Manual speed */ ++ write_reg(state, RSTV0910_P2_TSCFGL , 0x20); ++ ++ /* Speed = 67.5 MHz */ ++ write_reg(state, RSTV0910_P2_TSSPEED , state->tsspeed); ++ ++ /* Reset stream merger */ ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh); ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh); ++ ++ write_reg(state, RSTV0910_P1_I2CRPT, state->i2crpt); ++ write_reg(state, RSTV0910_P2_I2CRPT, state->i2crpt); ++ ++ init_diseqc(state); ++ return 0; ++} ++ ++ ++static int gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u8 i2crpt = state->i2crpt & ~0x86; ++ ++ if (enable) ++ mutex_lock(&state->base->i2c_lock); ++ ++ if (enable) ++ i2crpt |= 0x80; ++ else ++ i2crpt |= 0x02; ++ ++ if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT : ++ RSTV0910_P1_I2CRPT, i2crpt) < 0) ++ return -EIO; ++ ++ state->i2crpt = i2crpt; ++ ++ if (!enable) ++ mutex_unlock(&state->base->i2c_lock); ++ return 0; ++} ++ ++static void release(struct dvb_frontend *fe) ++{ ++ struct stv *state = fe->demodulator_priv; ++ ++ state->base->count--; ++ if (state->base->count == 0) { ++ pr_info("remove STV base\n"); ++ list_del(&state->base->stvlist); ++ kfree(state->base); ++ } ++ kfree(state); ++} ++ ++static int set_parameters(struct dvb_frontend *fe) ++{ ++ int stat = 0; ++ struct stv *state = fe->demodulator_priv; ++ u32 IF; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ ++ Stop(state); ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe); ++ if (fe->ops.tuner_ops.get_if_frequency) ++ fe->ops.tuner_ops.get_if_frequency(fe, &IF); ++ state->SymbolRate = p->symbol_rate; ++ stat = Start(state, p); ++ return stat; ++} ++ ++ ++static int read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u8 DmdState = 0; ++ u8 DStatus = 0; ++ enum ReceiveMode CurReceiveMode = Mode_None; ++ u32 FECLock = 0; ++ ++ read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &DmdState); ++ ++ if (DmdState & 0x40) { ++ read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &DStatus); ++ if (DStatus & 0x08) ++ CurReceiveMode = (DmdState & 0x20) ? ++ Mode_DVBS : Mode_DVBS2; ++ } ++ if (CurReceiveMode == Mode_None) { ++ *status = 0; ++ return 0; ++ } ++ ++ *status |= 0x0f; ++ if (state->ReceiveMode == Mode_None) { ++ state->ReceiveMode = CurReceiveMode; ++ state->DemodLockTime = jiffies; ++ state->FirstTimeLock = 0; ++ ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh); ++ usleep_range(3000, 4000); ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh); ++ } ++ if (DmdState & 0x40) { ++ if (state->ReceiveMode == Mode_DVBS2) { ++ u8 PDELStatus; ++ read_reg(state, ++ RSTV0910_P2_PDELSTATUS1 + state->regoff, ++ &PDELStatus); ++ FECLock = (PDELStatus & 0x02) != 0; ++ } else { ++ u8 VStatus; ++ read_reg(state, ++ RSTV0910_P2_VSTATUSVIT + state->regoff, ++ &VStatus); ++ FECLock = (VStatus & 0x08) != 0; ++ } ++ } ++ ++ if (!FECLock) ++ return 0; ++ ++ *status |= 0x10; ++ ++ if (state->FirstTimeLock) { ++ u8 tmp; ++ ++ state->FirstTimeLock = 0; ++ GetSignalParameters(state); ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ /* FSTV0910_P2_MANUALSX_ROLLOFF, ++ FSTV0910_P2_MANUALS2_ROLLOFF = 0 */ ++ state->DEMOD &= ~0x84; ++ write_reg(state, RSTV0910_P2_DEMOD + state->regoff, ++ state->DEMOD); ++ read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, ++ &tmp); ++ /*reset DVBS2 packet delinator error counter */ ++ tmp |= 0x40; ++ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, ++ tmp); ++ /*reset DVBS2 packet delinator error counter */ ++ tmp &= ~0x40; ++ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, ++ tmp); ++ ++ state->BERScale = 2; ++ state->LastBERNumerator = 0; ++ state->LastBERDenominator = 1; ++ /* force to PRE BCH Rate */ ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ BER_SRC_S2 | state->BERScale); ++ } else { ++ state->BERScale = 2; ++ state->LastBERNumerator = 0; ++ state->LastBERDenominator = 1; ++ /* force to PRE RS Rate */ ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ BER_SRC_S | state->BERScale); ++ } ++ /*Reset the Total packet counter */ ++ write_reg(state, RSTV0910_P2_FBERCPT4 + state->regoff, 0x00); ++ /*Reset the packet Error counter2 (and Set it to ++ infinit error count mode )*/ ++ write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1); ++ ++ TrackingOptimization(state); ++ } ++ return 0; ++} ++ ++static int tune(struct dvb_frontend *fe, bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, fe_status_t *status) ++{ ++ struct stv *state = fe->demodulator_priv; ++ int r; ++ ++ if (re_tune) { ++ r = set_parameters(fe); ++ if (r) ++ return r; ++ state->tune_time = jiffies; ++ } ++ if (*status & FE_HAS_LOCK) ++ return 0; ++ *delay = HZ; ++ ++ r = read_status(fe, status); ++ if (r) ++ return r; ++ return 0; ++} ++ ++ ++static int get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ ++static int set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u16 offs = state->nr ? 0x40 : 0; ++ ++ switch (tone) { ++ case SEC_TONE_ON: ++ return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x38); ++ break; ++ case SEC_TONE_OFF: ++ return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3a); ++ break; ++ default: ++ break; ++ } ++ return -EINVAL; ++} ++ ++static int send_master_cmd(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *cmd) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u16 offs = state->nr ? 0x40 : 0; ++ int i; ++ ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E); ++ for (i = 0; i < cmd->msg_len; i++) ++ write_reg(state, RSTV0910_P1_DISTXFIFO + offs, cmd->msg[i]); ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); ++ return 0; ++} ++ ++static int recv_slave_reply(struct dvb_frontend *fe, ++ struct dvb_diseqc_slave_reply *reply) ++{ ++ return 0; ++} ++ ++static int send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) ++{ ++ return 0; ++} ++ ++static int sleep(struct dvb_frontend *fe) ++{ ++ struct stv *state = fe->demodulator_priv; ++ ++ pr_info("sleep %d\n", state->nr); ++ Stop(state); ++ return 0; ++} ++ ++static int read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct stv *state = fe->demodulator_priv; ++ s32 SNR; ++ ++ *snr = 0; ++ if (GetSignalToNoise(state, &SNR)) ++ return -EIO; ++ *snr = SNR; ++ return 0; ++} ++ ++static int read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u32 n, d; ++ ++ GetBitErrorRate(state, &n, &d); ++ if (d) ++ *ber = n / d; ++ else ++ *ber = 0; ++ return 0; ++} ++ ++static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u8 Agc1, Agc0; ++ ++ read_reg(state, RSTV0910_P2_AGCIQIN1 + state->regoff, &Agc1); ++ read_reg(state, RSTV0910_P2_AGCIQIN0 + state->regoff, &Agc0); ++ ++ *strength = ((255 - Agc1) * 3300) / 256; ++ return 0; ++} ++ ++static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ /* struct stv *state = fe->demodulator_priv; */ ++ ++ ++ return 0; ++} ++ ++static struct dvb_frontend_ops stv0910_ops = { ++ .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, ++ .info = { ++ .name = "STV0910", ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_stepsize = 0, ++ .frequency_tolerance = 0, ++ .symbol_rate_min = 1000000, ++ .symbol_rate_max = 70000000, ++ .caps = FE_CAN_INVERSION_AUTO | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | ++ FE_CAN_2G_MODULATION ++ }, ++ .init = init, ++ .sleep = sleep, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .get_frontend_algo = get_algo, ++ .tune = tune, ++ .read_status = read_status, ++ .set_tone = set_tone, ++ ++ .diseqc_send_master_cmd = send_master_cmd, ++ .diseqc_send_burst = send_burst, ++ .diseqc_recv_slave_reply = recv_slave_reply, ++ ++ .read_snr = read_snr, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_ucblocks = read_ucblocks, ++}; ++ ++static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) ++{ ++ struct stv_base *p; ++ ++ list_for_each_entry(p, &stvlist, stvlist) ++ if (p->i2c == i2c && p->adr == adr) ++ return p; ++ return NULL; ++} ++ ++struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ++ struct stv0910_cfg *cfg, ++ int nr) ++{ ++ struct stv *state; ++ struct stv_base *base; ++ ++ state = kzalloc(sizeof(struct stv), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ ++ state->tscfgh = 0x20 | (cfg->parallel ? 0 : 0x40); ++ state->i2crpt = 0x0A | ((cfg->rptlvl & 0x07) << 4); ++ state->tsspeed = 0x40; ++ state->nr = nr; ++ state->regoff = state->nr ? 0 : 0x200; ++ state->SearchRange = 16000000; ++ state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */ ++ state->ReceiveMode = Mode_None; ++ ++ base = match_base(i2c, cfg->adr); ++ if (base) { ++ base->count++; ++ state->base = base; ++ } else { ++ base = kzalloc(sizeof(struct stv_base), GFP_KERNEL); ++ if (!base) ++ goto fail; ++ base->i2c = i2c; ++ base->adr = cfg->adr; ++ base->count = 1; ++ base->extclk = cfg->clk ? cfg->clk : 30000000; ++ ++ mutex_init(&base->i2c_lock); ++ mutex_init(&base->reg_lock); ++ state->base = base; ++ if (probe(state) < 0) { ++ kfree(base); ++ goto fail; ++ } ++ list_add(&base->stvlist, &stvlist); ++ } ++ state->fe.ops = stv0910_ops; ++ state->fe.demodulator_priv = state; ++ state->nr = nr; ++ ++ return &state->fe; ++ ++fail: ++ kfree(state); ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(stv0910_attach); ++ ++MODULE_DESCRIPTION("STV0910 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb-frontends/stv0910.h b/drivers/media/dvb-frontends/stv0910.h +new file mode 100644 +index 0000000..a6fad29 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0910.h +@@ -0,0 +1,31 @@ ++#ifndef _STV0910_H_ ++#define _STV0910_H_ ++ ++#include ++#include ++ ++struct stv0910_cfg { ++ u32 clk; ++ u8 adr; ++ u8 parallel; ++ u8 rptlvl; ++}; ++ ++#if defined(CONFIG_DVB_STV0910) || \ ++ (defined(CONFIG_DVB_STV0910_MODULE) && defined(MODULE)) ++ ++extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ++ struct stv0910_cfg *cfg, int nr); ++#else ++ ++static inline struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ++ struct stv0910_cfg *cfg, ++ int nr) ++{ ++ pr_warn("%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++ ++#endif ++ ++#endif +diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h +new file mode 100644 +index 0000000..16e922f +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0910_regs.h +@@ -0,0 +1,3998 @@ ++// @DVB-S/DVB-S2 STMicroelectronics STV0900 register defintions ++// Author Manfred Völkel, August 2013 ++// (c) 2013 Digital Devices GmbH Germany. All rights reserved ++ ++// $Id: DD_STV0910Register.h 504 2013-09-02 23:02:14Z manfred $ ++ ++/* ======================================================================= ++-- Registers Declaration (Internal ST, All Applications ) ++-- ------------------------- ++-- Each register (RSTV0910__XXXXX) is defined by its address (2 bytes). ++-- ++-- Each field (FSTV0910__XXXXX)is defined as follow: ++-- [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte] ++ ======================================================================= */ ++ ++/*MID*/ ++#define RSTV0910_MID 0xf100 ++#define FSTV0910_MCHIP_IDENT 0xf10000f0 ++#define FSTV0910_MRELEASE 0xf100000f ++ ++/*DID*/ ++#define RSTV0910_DID 0xf101 ++#define FSTV0910_DEVICE_ID 0xf10100ff ++ ++/*DACR1*/ ++#define RSTV0910_DACR1 0xf113 ++#define FSTV0910_DAC_MODE 0xf11300e0 ++#define FSTV0910_DAC_VALUE1 0xf113000f ++ ++/*DACR2*/ ++#define RSTV0910_DACR2 0xf114 ++#define FSTV0910_DAC_VALUE0 0xf11400ff ++ ++/*PADCFG*/ ++#define RSTV0910_PADCFG 0xf11a ++#define FSTV0910_AGCRF2_OPD 0xf11a0008 ++#define FSTV0910_AGCRF2_XOR 0xf11a0004 ++#define FSTV0910_AGCRF1_OPD 0xf11a0002 ++#define FSTV0910_AGCRF1_XOR 0xf11a0001 ++ ++/*OUTCFG2*/ ++#define RSTV0910_OUTCFG2 0xf11b ++#define FSTV0910_TS2_ERROR_XOR 0xf11b0080 ++#define FSTV0910_TS2_DPN_XOR 0xf11b0040 ++#define FSTV0910_TS2_STROUT_XOR 0xf11b0020 ++#define FSTV0910_TS2_CLOCKOUT_XOR 0xf11b0010 ++#define FSTV0910_TS1_ERROR_XOR 0xf11b0008 ++#define FSTV0910_TS1_DPN_XOR 0xf11b0004 ++#define FSTV0910_TS1_STROUT_XOR 0xf11b0002 ++#define FSTV0910_TS1_CLOCKOUT_XOR 0xf11b0001 ++ ++/*OUTCFG*/ ++#define RSTV0910_OUTCFG 0xf11c ++#define FSTV0910_INV_DATA6 0xf11c0080 ++#define FSTV0910_TS2_OUTSER_HZ 0xf11c0020 ++#define FSTV0910_TS1_OUTSER_HZ 0xf11c0010 ++#define FSTV0910_TS2_OUTPAR_HZ 0xf11c0008 ++#define FSTV0910_TS1_OUTPAR_HZ 0xf11c0004 ++#define FSTV0910_TS_SERDATA0 0xf11c0002 ++ ++/*IRQSTATUS3*/ ++#define RSTV0910_IRQSTATUS3 0xf120 ++#define FSTV0910_SPLL_LOCK 0xf1200020 ++#define FSTV0910_SSTREAM_LCK_1 0xf1200010 ++#define FSTV0910_SSTREAM_LCK_2 0xf1200008 ++#define FSTV0910_SDVBS1_PRF_2 0xf1200002 ++#define FSTV0910_SDVBS1_PRF_1 0xf1200001 ++ ++/*IRQSTATUS2*/ ++#define RSTV0910_IRQSTATUS2 0xf121 ++#define FSTV0910_SSPY_ENDSIM_1 0xf1210080 ++#define FSTV0910_SSPY_ENDSIM_2 0xf1210040 ++#define FSTV0910_SPKTDEL_ERROR_2 0xf1210010 ++#define FSTV0910_SPKTDEL_LOCKB_2 0xf1210008 ++#define FSTV0910_SPKTDEL_LOCK_2 0xf1210004 ++#define FSTV0910_SPKTDEL_ERROR_1 0xf1210002 ++#define FSTV0910_SPKTDEL_LOCKB_1 0xf1210001 ++ ++/*IRQSTATUS1*/ ++#define RSTV0910_IRQSTATUS1 0xf122 ++#define FSTV0910_SPKTDEL_LOCK_1 0xf1220080 ++#define FSTV0910_SFEC_LOCKB_2 0xf1220040 ++#define FSTV0910_SFEC_LOCK_2 0xf1220020 ++#define FSTV0910_SFEC_LOCKB_1 0xf1220010 ++#define FSTV0910_SFEC_LOCK_1 0xf1220008 ++#define FSTV0910_SDEMOD_LOCKB_2 0xf1220004 ++#define FSTV0910_SDEMOD_LOCK_2 0xf1220002 ++#define FSTV0910_SDEMOD_IRQ_2 0xf1220001 ++ ++/*IRQSTATUS0*/ ++#define RSTV0910_IRQSTATUS0 0xf123 ++#define FSTV0910_SDEMOD_LOCKB_1 0xf1230080 ++#define FSTV0910_SDEMOD_LOCK_1 0xf1230040 ++#define FSTV0910_SDEMOD_IRQ_1 0xf1230020 ++#define FSTV0910_SBCH_ERRFLAG 0xf1230010 ++#define FSTV0910_SECW2_IRQ 0xf1230008 ++#define FSTV0910_SDISEQC2_IRQ 0xf1230004 ++#define FSTV0910_SECW1_IRQ 0xf1230002 ++#define FSTV0910_SDISEQC1_IRQ 0xf1230001 ++ ++/*IRQMASK3*/ ++#define RSTV0910_IRQMASK3 0xf124 ++#define FSTV0910_MPLL_LOCK 0xf1240020 ++#define FSTV0910_MSTREAM_LCK_1 0xf1240010 ++#define FSTV0910_MSTREAM_LCK_2 0xf1240008 ++#define FSTV0910_MDVBS1_PRF_2 0xf1240002 ++#define FSTV0910_MDVBS1_PRF_1 0xf1240001 ++ ++/*IRQMASK2*/ ++#define RSTV0910_IRQMASK2 0xf125 ++#define FSTV0910_MSPY_ENDSIM_1 0xf1250080 ++#define FSTV0910_MSPY_ENDSIM_2 0xf1250040 ++#define FSTV0910_MPKTDEL_ERROR_2 0xf1250010 ++#define FSTV0910_MPKTDEL_LOCKB_2 0xf1250008 ++#define FSTV0910_MPKTDEL_LOCK_2 0xf1250004 ++#define FSTV0910_MPKTDEL_ERROR_1 0xf1250002 ++#define FSTV0910_MPKTDEL_LOCKB_1 0xf1250001 ++ ++/*IRQMASK1*/ ++#define RSTV0910_IRQMASK1 0xf126 ++#define FSTV0910_MPKTDEL_LOCK_1 0xf1260080 ++#define FSTV0910_MFEC_LOCKB_2 0xf1260040 ++#define FSTV0910_MFEC_LOCK_2 0xf1260020 ++#define FSTV0910_MFEC_LOCKB_1 0xf1260010 ++#define FSTV0910_MFEC_LOCK_1 0xf1260008 ++#define FSTV0910_MDEMOD_LOCKB_2 0xf1260004 ++#define FSTV0910_MDEMOD_LOCK_2 0xf1260002 ++#define FSTV0910_MDEMOD_IRQ_2 0xf1260001 ++ ++/*IRQMASK0*/ ++#define RSTV0910_IRQMASK0 0xf127 ++#define FSTV0910_MDEMOD_LOCKB_1 0xf1270080 ++#define FSTV0910_MDEMOD_LOCK_1 0xf1270040 ++#define FSTV0910_MDEMOD_IRQ_1 0xf1270020 ++#define FSTV0910_MBCH_ERRFLAG 0xf1270010 ++#define FSTV0910_MECW2_IRQ 0xf1270008 ++#define FSTV0910_MDISEQC2_IRQ 0xf1270004 ++#define FSTV0910_MECW1_IRQ 0xf1270002 ++#define FSTV0910_MDISEQC1_IRQ 0xf1270001 ++ ++/*I2CCFG*/ ++#define RSTV0910_I2CCFG 0xf129 ++#define FSTV0910_I2C2_FASTMODE 0xf1290080 ++#define FSTV0910_STATUS_WR2 0xf1290040 ++#define FSTV0910_I2C2ADDR_INC 0xf1290030 ++#define FSTV0910_I2C_FASTMODE 0xf1290008 ++#define FSTV0910_STATUS_WR 0xf1290004 ++#define FSTV0910_I2CADDR_INC 0xf1290003 ++ ++/*P1_I2CRPT*/ ++#define RSTV0910_P1_I2CRPT 0xf12a ++#define FSTV0910_P1_I2CT_ON 0xf12a0080 ++#define FSTV0910_P1_ENARPT_LEVEL 0xf12a0070 ++#define FSTV0910_P1_SCLT_DELAY 0xf12a0008 ++#define FSTV0910_P1_STOP_ENABLE 0xf12a0004 ++#define FSTV0910_P1_STOP_SDAT2SDA 0xf12a0002 ++ ++/*P2_I2CRPT*/ ++#define RSTV0910_P2_I2CRPT 0xf12b ++#define FSTV0910_P2_I2CT_ON 0xf12b0080 ++#define FSTV0910_P2_ENARPT_LEVEL 0xf12b0070 ++#define FSTV0910_P2_SCLT_DELAY 0xf12b0008 ++#define FSTV0910_P2_STOP_ENABLE 0xf12b0004 ++#define FSTV0910_P2_STOP_SDAT2SDA 0xf12b0002 ++ ++/*GPIO0CFG*/ ++#define RSTV0910_GPIO0CFG 0xf140 ++#define FSTV0910_GPIO0_OPD 0xf1400080 ++#define FSTV0910_GPIO0_CONFIG 0xf140007e ++#define FSTV0910_GPIO0_XOR 0xf1400001 ++ ++/*GPIO1CFG*/ ++#define RSTV0910_GPIO1CFG 0xf141 ++#define FSTV0910_GPIO1_OPD 0xf1410080 ++#define FSTV0910_GPIO1_CONFIG 0xf141007e ++#define FSTV0910_GPIO1_XOR 0xf1410001 ++ ++/*GPIO2CFG*/ ++#define RSTV0910_GPIO2CFG 0xf142 ++#define FSTV0910_GPIO2_OPD 0xf1420080 ++#define FSTV0910_GPIO2_CONFIG 0xf142007e ++#define FSTV0910_GPIO2_XOR 0xf1420001 ++ ++/*GPIO3CFG*/ ++#define RSTV0910_GPIO3CFG 0xf143 ++#define FSTV0910_GPIO3_OPD 0xf1430080 ++#define FSTV0910_GPIO3_CONFIG 0xf143007e ++#define FSTV0910_GPIO3_XOR 0xf1430001 ++ ++/*GPIO4CFG*/ ++#define RSTV0910_GPIO4CFG 0xf144 ++#define FSTV0910_GPIO4_OPD 0xf1440080 ++#define FSTV0910_GPIO4_CONFIG 0xf144007e ++#define FSTV0910_GPIO4_XOR 0xf1440001 ++ ++/*GPIO5CFG*/ ++#define RSTV0910_GPIO5CFG 0xf145 ++#define FSTV0910_GPIO5_OPD 0xf1450080 ++#define FSTV0910_GPIO5_CONFIG 0xf145007e ++#define FSTV0910_GPIO5_XOR 0xf1450001 ++ ++/*GPIO6CFG*/ ++#define RSTV0910_GPIO6CFG 0xf146 ++#define FSTV0910_GPIO6_OPD 0xf1460080 ++#define FSTV0910_GPIO6_CONFIG 0xf146007e ++#define FSTV0910_GPIO6_XOR 0xf1460001 ++ ++/*GPIO7CFG*/ ++#define RSTV0910_GPIO7CFG 0xf147 ++#define FSTV0910_GPIO7_OPD 0xf1470080 ++#define FSTV0910_GPIO7_CONFIG 0xf147007e ++#define FSTV0910_GPIO7_XOR 0xf1470001 ++ ++/*GPIO8CFG*/ ++#define RSTV0910_GPIO8CFG 0xf148 ++#define FSTV0910_GPIO8_OPD 0xf1480080 ++#define FSTV0910_GPIO8_CONFIG 0xf148007e ++#define FSTV0910_GPIO8_XOR 0xf1480001 ++ ++/*GPIO9CFG*/ ++#define RSTV0910_GPIO9CFG 0xf149 ++#define FSTV0910_GPIO9_OPD 0xf1490080 ++#define FSTV0910_GPIO9_CONFIG 0xf149007e ++#define FSTV0910_GPIO9_XOR 0xf1490001 ++ ++/*GPIO10CFG*/ ++#define RSTV0910_GPIO10CFG 0xf14a ++#define FSTV0910_GPIO10_OPD 0xf14a0080 ++#define FSTV0910_GPIO10_CONFIG 0xf14a007e ++#define FSTV0910_GPIO10_XOR 0xf14a0001 ++ ++/*GPIO11CFG*/ ++#define RSTV0910_GPIO11CFG 0xf14b ++#define FSTV0910_GPIO11_OPD 0xf14b0080 ++#define FSTV0910_GPIO11_CONFIG 0xf14b007e ++#define FSTV0910_GPIO11_XOR 0xf14b0001 ++ ++/*GPIO12CFG*/ ++#define RSTV0910_GPIO12CFG 0xf14c ++#define FSTV0910_GPIO12_OPD 0xf14c0080 ++#define FSTV0910_GPIO12_CONFIG 0xf14c007e ++#define FSTV0910_GPIO12_XOR 0xf14c0001 ++ ++/*GPIO13CFG*/ ++#define RSTV0910_GPIO13CFG 0xf14d ++#define FSTV0910_GPIO13_OPD 0xf14d0080 ++#define FSTV0910_GPIO13_CONFIG 0xf14d007e ++#define FSTV0910_GPIO13_XOR 0xf14d0001 ++ ++/*GPIO14CFG*/ ++#define RSTV0910_GPIO14CFG 0xf14e ++#define FSTV0910_GPIO14_OPD 0xf14e0080 ++#define FSTV0910_GPIO14_CONFIG 0xf14e007e ++#define FSTV0910_GPIO14_XOR 0xf14e0001 ++ ++/*GPIO15CFG*/ ++#define RSTV0910_GPIO15CFG 0xf14f ++#define FSTV0910_GPIO15_OPD 0xf14f0080 ++#define FSTV0910_GPIO15_CONFIG 0xf14f007e ++#define FSTV0910_GPIO15_XOR 0xf14f0001 ++ ++/*GPIO16CFG*/ ++#define RSTV0910_GPIO16CFG 0xf150 ++#define FSTV0910_GPIO16_OPD 0xf1500080 ++#define FSTV0910_GPIO16_CONFIG 0xf150007e ++#define FSTV0910_GPIO16_XOR 0xf1500001 ++ ++/*GPIO17CFG*/ ++#define RSTV0910_GPIO17CFG 0xf151 ++#define FSTV0910_GPIO17_OPD 0xf1510080 ++#define FSTV0910_GPIO17_CONFIG 0xf151007e ++#define FSTV0910_GPIO17_XOR 0xf1510001 ++ ++/*GPIO18CFG*/ ++#define RSTV0910_GPIO18CFG 0xf152 ++#define FSTV0910_GPIO18_OPD 0xf1520080 ++#define FSTV0910_GPIO18_CONFIG 0xf152007e ++#define FSTV0910_GPIO18_XOR 0xf1520001 ++ ++/*GPIO19CFG*/ ++#define RSTV0910_GPIO19CFG 0xf153 ++#define FSTV0910_GPIO19_OPD 0xf1530080 ++#define FSTV0910_GPIO19_CONFIG 0xf153007e ++#define FSTV0910_GPIO19_XOR 0xf1530001 ++ ++/*GPIO20CFG*/ ++#define RSTV0910_GPIO20CFG 0xf154 ++#define FSTV0910_GPIO20_OPD 0xf1540080 ++#define FSTV0910_GPIO20_CONFIG 0xf154007e ++#define FSTV0910_GPIO20_XOR 0xf1540001 ++ ++/*GPIO21CFG*/ ++#define RSTV0910_GPIO21CFG 0xf155 ++#define FSTV0910_GPIO21_OPD 0xf1550080 ++#define FSTV0910_GPIO21_CONFIG 0xf155007e ++#define FSTV0910_GPIO21_XOR 0xf1550001 ++ ++/*GPIO22CFG*/ ++#define RSTV0910_GPIO22CFG 0xf156 ++#define FSTV0910_GPIO22_OPD 0xf1560080 ++#define FSTV0910_GPIO22_CONFIG 0xf156007e ++#define FSTV0910_GPIO22_XOR 0xf1560001 ++ ++/*STRSTATUS1*/ ++#define RSTV0910_STRSTATUS1 0xf16a ++#define FSTV0910_STRSTATUS_SEL2 0xf16a00f0 ++#define FSTV0910_STRSTATUS_SEL1 0xf16a000f ++ ++/*STRSTATUS2*/ ++#define RSTV0910_STRSTATUS2 0xf16b ++#define FSTV0910_STRSTATUS_SEL4 0xf16b00f0 ++#define FSTV0910_STRSTATUS_SEL3 0xf16b000f ++ ++/*STRSTATUS3*/ ++#define RSTV0910_STRSTATUS3 0xf16c ++#define FSTV0910_STRSTATUS_SEL6 0xf16c00f0 ++#define FSTV0910_STRSTATUS_SEL5 0xf16c000f ++ ++/*FSKTFC2*/ ++#define RSTV0910_FSKTFC2 0xf170 ++#define FSTV0910_FSKT_KMOD 0xf17000fc ++#define FSTV0910_FSKT_CAR2 0xf1700003 ++ ++/*FSKTFC1*/ ++#define RSTV0910_FSKTFC1 0xf171 ++#define FSTV0910_FSKT_CAR1 0xf17100ff ++ ++/*FSKTFC0*/ ++#define RSTV0910_FSKTFC0 0xf172 ++#define FSTV0910_FSKT_CAR0 0xf17200ff ++ ++/*FSKTDELTAF1*/ ++#define RSTV0910_FSKTDELTAF1 0xf173 ++#define FSTV0910_FSKT_DELTAF1 0xf173000f ++ ++/*FSKTDELTAF0*/ ++#define RSTV0910_FSKTDELTAF0 0xf174 ++#define FSTV0910_FSKT_DELTAF0 0xf17400ff ++ ++/*FSKTCTRL*/ ++#define RSTV0910_FSKTCTRL 0xf175 ++#define FSTV0910_FSKT_PINSEL 0xf1750080 ++#define FSTV0910_FSKT_EN_SGN 0xf1750040 ++#define FSTV0910_FSKT_MOD_SGN 0xf1750020 ++#define FSTV0910_FSKT_MOD_EN 0xf175001c ++#define FSTV0910_FSKT_DACMODE 0xf1750003 ++ ++/*FSKRFC2*/ ++#define RSTV0910_FSKRFC2 0xf176 ++#define FSTV0910_FSKR_DETSGN 0xf1760040 ++#define FSTV0910_FSKR_OUTSGN 0xf1760020 ++#define FSTV0910_FSKR_KAGC 0xf176001c ++#define FSTV0910_FSKR_CAR2 0xf1760003 ++ ++/*FSKRFC1*/ ++#define RSTV0910_FSKRFC1 0xf177 ++#define FSTV0910_FSKR_CAR1 0xf17700ff ++ ++/*FSKRFC0*/ ++#define RSTV0910_FSKRFC0 0xf178 ++#define FSTV0910_FSKR_CAR0 0xf17800ff ++ ++/*FSKRK1*/ ++#define RSTV0910_FSKRK1 0xf179 ++#define FSTV0910_FSKR_K1_EXP 0xf17900e0 ++#define FSTV0910_FSKR_K1_MANT 0xf179001f ++ ++/*FSKRK2*/ ++#define RSTV0910_FSKRK2 0xf17a ++#define FSTV0910_FSKR_K2_EXP 0xf17a00e0 ++#define FSTV0910_FSKR_K2_MANT 0xf17a001f ++ ++/*FSKRAGCR*/ ++#define RSTV0910_FSKRAGCR 0xf17b ++#define FSTV0910_FSKR_OUTCTL 0xf17b00c0 ++#define FSTV0910_FSKR_AGC_REF 0xf17b003f ++ ++/*FSKRAGC*/ ++#define RSTV0910_FSKRAGC 0xf17c ++#define FSTV0910_FSKR_AGC_ACCU 0xf17c00ff ++ ++/*FSKRALPHA*/ ++#define RSTV0910_FSKRALPHA 0xf17d ++#define FSTV0910_FSKR_ALPHA_EXP 0xf17d001c ++#define FSTV0910_FSKR_ALPHA_M 0xf17d0003 ++ ++/*FSKRPLTH1*/ ++#define RSTV0910_FSKRPLTH1 0xf17e ++#define FSTV0910_FSKR_BETA 0xf17e00f0 ++#define FSTV0910_FSKR_PLL_TRESH1 0xf17e000f ++ ++/*FSKRPLTH0*/ ++#define RSTV0910_FSKRPLTH0 0xf17f ++#define FSTV0910_FSKR_PLL_TRESH0 0xf17f00ff ++ ++/*FSKRDF1*/ ++#define RSTV0910_FSKRDF1 0xf180 ++#define FSTV0910_FSKR_OUT 0xf1800080 ++#define FSTV0910_FSKR_STATE 0xf1800060 ++#define FSTV0910_FSKR_DELTAF1 0xf180001f ++ ++/*FSKRDF0*/ ++#define RSTV0910_FSKRDF0 0xf181 ++#define FSTV0910_FSKR_DELTAF0 0xf18100ff ++ ++/*FSKRSTEPP*/ ++#define RSTV0910_FSKRSTEPP 0xf182 ++#define FSTV0910_FSKR_STEP_PLUS 0xf18200ff ++ ++/*FSKRSTEPM*/ ++#define RSTV0910_FSKRSTEPM 0xf183 ++#define FSTV0910_FSKR_STEP_MINUS 0xf18300ff ++ ++/*FSKRDET1*/ ++#define RSTV0910_FSKRDET1 0xf184 ++#define FSTV0910_FSKR_DETECT 0xf1840080 ++#define FSTV0910_FSKR_CARDET_ACCU1 0xf184000f ++ ++/*FSKRDET0*/ ++#define RSTV0910_FSKRDET0 0xf185 ++#define FSTV0910_FSKR_CARDET_ACCU0 0xf18500ff ++ ++/*FSKRDTH1*/ ++#define RSTV0910_FSKRDTH1 0xf186 ++#define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18600f0 ++#define FSTV0910_FSKR_CARDET_THRESH1 0xf186000f ++ ++/*FSKRDTH0*/ ++#define RSTV0910_FSKRDTH0 0xf187 ++#define FSTV0910_FSKR_CARDET_THRESH0 0xf18700ff ++ ++/*FSKRLOSS*/ ++#define RSTV0910_FSKRLOSS 0xf188 ++#define FSTV0910_FSKR_CARLOSS_THRESH0 0xf18800ff ++ ++/*NCOARSE*/ ++#define RSTV0910_NCOARSE 0xf1b3 ++#define FSTV0910_CP 0xf1b300f8 ++#define FSTV0910_IDF 0xf1b30007 ++ ++/*NCOARSE1*/ ++#define RSTV0910_NCOARSE1 0xf1b4 ++#define FSTV0910_N_DIV 0xf1b400ff ++ ++/*NCOARSE2*/ ++#define RSTV0910_NCOARSE2 0xf1b5 ++#define FSTV0910_ODF 0xf1b5003f ++ ++/*SYNTCTRL*/ ++#define RSTV0910_SYNTCTRL 0xf1b6 ++#define FSTV0910_STANDBY 0xf1b60080 ++#define FSTV0910_BYPASSPLLCORE 0xf1b60040 ++#define FSTV0910_STOP_PLL 0xf1b60008 ++#define FSTV0910_OSCI_E 0xf1b60002 ++ ++/*FILTCTRL*/ ++#define RSTV0910_FILTCTRL 0xf1b7 ++#define FSTV0910_INV_CLKFSK 0xf1b70002 ++#define FSTV0910_BYPASS_APPLI 0xf1b70001 ++ ++/*PLLSTAT*/ ++#define RSTV0910_PLLSTAT 0xf1b8 ++#define FSTV0910_PLL_BIST_END 0xf1b80004 ++#define FSTV0910_PLLLOCK 0xf1b80001 ++ ++/*STOPCLK1*/ ++#define RSTV0910_STOPCLK1 0xf1c2 ++#define FSTV0910_INV_CLKADCI2 0xf1c20004 ++#define FSTV0910_INV_CLKADCI1 0xf1c20001 ++ ++/*STOPCLK2*/ ++#define RSTV0910_STOPCLK2 0xf1c3 ++#define FSTV0910_STOP_DVBS2FEC2 0xf1c30020 ++#define FSTV0910_STOP_DVBS2FEC 0xf1c30010 ++#define FSTV0910_STOP_DVBS1FEC2 0xf1c30008 ++#define FSTV0910_STOP_DVBS1FEC 0xf1c30004 ++#define FSTV0910_STOP_DEMOD2 0xf1c30002 ++#define FSTV0910_STOP_DEMOD 0xf1c30001 ++ ++/*PREGCTL*/ ++#define RSTV0910_PREGCTL 0xf1c8 ++#define FSTV0910_REG3V3TO2V5_POFF 0xf1c80080 ++ ++/*TSTTNR0*/ ++#define RSTV0910_TSTTNR0 0xf1df ++#define FSTV0910_FSK_PON 0xf1df0004 ++#define FSTV0910_FSK_OPENLOOP 0xf1df0002 ++ ++/*TSTTNR1*/ ++#define RSTV0910_TSTTNR1 0xf1e0 ++#define FSTV0910_BYPASS_ADC1 0xf1e00080 ++#define FSTV0910_INVADC1_CKOUT 0xf1e00040 ++#define FSTV0910_SELIQSRC1 0xf1e00030 ++#define FSTV0910_DEMOD2_SELADC 0xf1e00008 ++#define FSTV0910_DEMOD1_SELADC 0xf1e00004 ++#define FSTV0910_ADC1_PON 0xf1e00002 ++ ++/*TSTTNR2*/ ++#define RSTV0910_TSTTNR2 0xf1e1 ++#define FSTV0910_I2C_DISEQC_BYPASS 0xf1e10080 ++#define FSTV0910_I2C_DISEQC_ENCH 0xf1e10040 ++#define FSTV0910_I2C_DISEQC_PON 0xf1e10020 ++#define FSTV0910_DISEQC_CLKDIV 0xf1e1000f ++ ++/*TSTTNR3*/ ++#define RSTV0910_TSTTNR3 0xf1e2 ++#define FSTV0910_BYPASS_ADC2 0xf1e20080 ++#define FSTV0910_INVADC2_CKOUT 0xf1e20040 ++#define FSTV0910_SELIQSRC2 0xf1e20030 ++#define FSTV0910_ADC2_PON 0xf1e20002 ++ ++/*P2_IQCONST*/ ++#define RSTV0910_P2_IQCONST 0xf200 ++#define FSTV0910_P2_CONSTEL_SELECT 0xf2000060 ++#define FSTV0910_P2_IQSYMB_SEL 0xf200001f ++ ++/*P2_NOSCFG*/ ++#define RSTV0910_P2_NOSCFG 0xf201 ++#define FSTV0910_P2_DIS_ACMRATIO 0xf2010080 ++#define FSTV0910_P2_NOSIN_EGALSEL 0xf2010040 ++#define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2010020 ++#define FSTV0910_P2_NOSPLH_BETA 0xf2010018 ++#define FSTV0910_P2_NOSDATA_BETA 0xf2010007 ++ ++/*P2_ISYMB*/ ++#define RSTV0910_P2_ISYMB 0xf202 ++#define FSTV0910_P2_I_SYMBOL 0xf20201ff ++ ++/*P2_QSYMB*/ ++#define RSTV0910_P2_QSYMB 0xf203 ++#define FSTV0910_P2_Q_SYMBOL 0xf20301ff ++ ++/*P2_AGC1CFG*/ ++#define RSTV0910_P2_AGC1CFG 0xf204 ++#define FSTV0910_P2_DC_FROZEN 0xf2040080 ++#define FSTV0910_P2_DC_CORRECT 0xf2040040 ++#define FSTV0910_P2_AMM_FROZEN 0xf2040020 ++#define FSTV0910_P2_AMM_CORRECT 0xf2040010 ++#define FSTV0910_P2_QUAD_FROZEN 0xf2040008 ++#define FSTV0910_P2_QUAD_CORRECT 0xf2040004 ++#define FSTV0910_P2_DCCOMP_SLOW 0xf2040002 ++#define FSTV0910_P2_IQMISM_SLOW 0xf2040001 ++ ++/*P2_AGC1CN*/ ++#define RSTV0910_P2_AGC1CN 0xf206 ++#define FSTV0910_P2_AGC1_LOCKED 0xf2060080 ++#define FSTV0910_P2_AGC1_OVERFLOW 0xf2060040 ++#define FSTV0910_P2_AGC1_NOSLOWLK 0xf2060020 ++#define FSTV0910_P2_AGC1_MINPOWER 0xf2060010 ++#define FSTV0910_P2_AGCOUT_FAST 0xf2060008 ++#define FSTV0910_P2_AGCIQ_BETA 0xf2060007 ++ ++/*P2_AGC1REF*/ ++#define RSTV0910_P2_AGC1REF 0xf207 ++#define FSTV0910_P2_AGCIQ_REF 0xf20700ff ++ ++/*P2_IDCCOMP*/ ++#define RSTV0910_P2_IDCCOMP 0xf208 ++#define FSTV0910_P2_IAVERAGE_ADJ 0xf20801ff ++ ++/*P2_QDCCOMP*/ ++#define RSTV0910_P2_QDCCOMP 0xf209 ++#define FSTV0910_P2_QAVERAGE_ADJ 0xf20901ff ++ ++/*P2_POWERI*/ ++#define RSTV0910_P2_POWERI 0xf20a ++#define FSTV0910_P2_POWER_I 0xf20a00ff ++ ++/*P2_POWERQ*/ ++#define RSTV0910_P2_POWERQ 0xf20b ++#define FSTV0910_P2_POWER_Q 0xf20b00ff ++ ++/*P2_AGC1AMM*/ ++#define RSTV0910_P2_AGC1AMM 0xf20c ++#define FSTV0910_P2_AMM_VALUE 0xf20c00ff ++ ++/*P2_AGC1QUAD*/ ++#define RSTV0910_P2_AGC1QUAD 0xf20d ++#define FSTV0910_P2_QUAD_VALUE 0xf20d01ff ++ ++/*P2_AGCIQIN1*/ ++#define RSTV0910_P2_AGCIQIN1 0xf20e ++#define FSTV0910_P2_AGCIQ_VALUE1 0xf20e00ff ++ ++/*P2_AGCIQIN0*/ ++#define RSTV0910_P2_AGCIQIN0 0xf20f ++#define FSTV0910_P2_AGCIQ_VALUE0 0xf20f00ff ++ ++/*P2_DEMOD*/ ++#define RSTV0910_P2_DEMOD 0xf210 ++#define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2100080 ++#define FSTV0910_P2_SPECINV_CONTROL 0xf2100030 ++#define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2100004 ++#define FSTV0910_P2_ROLLOFF_CONTROL 0xf2100003 ++ ++/*P2_DMDMODCOD*/ ++#define RSTV0910_P2_DMDMODCOD 0xf211 ++#define FSTV0910_P2_MANUAL_MODCOD 0xf2110080 ++#define FSTV0910_P2_DEMOD_MODCOD 0xf211007c ++#define FSTV0910_P2_DEMOD_TYPE 0xf2110003 ++ ++/*P2_DSTATUS*/ ++#define RSTV0910_P2_DSTATUS 0xf212 ++#define FSTV0910_P2_CAR_LOCK 0xf2120080 ++#define FSTV0910_P2_TMGLOCK_QUALITY 0xf2120060 ++#define FSTV0910_P2_SDVBS1_ENABLE 0xf2120010 ++#define FSTV0910_P2_LOCK_DEFINITIF 0xf2120008 ++#define FSTV0910_P2_TIMING_IS_LOCKED 0xf2120004 ++#define FSTV0910_P2_DEMOD_SYSCFG 0xf2120002 ++#define FSTV0910_P2_OVADC_DETECT 0xf2120001 ++ ++/*P2_DSTATUS2*/ ++#define RSTV0910_P2_DSTATUS2 0xf213 ++#define FSTV0910_P2_DEMOD_DELOCK 0xf2130080 ++#define FSTV0910_P2_DEMOD_TIMEOUT 0xf2130040 ++#define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2130020 ++#define FSTV0910_P2_POLYPH_SATEVENT 0xf2130010 ++#define FSTV0910_P2_AGC1_NOSIGNALACK 0xf2130008 ++#define FSTV0910_P2_AGC2_OVERFLOW 0xf2130004 ++#define FSTV0910_P2_CFR_OVERFLOW 0xf2130002 ++#define FSTV0910_P2_GAMMA_OVERUNDER 0xf2130001 ++ ++/*P2_DMDCFGMD*/ ++#define RSTV0910_P2_DMDCFGMD 0xf214 ++#define FSTV0910_P2_DVBS2_ENABLE 0xf2140080 ++#define FSTV0910_P2_DVBS1_ENABLE 0xf2140040 ++#define FSTV0910_P2_SCAN_ENABLE 0xf2140010 ++#define FSTV0910_P2_CFR_AUTOSCAN 0xf2140008 ++#define FSTV0910_P2_NOFORCE_RELOCK 0xf2140004 ++#define FSTV0910_P2_TUN_RNG 0xf2140003 ++ ++/*P2_DMDCFG2*/ ++#define RSTV0910_P2_DMDCFG2 0xf215 ++#define FSTV0910_P2_AGC1_WAITLOCK 0xf2150080 ++#define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2150040 ++#define FSTV0910_P2_BLINDPEA_MODE 0xf2150020 ++#define FSTV0910_P2_INFINITE_RELOCK 0xf2150010 ++#define FSTV0910_P2_BWOFFSET_COLDWARM 0xf2150008 ++#define FSTV0910_P2_TMGLOCK_NSCANSTOP 0xf2150004 ++#define FSTV0910_P2_COARSE_LK3MODE 0xf2150002 ++#define FSTV0910_P2_COARSE_LK2MODE 0xf2150001 ++ ++/*P2_DMDISTATE*/ ++#define RSTV0910_P2_DMDISTATE 0xf216 ++#define FSTV0910_P2_I2C_NORESETDMODE 0xf2160080 ++#define FSTV0910_P2_FORCE_ETAPED 0xf2160040 ++#define FSTV0910_P2_SDMDRST_DIRCLK 0xf2160020 ++#define FSTV0910_P2_I2C_DEMOD_MODE 0xf216001f ++ ++/*P2_DMDT0M*/ ++#define RSTV0910_P2_DMDT0M 0xf217 ++#define FSTV0910_P2_DMDT0_MIN 0xf21700ff ++ ++/*P2_DMDSTATE*/ ++#define RSTV0910_P2_DMDSTATE 0xf21b ++#define FSTV0910_P2_DEMOD_LOCKED 0xf21b0080 ++#define FSTV0910_P2_HEADER_MODE 0xf21b0060 ++#define FSTV0910_P2_DEMOD_MODE 0xf21b001f ++ ++/*P2_DMDFLYW*/ ++#define RSTV0910_P2_DMDFLYW 0xf21c ++#define FSTV0910_P2_I2C_IRQVAL 0xf21c00f0 ++#define FSTV0910_P2_FLYWHEEL_CPT 0xf21c000f ++ ++/*P2_DSTATUS3*/ ++#define RSTV0910_P2_DSTATUS3 0xf21d ++#define FSTV0910_P2_CFR_ZIGZAG 0xf21d0080 ++#define FSTV0910_P2_DEMOD_CFGMODE 0xf21d0060 ++#define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d0010 ++#define FSTV0910_P2_RELOCK_MODE 0xf21d0008 ++#define FSTV0910_P2_DEMOD_FAIL 0xf21d0004 ++#define FSTV0910_P2_ETAPE1A_DVBXMEM 0xf21d0003 ++ ++/*P2_DMDCFG3*/ ++#define RSTV0910_P2_DMDCFG3 0xf21e ++#define FSTV0910_P2_DVBS1_TMGWAIT 0xf21e0080 ++#define FSTV0910_P2_NO_BWCENTERING 0xf21e0040 ++#define FSTV0910_P2_INV_SEQSRCH 0xf21e0020 ++#define FSTV0910_P2_DIS_SFRUPLOW_TRK 0xf21e0010 ++#define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e0008 ++#define FSTV0910_P2_LOCKTIME_MODE 0xf21e0007 ++ ++/*P2_DMDCFG4*/ ++#define RSTV0910_P2_DMDCFG4 0xf21f ++#define FSTV0910_P2_DIS_VITLOCK 0xf21f0080 ++#define FSTV0910_P2_S1S2TOUT_FAST 0xf21f0040 ++#define FSTV0910_P2_DEMOD_FASTLOCK 0xf21f0020 ++#define FSTV0910_P2_S1HIER_ENABLE 0xf21f0010 ++#define FSTV0910_P2_TUNER_NRELAUNCH 0xf21f0008 ++#define FSTV0910_P2_DIS_CLKENABLE 0xf21f0004 ++#define FSTV0910_P2_DIS_HDRDIVLOCK 0xf21f0002 ++#define FSTV0910_P2_NO_TNRWBINIT 0xf21f0001 ++ ++/*P2_CORRELMANT*/ ++#define RSTV0910_P2_CORRELMANT 0xf220 ++#define FSTV0910_P2_CORREL_MANT 0xf22000ff ++ ++/*P2_CORRELABS*/ ++#define RSTV0910_P2_CORRELABS 0xf221 ++#define FSTV0910_P2_CORREL_ABS 0xf22100ff ++ ++/*P2_CORRELEXP*/ ++#define RSTV0910_P2_CORRELEXP 0xf222 ++#define FSTV0910_P2_CORREL_ABSEXP 0xf22200f0 ++#define FSTV0910_P2_CORREL_EXP 0xf222000f ++ ++/*P2_PLHMODCOD*/ ++#define RSTV0910_P2_PLHMODCOD 0xf224 ++#define FSTV0910_P2_SPECINV_DEMOD 0xf2240080 ++#define FSTV0910_P2_PLH_MODCOD 0xf224007c ++#define FSTV0910_P2_PLH_TYPE 0xf2240003 ++ ++/*P2_DMDREG*/ ++#define RSTV0910_P2_DMDREG 0xf225 ++#define FSTV0910_P2_EXTPSK_MODE 0xf2250080 ++#define FSTV0910_P2_HIER_SHORTFRAME 0xf2250002 ++#define FSTV0910_P2_DECIM_PLFRAMES 0xf2250001 ++ ++/*P2_AGC2O*/ ++#define RSTV0910_P2_AGC2O 0xf22c ++#define FSTV0910_P2_CSTENV_MODE 0xf22c00c0 ++#define FSTV0910_P2_AGC2_LKSQRT 0xf22c0020 ++#define FSTV0910_P2_AGC2_LKMODE 0xf22c0010 ++#define FSTV0910_P2_AGC2_LKEQUA 0xf22c0008 ++#define FSTV0910_P2_AGC2_COEF 0xf22c0007 ++ ++/*P2_AGC2REF*/ ++#define RSTV0910_P2_AGC2REF 0xf22d ++#define FSTV0910_P2_AGC2_REF 0xf22d00ff ++ ++/*P2_AGC1ADJ*/ ++#define RSTV0910_P2_AGC1ADJ 0xf22e ++#define FSTV0910_P2_AGC1ADJ_MANUAL 0xf22e0080 ++#define FSTV0910_P2_AGC1_ADJUSTED 0xf22e007f ++ ++/*P2_AGC2I1*/ ++#define RSTV0910_P2_AGC2I1 0xf236 ++#define FSTV0910_P2_AGC2_INTEGRATOR1 0xf23600ff ++ ++/*P2_AGC2I0*/ ++#define RSTV0910_P2_AGC2I0 0xf237 ++#define FSTV0910_P2_AGC2_INTEGRATOR0 0xf23700ff ++ ++/*P2_CARCFG*/ ++#define RSTV0910_P2_CARCFG 0xf238 ++#define FSTV0910_P2_CFRUPLOW_AUTO 0xf2380080 ++#define FSTV0910_P2_CFRUPLOW_TEST 0xf2380040 ++#define FSTV0910_P2_WIDE_FREQDET 0xf2380020 ++#define FSTV0910_P2_CARHDR_NODIV8 0xf2380010 ++#define FSTV0910_P2_I2C_ROTA 0xf2380008 ++#define FSTV0910_P2_ROTAON 0xf2380004 ++#define FSTV0910_P2_PH_DET_ALGO 0xf2380003 ++ ++/*P2_ACLC*/ ++#define RSTV0910_P2_ACLC 0xf239 ++#define FSTV0910_P2_CARS1_ANOSAUTO 0xf2390040 ++#define FSTV0910_P2_CAR_ALPHA_MANT 0xf2390030 ++#define FSTV0910_P2_CAR_ALPHA_EXP 0xf239000f ++ ++/*P2_BCLC*/ ++#define RSTV0910_P2_BCLC 0xf23a ++#define FSTV0910_P2_CARS1_BNOSAUTO 0xf23a0040 ++#define FSTV0910_P2_CAR_BETA_MANT 0xf23a0030 ++#define FSTV0910_P2_CAR_BETA_EXP 0xf23a000f ++ ++/*P2_CARFREQ*/ ++#define RSTV0910_P2_CARFREQ 0xf23d ++#define FSTV0910_P2_KC_COARSE_EXP 0xf23d00f0 ++#define FSTV0910_P2_BETA_FREQ 0xf23d000f ++ ++/*P2_CARHDR*/ ++#define RSTV0910_P2_CARHDR 0xf23e ++#define FSTV0910_P2_K_FREQ_HDR 0xf23e00ff ++ ++/*P2_LDT*/ ++#define RSTV0910_P2_LDT 0xf23f ++#define FSTV0910_P2_CARLOCK_THRES 0xf23f01ff ++ ++/*P2_LDT2*/ ++#define RSTV0910_P2_LDT2 0xf240 ++#define FSTV0910_P2_CARLOCK_THRES2 0xf24001ff ++ ++/*P2_CFRICFG*/ ++#define RSTV0910_P2_CFRICFG 0xf241 ++#define FSTV0910_P2_CFRINIT_UNVALRNG 0xf2410080 ++#define FSTV0910_P2_CFRINIT_LUNVALCPT 0xf2410040 ++#define FSTV0910_P2_CFRINIT_ABORTDBL 0xf2410020 ++#define FSTV0910_P2_CFRINIT_ABORTPRED 0xf2410010 ++#define FSTV0910_P2_CFRINIT_UNVALSKIP 0xf2410008 ++#define FSTV0910_P2_CFRINIT_CSTINC 0xf2410004 ++#define FSTV0910_P2_CFRIROLL_GARDER 0xf2410002 ++#define FSTV0910_P2_NEG_CFRSTEP 0xf2410001 ++ ++/*P2_CFRUP1*/ ++#define RSTV0910_P2_CFRUP1 0xf242 ++#define FSTV0910_P2_CFR_UP1 0xf24201ff ++ ++/*P2_CFRUP0*/ ++#define RSTV0910_P2_CFRUP0 0xf243 ++#define FSTV0910_P2_CFR_UP0 0xf24300ff ++ ++/*P2_CFRIBASE1*/ ++#define RSTV0910_P2_CFRIBASE1 0xf244 ++#define FSTV0910_P2_CFRINIT_BASE1 0xf24400ff ++ ++/*P2_CFRIBASE0*/ ++#define RSTV0910_P2_CFRIBASE0 0xf245 ++#define FSTV0910_P2_CFRINIT_BASE0 0xf24500ff ++ ++/*P2_CFRLOW1*/ ++#define RSTV0910_P2_CFRLOW1 0xf246 ++#define FSTV0910_P2_CFR_LOW1 0xf24601ff ++ ++/*P2_CFRLOW0*/ ++#define RSTV0910_P2_CFRLOW0 0xf247 ++#define FSTV0910_P2_CFR_LOW0 0xf24700ff ++ ++/*P2_CFRINIT1*/ ++#define RSTV0910_P2_CFRINIT1 0xf248 ++#define FSTV0910_P2_CFR_INIT1 0xf24801ff ++ ++/*P2_CFRINIT0*/ ++#define RSTV0910_P2_CFRINIT0 0xf249 ++#define FSTV0910_P2_CFR_INIT0 0xf24900ff ++ ++/*P2_CFRINC1*/ ++#define RSTV0910_P2_CFRINC1 0xf24a ++#define FSTV0910_P2_MANUAL_CFRINC 0xf24a0080 ++#define FSTV0910_P2_CFR_INC1 0xf24a003f ++ ++/*P2_CFRINC0*/ ++#define RSTV0910_P2_CFRINC0 0xf24b ++#define FSTV0910_P2_CFR_INC0 0xf24b00ff ++ ++/*P2_CFR2*/ ++#define RSTV0910_P2_CFR2 0xf24c ++#define FSTV0910_P2_CAR_FREQ2 0xf24c01ff ++ ++/*P2_CFR1*/ ++#define RSTV0910_P2_CFR1 0xf24d ++#define FSTV0910_P2_CAR_FREQ1 0xf24d00ff ++ ++/*P2_CFR0*/ ++#define RSTV0910_P2_CFR0 0xf24e ++#define FSTV0910_P2_CAR_FREQ0 0xf24e00ff ++ ++/*P2_LDI*/ ++#define RSTV0910_P2_LDI 0xf24f ++#define FSTV0910_P2_LOCK_DET_INTEGR 0xf24f01ff ++ ++/*P2_TMGCFG*/ ++#define RSTV0910_P2_TMGCFG 0xf250 ++#define FSTV0910_P2_TMGLOCK_BETA 0xf25000c0 ++#define FSTV0910_P2_DO_TIMING_CORR 0xf2500010 ++#define FSTV0910_P2_MANUAL_SCAN 0xf250000c ++#define FSTV0910_P2_TMG_MINFREQ 0xf2500003 ++ ++/*P2_RTC*/ ++#define RSTV0910_P2_RTC 0xf251 ++#define FSTV0910_P2_TMGALPHA_EXP 0xf25100f0 ++#define FSTV0910_P2_TMGBETA_EXP 0xf251000f ++ ++/*P2_RTCS2*/ ++#define RSTV0910_P2_RTCS2 0xf252 ++#define FSTV0910_P2_TMGALPHAS2_EXP 0xf25200f0 ++#define FSTV0910_P2_TMGBETAS2_EXP 0xf252000f ++ ++/*P2_TMGTHRISE*/ ++#define RSTV0910_P2_TMGTHRISE 0xf253 ++#define FSTV0910_P2_TMGLOCK_THRISE 0xf25300ff ++ ++/*P2_TMGTHFALL*/ ++#define RSTV0910_P2_TMGTHFALL 0xf254 ++#define FSTV0910_P2_TMGLOCK_THFALL 0xf25400ff ++ ++/*P2_SFRUPRATIO*/ ++#define RSTV0910_P2_SFRUPRATIO 0xf255 ++#define FSTV0910_P2_SFR_UPRATIO 0xf25500ff ++ ++/*P2_SFRLOWRATIO*/ ++#define RSTV0910_P2_SFRLOWRATIO 0xf256 ++#define FSTV0910_P2_SFR_LOWRATIO 0xf25600ff ++ ++/*P2_KTTMG*/ ++#define RSTV0910_P2_KTTMG 0xf257 ++#define FSTV0910_P2_KT_TMG_EXP 0xf25700f0 ++ ++/*P2_KREFTMG*/ ++#define RSTV0910_P2_KREFTMG 0xf258 ++#define FSTV0910_P2_KREF_TMG 0xf25800ff ++ ++/*P2_SFRSTEP*/ ++#define RSTV0910_P2_SFRSTEP 0xf259 ++#define FSTV0910_P2_SFR_SCANSTEP 0xf25900f0 ++#define FSTV0910_P2_SFR_CENTERSTEP 0xf259000f ++ ++/*P2_TMGCFG2*/ ++#define RSTV0910_P2_TMGCFG2 0xf25a ++#define FSTV0910_P2_KREFTMG2_DECMODE 0xf25a00c0 ++#define FSTV0910_P2_DIS_AUTOSAMP 0xf25a0008 ++#define FSTV0910_P2_SCANINIT_QUART 0xf25a0004 ++#define FSTV0910_P2_NOTMG_DVBS1DERAT 0xf25a0002 ++#define FSTV0910_P2_SFRRATIO_FINE 0xf25a0001 ++ ++/*P2_KREFTMG2*/ ++#define RSTV0910_P2_KREFTMG2 0xf25b ++#define FSTV0910_P2_KREF_TMG2 0xf25b00ff ++ ++/*P2_TMGCFG3*/ ++#define RSTV0910_P2_TMGCFG3 0xf25d ++#define FSTV0910_P2_CFRINC_MODE 0xf25d0070 ++#define FSTV0910_P2_CONT_TMGCENTER 0xf25d0008 ++#define FSTV0910_P2_AUTO_GUP 0xf25d0004 ++#define FSTV0910_P2_AUTO_GLOW 0xf25d0002 ++#define FSTV0910_P2_SFRVAL_MINMODE 0xf25d0001 ++ ++/*P2_SFRINIT1*/ ++#define RSTV0910_P2_SFRINIT1 0xf25e ++#define FSTV0910_P2_SFR_INIT1 0xf25e00ff ++ ++/*P2_SFRINIT0*/ ++#define RSTV0910_P2_SFRINIT0 0xf25f ++#define FSTV0910_P2_SFR_INIT0 0xf25f00ff ++ ++/*P2_SFRUP1*/ ++#define RSTV0910_P2_SFRUP1 0xf260 ++#define FSTV0910_P2_SYMB_FREQ_UP1 0xf26000ff ++ ++/*P2_SFRUP0*/ ++#define RSTV0910_P2_SFRUP0 0xf261 ++#define FSTV0910_P2_SYMB_FREQ_UP0 0xf26100ff ++ ++/*P2_SFRLOW1*/ ++#define RSTV0910_P2_SFRLOW1 0xf262 ++#define FSTV0910_P2_SYMB_FREQ_LOW1 0xf26200ff ++ ++/*P2_SFRLOW0*/ ++#define RSTV0910_P2_SFRLOW0 0xf263 ++#define FSTV0910_P2_SYMB_FREQ_LOW0 0xf26300ff ++ ++/*P2_SFR3*/ ++#define RSTV0910_P2_SFR3 0xf264 ++#define FSTV0910_P2_SYMB_FREQ3 0xf26400ff ++ ++/*P2_SFR2*/ ++#define RSTV0910_P2_SFR2 0xf265 ++#define FSTV0910_P2_SYMB_FREQ2 0xf26500ff ++ ++/*P2_SFR1*/ ++#define RSTV0910_P2_SFR1 0xf266 ++#define FSTV0910_P2_SYMB_FREQ1 0xf26600ff ++ ++/*P2_SFR0*/ ++#define RSTV0910_P2_SFR0 0xf267 ++#define FSTV0910_P2_SYMB_FREQ0 0xf26700ff ++ ++/*P2_TMGREG2*/ ++#define RSTV0910_P2_TMGREG2 0xf268 ++#define FSTV0910_P2_TMGREG2 0xf26800ff ++ ++/*P2_TMGREG1*/ ++#define RSTV0910_P2_TMGREG1 0xf269 ++#define FSTV0910_P2_TMGREG1 0xf26900ff ++ ++/*P2_TMGREG0*/ ++#define RSTV0910_P2_TMGREG0 0xf26a ++#define FSTV0910_P2_TMGREG0 0xf26a00ff ++ ++/*P2_TMGLOCK1*/ ++#define RSTV0910_P2_TMGLOCK1 0xf26b ++#define FSTV0910_P2_TMGLOCK_LEVEL1 0xf26b01ff ++ ++/*P2_TMGLOCK0*/ ++#define RSTV0910_P2_TMGLOCK0 0xf26c ++#define FSTV0910_P2_TMGLOCK_LEVEL0 0xf26c00ff ++ ++/*P2_TMGOBS*/ ++#define RSTV0910_P2_TMGOBS 0xf26d ++#define FSTV0910_P2_ROLLOFF_STATUS 0xf26d00c0 ++#define FSTV0910_P2_SCAN_SIGN 0xf26d0030 ++#define FSTV0910_P2_TMG_SCANNING 0xf26d0008 ++#define FSTV0910_P2_CHCENTERING_MODE 0xf26d0004 ++#define FSTV0910_P2_TMG_SCANFAIL 0xf26d0002 ++ ++/*P2_EQUALCFG*/ ++#define RSTV0910_P2_EQUALCFG 0xf26f ++#define FSTV0910_P2_NOTMG_NEGALWAIT 0xf26f0080 ++#define FSTV0910_P2_EQUAL_ON 0xf26f0040 ++#define FSTV0910_P2_SEL_EQUALCOR 0xf26f0038 ++#define FSTV0910_P2_MU_EQUALDFE 0xf26f0007 ++ ++/*P2_EQUAI1*/ ++#define RSTV0910_P2_EQUAI1 0xf270 ++#define FSTV0910_P2_EQUA_ACCI1 0xf27001ff ++ ++/*P2_EQUAQ1*/ ++#define RSTV0910_P2_EQUAQ1 0xf271 ++#define FSTV0910_P2_EQUA_ACCQ1 0xf27101ff ++ ++/*P2_EQUAI2*/ ++#define RSTV0910_P2_EQUAI2 0xf272 ++#define FSTV0910_P2_EQUA_ACCI2 0xf27201ff ++ ++/*P2_EQUAQ2*/ ++#define RSTV0910_P2_EQUAQ2 0xf273 ++#define FSTV0910_P2_EQUA_ACCQ2 0xf27301ff ++ ++/*P2_EQUAI3*/ ++#define RSTV0910_P2_EQUAI3 0xf274 ++#define FSTV0910_P2_EQUA_ACCI3 0xf27401ff ++ ++/*P2_EQUAQ3*/ ++#define RSTV0910_P2_EQUAQ3 0xf275 ++#define FSTV0910_P2_EQUA_ACCQ3 0xf27501ff ++ ++/*P2_EQUAI4*/ ++#define RSTV0910_P2_EQUAI4 0xf276 ++#define FSTV0910_P2_EQUA_ACCI4 0xf27601ff ++ ++/*P2_EQUAQ4*/ ++#define RSTV0910_P2_EQUAQ4 0xf277 ++#define FSTV0910_P2_EQUA_ACCQ4 0xf27701ff ++ ++/*P2_EQUAI5*/ ++#define RSTV0910_P2_EQUAI5 0xf278 ++#define FSTV0910_P2_EQUA_ACCI5 0xf27801ff ++ ++/*P2_EQUAQ5*/ ++#define RSTV0910_P2_EQUAQ5 0xf279 ++#define FSTV0910_P2_EQUA_ACCQ5 0xf27901ff ++ ++/*P2_EQUAI6*/ ++#define RSTV0910_P2_EQUAI6 0xf27a ++#define FSTV0910_P2_EQUA_ACCI6 0xf27a01ff ++ ++/*P2_EQUAQ6*/ ++#define RSTV0910_P2_EQUAQ6 0xf27b ++#define FSTV0910_P2_EQUA_ACCQ6 0xf27b01ff ++ ++/*P2_EQUAI7*/ ++#define RSTV0910_P2_EQUAI7 0xf27c ++#define FSTV0910_P2_EQUA_ACCI7 0xf27c01ff ++ ++/*P2_EQUAQ7*/ ++#define RSTV0910_P2_EQUAQ7 0xf27d ++#define FSTV0910_P2_EQUA_ACCQ7 0xf27d01ff ++ ++/*P2_EQUAI8*/ ++#define RSTV0910_P2_EQUAI8 0xf27e ++#define FSTV0910_P2_EQUA_ACCI8 0xf27e01ff ++ ++/*P2_EQUAQ8*/ ++#define RSTV0910_P2_EQUAQ8 0xf27f ++#define FSTV0910_P2_EQUA_ACCQ8 0xf27f01ff ++ ++/*P2_NNOSDATAT1*/ ++#define RSTV0910_P2_NNOSDATAT1 0xf280 ++#define FSTV0910_P2_NOSDATAT_NORMED1 0xf28000ff ++ ++/*P2_NNOSDATAT0*/ ++#define RSTV0910_P2_NNOSDATAT0 0xf281 ++#define FSTV0910_P2_NOSDATAT_NORMED0 0xf28100ff ++ ++/*P2_NNOSDATA1*/ ++#define RSTV0910_P2_NNOSDATA1 0xf282 ++#define FSTV0910_P2_NOSDATA_NORMED1 0xf28200ff ++ ++/*P2_NNOSDATA0*/ ++#define RSTV0910_P2_NNOSDATA0 0xf283 ++#define FSTV0910_P2_NOSDATA_NORMED0 0xf28300ff ++ ++/*P2_NNOSPLHT1*/ ++#define RSTV0910_P2_NNOSPLHT1 0xf284 ++#define FSTV0910_P2_NOSPLHT_NORMED1 0xf28400ff ++ ++/*P2_NNOSPLHT0*/ ++#define RSTV0910_P2_NNOSPLHT0 0xf285 ++#define FSTV0910_P2_NOSPLHT_NORMED0 0xf28500ff ++ ++/*P2_NNOSPLH1*/ ++#define RSTV0910_P2_NNOSPLH1 0xf286 ++#define FSTV0910_P2_NOSPLH_NORMED1 0xf28600ff ++ ++/*P2_NNOSPLH0*/ ++#define RSTV0910_P2_NNOSPLH0 0xf287 ++#define FSTV0910_P2_NOSPLH_NORMED0 0xf28700ff ++ ++/*P2_NOSDATAT1*/ ++#define RSTV0910_P2_NOSDATAT1 0xf288 ++#define FSTV0910_P2_NOSDATAT_UNNORMED1 0xf28800ff ++ ++/*P2_NOSDATAT0*/ ++#define RSTV0910_P2_NOSDATAT0 0xf289 ++#define FSTV0910_P2_NOSDATAT_UNNORMED0 0xf28900ff ++ ++/*P2_NNOSFRAME1*/ ++#define RSTV0910_P2_NNOSFRAME1 0xf28a ++#define FSTV0910_P2_NOSFRAME_NORMED1 0xf28a00ff ++ ++/*P2_NNOSFRAME0*/ ++#define RSTV0910_P2_NNOSFRAME0 0xf28b ++#define FSTV0910_P2_NOSFRAME_NORMED0 0xf28b00ff ++ ++/*P2_NNOSRAD1*/ ++#define RSTV0910_P2_NNOSRAD1 0xf28c ++#define FSTV0910_P2_NOSRADIAL_NORMED1 0xf28c00ff ++ ++/*P2_NNOSRAD0*/ ++#define RSTV0910_P2_NNOSRAD0 0xf28d ++#define FSTV0910_P2_NOSRADIAL_NORMED0 0xf28d00ff ++ ++/*P2_NOSCFGF1*/ ++#define RSTV0910_P2_NOSCFGF1 0xf28e ++#define FSTV0910_P2_LOWNOISE_MESURE 0xf28e0080 ++#define FSTV0910_P2_NOS_DELFRAME 0xf28e0040 ++#define FSTV0910_P2_NOSDATA_MODE 0xf28e0030 ++#define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e000c ++#define FSTV0910_P2_FRAMESEL_TYPE 0xf28e0003 ++ ++/*P2_CAR2CFG*/ ++#define RSTV0910_P2_CAR2CFG 0xf290 ++#define FSTV0910_P2_DESCRAMB_OFF 0xf2900080 ++#define FSTV0910_P2_EN_PHNOSRAM 0xf2900020 ++#define FSTV0910_P2_STOP_CFR2UPDATE 0xf2900010 ++#define FSTV0910_P2_STOP_NCO2UPDATE 0xf2900008 ++#define FSTV0910_P2_ROTA2ON 0xf2900004 ++#define FSTV0910_P2_PH_DET_ALGO2 0xf2900003 ++ ++/*P2_CFR2CFR1*/ ++#define RSTV0910_P2_CFR2CFR1 0xf291 ++#define FSTV0910_P2_CFR2_S2CONTROL 0xf29100c0 ++#define FSTV0910_P2_EN_S2CAR2CENTER 0xf2910020 ++#define FSTV0910_P2_BCHERRCFR2_MODE 0xf2910018 ++#define FSTV0910_P2_CFR2TOCFR1_BETA 0xf2910007 ++ ++/*P2_CAR3CFG*/ ++#define RSTV0910_P2_CAR3CFG 0xf292 ++#define FSTV0910_P2_CARRIER23_MODE 0xf29200c0 ++#define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2920020 ++#define FSTV0910_P2_ABAMPLIF_MODE 0xf2920018 ++#define FSTV0910_P2_CARRIER3_ALPHA3DL 0xf2920007 ++ ++/*P2_CFR22*/ ++#define RSTV0910_P2_CFR22 0xf293 ++#define FSTV0910_P2_CAR2_FREQ2 0xf29301ff ++ ++/*P2_CFR21*/ ++#define RSTV0910_P2_CFR21 0xf294 ++#define FSTV0910_P2_CAR2_FREQ1 0xf29400ff ++ ++/*P2_CFR20*/ ++#define RSTV0910_P2_CFR20 0xf295 ++#define FSTV0910_P2_CAR2_FREQ0 0xf29500ff ++ ++/*P2_ACLC2S2Q*/ ++#define RSTV0910_P2_ACLC2S2Q 0xf297 ++#define FSTV0910_P2_ENAB_SPSKSYMB 0xf2970080 ++#define FSTV0910_P2_CAR2S2_QANOSAUTO 0xf2970040 ++#define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2970030 ++#define FSTV0910_P2_CAR2S2_Q_ALPH_E 0xf297000f ++ ++/*P2_ACLC2S28*/ ++#define RSTV0910_P2_ACLC2S28 0xf298 ++#define FSTV0910_P2_OLDI3Q_MODE 0xf2980080 ++#define FSTV0910_P2_CAR2S2_8ANOSAUTO 0xf2980040 ++#define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2980030 ++#define FSTV0910_P2_CAR2S2_8_ALPH_E 0xf298000f ++ ++/*P2_ACLC2S216A*/ ++#define RSTV0910_P2_ACLC2S216A 0xf299 ++#define FSTV0910_P2_CAR2S2_16ANOSAUTO 0xf2990040 ++#define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2990030 ++#define FSTV0910_P2_CAR2S2_16A_ALPH_E 0xf299000f ++ ++/*P2_ACLC2S232A*/ ++#define RSTV0910_P2_ACLC2S232A 0xf29a ++#define FSTV0910_P2_CAR2S2_32ANOSUATO 0xf29a0040 ++#define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a0030 ++#define FSTV0910_P2_CAR2S2_32A_ALPH_E 0xf29a000f ++ ++/*P2_BCLC2S2Q*/ ++#define RSTV0910_P2_BCLC2S2Q 0xf29c ++#define FSTV0910_P2_DVBS2S2Q_NIP 0xf29c0080 ++#define FSTV0910_P2_CAR2S2_QBNOSAUTO 0xf29c0040 ++#define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c0030 ++#define FSTV0910_P2_CAR2S2_Q_BETA_E 0xf29c000f ++ ++/*P2_BCLC2S28*/ ++#define RSTV0910_P2_BCLC2S28 0xf29d ++#define FSTV0910_P2_DVBS2S28_NIP 0xf29d0080 ++#define FSTV0910_P2_CAR2S2_8BNOSAUTO 0xf29d0040 ++#define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d0030 ++#define FSTV0910_P2_CAR2S2_8_BETA_E 0xf29d000f ++ ++/*P2_PLROOT2*/ ++#define RSTV0910_P2_PLROOT2 0xf2ac ++#define FSTV0910_P2_PLHAUTO_DISPLH 0xf2ac0040 ++#define FSTV0910_P2_PLHAUTO_FASTMODE 0xf2ac0020 ++#define FSTV0910_P2_PLHAUTO_ENABLE 0xf2ac0010 ++#define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac000c ++#define FSTV0910_P2_PLSCRAMB_ROOT2 0xf2ac0003 ++ ++/*P2_PLROOT1*/ ++#define RSTV0910_P2_PLROOT1 0xf2ad ++#define FSTV0910_P2_PLSCRAMB_ROOT1 0xf2ad00ff ++ ++/*P2_PLROOT0*/ ++#define RSTV0910_P2_PLROOT0 0xf2ae ++#define FSTV0910_P2_PLSCRAMB_ROOT0 0xf2ae00ff ++ ++/*P2_MODCODLST7*/ ++#define RSTV0910_P2_MODCODLST7 0xf2b7 ++#define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b70080 ++#define FSTV0910_P2_MODCODLST_NOSTYPE 0xf2b70040 ++#define FSTV0910_P2_DIS_8PSK_9_10 0xf2b70030 ++#define FSTV0910_P2_DIS_8P_8_9 0xf2b7000f ++ ++/*P2_MODCODLST8*/ ++#define RSTV0910_P2_MODCODLST8 0xf2b8 ++#define FSTV0910_P2_DIS_8P_5_6 0xf2b800f0 ++#define FSTV0910_P2_DIS_8P_3_4 0xf2b8000f ++ ++/*P2_MODCODLST9*/ ++#define RSTV0910_P2_MODCODLST9 0xf2b9 ++#define FSTV0910_P2_DIS_8P_2_3 0xf2b900f0 ++#define FSTV0910_P2_DIS_8P_3_5 0xf2b9000f ++ ++/*P2_MODCODLSTA*/ ++#define RSTV0910_P2_MODCODLSTA 0xf2ba ++#define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba0080 ++#define FSTV0910_P2_NOSFILTER_MODE 0xf2ba0040 ++#define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba0030 ++#define FSTV0910_P2_DIS_QP_8_9 0xf2ba000f ++ ++/*P2_MODCODLSTB*/ ++#define RSTV0910_P2_MODCODLSTB 0xf2bb ++#define FSTV0910_P2_DIS_QP_5_6 0xf2bb00f0 ++#define FSTV0910_P2_DIS_QP_4_5 0xf2bb000f ++ ++/*P2_MODCODLSTC*/ ++#define RSTV0910_P2_MODCODLSTC 0xf2bc ++#define FSTV0910_P2_DIS_QP_3_4 0xf2bc00f0 ++#define FSTV0910_P2_DIS_QP_2_3 0xf2bc000f ++ ++/*P2_MODCODLSTD*/ ++#define RSTV0910_P2_MODCODLSTD 0xf2bd ++#define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd00f0 ++#define FSTV0910_P2_DIS_QPSK_1_2 0xf2bd000f ++ ++/*P2_GAUSSR0*/ ++#define RSTV0910_P2_GAUSSR0 0xf2c0 ++#define FSTV0910_P2_EN_CCIMODE 0xf2c00080 ++#define FSTV0910_P2_R0_GAUSSIEN 0xf2c0007f ++ ++/*P2_CCIR0*/ ++#define RSTV0910_P2_CCIR0 0xf2c1 ++#define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c10080 ++#define FSTV0910_P2_R0_CCI 0xf2c1007f ++ ++/*P2_CCIQUANT*/ ++#define RSTV0910_P2_CCIQUANT 0xf2c2 ++#define FSTV0910_P2_CCI_BETA 0xf2c200e0 ++#define FSTV0910_P2_CCI_QUANT 0xf2c2001f ++ ++/*P2_CCITHRES*/ ++#define RSTV0910_P2_CCITHRES 0xf2c3 ++#define FSTV0910_P2_CCI_THRESHOLD 0xf2c300ff ++ ++/*P2_CCIACC*/ ++#define RSTV0910_P2_CCIACC 0xf2c4 ++#define FSTV0910_P2_CCI_VALUE 0xf2c400ff ++ ++/*P2_DSTATUS4*/ ++#define RSTV0910_P2_DSTATUS4 0xf2c5 ++#define FSTV0910_P2_RAINFADE_DETECT 0xf2c50080 ++#define FSTV0910_P2_NOTHRES2_FAIL 0xf2c50040 ++#define FSTV0910_P2_NOTHRES1_FAIL 0xf2c50020 ++#define FSTV0910_P2_PILOT_FAILDETECT 0xf2c50010 ++#define FSTV0910_P2_HIER_DETECT 0xf2c50008 ++#define FSTV0910_P2_DMDPROG_ERROR 0xf2c50004 ++#define FSTV0910_P2_CSTENV_DETECT 0xf2c50002 ++#define FSTV0910_P2_DETECTION_TRIAX 0xf2c50001 ++ ++/*P2_DMDRESCFG*/ ++#define RSTV0910_P2_DMDRESCFG 0xf2c6 ++#define FSTV0910_P2_DMDRES_RESET 0xf2c60080 ++#define FSTV0910_P2_DMDRES_NOISESQR 0xf2c60010 ++#define FSTV0910_P2_DMDRES_STRALL 0xf2c60008 ++#define FSTV0910_P2_DMDRES_NEWONLY 0xf2c60004 ++#define FSTV0910_P2_DMDRES_NOSTORE 0xf2c60002 ++#define FSTV0910_P2_DMDRES_AGC2MEM 0xf2c60001 ++ ++/*P2_DMDRESADR*/ ++#define RSTV0910_P2_DMDRESADR 0xf2c7 ++#define FSTV0910_P2_SUSP_PREDCANAL 0xf2c70080 ++#define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c70040 ++#define FSTV0910_P2_DMDRES_MEMFULL 0xf2c70030 ++#define FSTV0910_P2_DMDRES_RESNBR 0xf2c7000f ++ ++/*P2_DMDRESDATA7*/ ++#define RSTV0910_P2_DMDRESDATA7 0xf2c8 ++#define FSTV0910_P2_DMDRES_DATA7 0xf2c800ff ++ ++/*P2_DMDRESDATA6*/ ++#define RSTV0910_P2_DMDRESDATA6 0xf2c9 ++#define FSTV0910_P2_DMDRES_DATA6 0xf2c900ff ++ ++/*P2_DMDRESDATA5*/ ++#define RSTV0910_P2_DMDRESDATA5 0xf2ca ++#define FSTV0910_P2_DMDRES_DATA5 0xf2ca00ff ++ ++/*P2_DMDRESDATA4*/ ++#define RSTV0910_P2_DMDRESDATA4 0xf2cb ++#define FSTV0910_P2_DMDRES_DATA4 0xf2cb00ff ++ ++/*P2_DMDRESDATA3*/ ++#define RSTV0910_P2_DMDRESDATA3 0xf2cc ++#define FSTV0910_P2_DMDRES_DATA3 0xf2cc00ff ++ ++/*P2_DMDRESDATA2*/ ++#define RSTV0910_P2_DMDRESDATA2 0xf2cd ++#define FSTV0910_P2_DMDRES_DATA2 0xf2cd00ff ++ ++/*P2_DMDRESDATA1*/ ++#define RSTV0910_P2_DMDRESDATA1 0xf2ce ++#define FSTV0910_P2_DMDRES_DATA1 0xf2ce00ff ++ ++/*P2_DMDRESDATA0*/ ++#define RSTV0910_P2_DMDRESDATA0 0xf2cf ++#define FSTV0910_P2_DMDRES_DATA0 0xf2cf00ff ++ ++/*P2_FFEI1*/ ++#define RSTV0910_P2_FFEI1 0xf2d0 ++#define FSTV0910_P2_FFE_ACCI1 0xf2d001ff ++ ++/*P2_FFEQ1*/ ++#define RSTV0910_P2_FFEQ1 0xf2d1 ++#define FSTV0910_P2_FFE_ACCQ1 0xf2d101ff ++ ++/*P2_FFEI2*/ ++#define RSTV0910_P2_FFEI2 0xf2d2 ++#define FSTV0910_P2_FFE_ACCI2 0xf2d201ff ++ ++/*P2_FFEQ2*/ ++#define RSTV0910_P2_FFEQ2 0xf2d3 ++#define FSTV0910_P2_FFE_ACCQ2 0xf2d301ff ++ ++/*P2_FFEI3*/ ++#define RSTV0910_P2_FFEI3 0xf2d4 ++#define FSTV0910_P2_FFE_ACCI3 0xf2d401ff ++ ++/*P2_FFEQ3*/ ++#define RSTV0910_P2_FFEQ3 0xf2d5 ++#define FSTV0910_P2_FFE_ACCQ3 0xf2d501ff ++ ++/*P2_FFEI4*/ ++#define RSTV0910_P2_FFEI4 0xf2d6 ++#define FSTV0910_P2_FFE_ACCI4 0xf2d601ff ++ ++/*P2_FFEQ4*/ ++#define RSTV0910_P2_FFEQ4 0xf2d7 ++#define FSTV0910_P2_FFE_ACCQ4 0xf2d701ff ++ ++/*P2_FFECFG*/ ++#define RSTV0910_P2_FFECFG 0xf2d8 ++#define FSTV0910_P2_EQUALFFE_ON 0xf2d80040 ++#define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d80030 ++#define FSTV0910_P2_MU_EQUALFFE 0xf2d80007 ++ ++/*P2_TNRCFG2*/ ++#define RSTV0910_P2_TNRCFG2 0xf2e1 ++#define FSTV0910_P2_TUN_IQSWAP 0xf2e10080 ++#define FSTV0910_P2_STB6110_STEP2MHZ 0xf2e10040 ++#define FSTV0910_P2_STB6120_DBLI2C 0xf2e10020 ++#define FSTV0910_P2_TUNER_WIDEBAND 0xf2e10010 ++#define FSTV0910_P2_TUNER_OBSPAGE 0xf2e10008 ++#define FSTV0910_P2_DIS_BWCALC 0xf2e10004 ++#define FSTV0910_P2_SHORT_WAITSTATES 0xf2e10002 ++#define FSTV0910_P2_DIS_2BWAGC1 0xf2e10001 ++ ++/*P2_SMAPCOEF7*/ ++#define RSTV0910_P2_SMAPCOEF7 0xf300 ++#define FSTV0910_P2_DIS_QSCALE 0xf3000080 ++#define FSTV0910_P2_SMAPCOEF_Q_LLR12 0xf300017f ++ ++/*P2_SMAPCOEF6*/ ++#define RSTV0910_P2_SMAPCOEF6 0xf301 ++#define FSTV0910_P2_DIS_AGC2SCALE 0xf3010080 ++#define FSTV0910_P2_DIS_16IQMULT 0xf3010040 ++#define FSTV0910_P2_OLD_16APSK47 0xf3010020 ++#define FSTV0910_P2_OLD_16APSK12 0xf3010010 ++#define FSTV0910_P2_DIS_NEWSCALE 0xf3010008 ++#define FSTV0910_P2_ADJ_8PSKLLR1 0xf3010004 ++#define FSTV0910_P2_OLD_8PSKLLR1 0xf3010002 ++#define FSTV0910_P2_DIS_AB8PSK 0xf3010001 ++ ++/*P2_SMAPCOEF5*/ ++#define RSTV0910_P2_SMAPCOEF5 0xf302 ++#define FSTV0910_P2_DIS_8SCALE 0xf3020080 ++#define FSTV0910_P2_SMAPCOEF_8P_LLR23 0xf302017f ++ ++/*P2_NOSTHRES1*/ ++#define RSTV0910_P2_NOSTHRES1 0xf309 ++#define FSTV0910_P2_NOS_THRESHOLD1 0xf30900ff ++ ++/*P2_NOSTHRES2*/ ++#define RSTV0910_P2_NOSTHRES2 0xf30a ++#define FSTV0910_P2_NOS_THRESHOLD2 0xf30a00ff ++ ++/*P2_NOSDIFF1*/ ++#define RSTV0910_P2_NOSDIFF1 0xf30b ++#define FSTV0910_P2_NOSTHRES1_DIFF 0xf30b00ff ++ ++/*P2_RAINFADE*/ ++#define RSTV0910_P2_RAINFADE 0xf30c ++#define FSTV0910_P2_NOSTHRES_DATAT 0xf30c0080 ++#define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c0070 ++#define FSTV0910_P2_RAINFADE_TIMEOUT 0xf30c0007 ++ ++/*P2_NOSRAMCFG*/ ++#define RSTV0910_P2_NOSRAMCFG 0xf30d ++#define FSTV0910_P2_NOSRAM_DVBS2DATA 0xf30d0080 ++#define FSTV0910_P2_NOSRAM_QUADRAT 0xf30d0040 ++#define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d0030 ++#define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d0008 ++#define FSTV0910_P2_NOSRAM_LGNCNR1 0xf30d0007 ++ ++/*P2_NOSRAMPOS*/ ++#define RSTV0910_P2_NOSRAMPOS 0xf30e ++#define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e00f0 ++#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004 ++#define FSTV0910_P2_NOSRAM_CNRVAL1 0xf30e0003 ++ ++/*P2_NOSRAMVAL*/ ++#define RSTV0910_P2_NOSRAMVAL 0xf30f ++#define FSTV0910_P2_NOSRAM_CNRVAL0 0xf30f00ff ++ ++/*P2_DMDPLHSTAT*/ ++#define RSTV0910_P2_DMDPLHSTAT 0xf320 ++#define FSTV0910_P2_PLH_STATISTIC 0xf32000ff ++ ++/*P2_LOCKTIME3*/ ++#define RSTV0910_P2_LOCKTIME3 0xf322 ++#define FSTV0910_P2_DEMOD_LOCKTIME3 0xf32200ff ++ ++/*P2_LOCKTIME2*/ ++#define RSTV0910_P2_LOCKTIME2 0xf323 ++#define FSTV0910_P2_DEMOD_LOCKTIME2 0xf32300ff ++ ++/*P2_LOCKTIME1*/ ++#define RSTV0910_P2_LOCKTIME1 0xf324 ++#define FSTV0910_P2_DEMOD_LOCKTIME1 0xf32400ff ++ ++/*P2_LOCKTIME0*/ ++#define RSTV0910_P2_LOCKTIME0 0xf325 ++#define FSTV0910_P2_DEMOD_LOCKTIME0 0xf32500ff ++ ++/*P2_VITSCALE*/ ++#define RSTV0910_P2_VITSCALE 0xf332 ++#define FSTV0910_P2_NVTH_NOSRANGE 0xf3320080 ++#define FSTV0910_P2_VERROR_MAXMODE 0xf3320040 ++#define FSTV0910_P2_KDIV_MODE 0xf3320030 ++#define FSTV0910_P2_NSLOWSN_LOCKED 0xf3320008 ++#define FSTV0910_P2_DELOCK_PRFLOSS 0xf3320004 ++#define FSTV0910_P2_DIS_RSFLOCK 0xf3320002 ++ ++/*P2_FECM*/ ++#define RSTV0910_P2_FECM 0xf333 ++#define FSTV0910_P2_DSS_DVB 0xf3330080 ++#define FSTV0910_P2_DEMOD_BYPASS 0xf3330040 ++#define FSTV0910_P2_CMP_SLOWMODE 0xf3330020 ++#define FSTV0910_P2_DSS_SRCH 0xf3330010 ++#define FSTV0910_P2_DIFF_MODEVIT 0xf3330004 ++#define FSTV0910_P2_SYNCVIT 0xf3330002 ++#define FSTV0910_P2_IQINV 0xf3330001 ++ ++/*P2_VTH12*/ ++#define RSTV0910_P2_VTH12 0xf334 ++#define FSTV0910_P2_VTH12 0xf33400ff ++ ++/*P2_VTH23*/ ++#define RSTV0910_P2_VTH23 0xf335 ++#define FSTV0910_P2_VTH23 0xf33500ff ++ ++/*P2_VTH34*/ ++#define RSTV0910_P2_VTH34 0xf336 ++#define FSTV0910_P2_VTH34 0xf33600ff ++ ++/*P2_VTH56*/ ++#define RSTV0910_P2_VTH56 0xf337 ++#define FSTV0910_P2_VTH56 0xf33700ff ++ ++/*P2_VTH67*/ ++#define RSTV0910_P2_VTH67 0xf338 ++#define FSTV0910_P2_VTH67 0xf33800ff ++ ++/*P2_VTH78*/ ++#define RSTV0910_P2_VTH78 0xf339 ++#define FSTV0910_P2_VTH78 0xf33900ff ++ ++/*P2_VITCURPUN*/ ++#define RSTV0910_P2_VITCURPUN 0xf33a ++#define FSTV0910_P2_CYCLESLIP_VIT 0xf33a0080 ++#define FSTV0910_P2_VIT_ROTA180 0xf33a0040 ++#define FSTV0910_P2_VIT_ROTA90 0xf33a0020 ++#define FSTV0910_P2_VIT_CURPUN 0xf33a001f ++ ++/*P2_VERROR*/ ++#define RSTV0910_P2_VERROR 0xf33b ++#define FSTV0910_P2_REGERR_VIT 0xf33b00ff ++ ++/*P2_PRVIT*/ ++#define RSTV0910_P2_PRVIT 0xf33c ++#define FSTV0910_P2_DIS_VTHLOCK 0xf33c0040 ++#define FSTV0910_P2_E7_8VIT 0xf33c0020 ++#define FSTV0910_P2_E6_7VIT 0xf33c0010 ++#define FSTV0910_P2_E5_6VIT 0xf33c0008 ++#define FSTV0910_P2_E3_4VIT 0xf33c0004 ++#define FSTV0910_P2_E2_3VIT 0xf33c0002 ++#define FSTV0910_P2_E1_2VIT 0xf33c0001 ++ ++/*P2_VAVSRVIT*/ ++#define RSTV0910_P2_VAVSRVIT 0xf33d ++#define FSTV0910_P2_AMVIT 0xf33d0080 ++#define FSTV0910_P2_FROZENVIT 0xf33d0040 ++#define FSTV0910_P2_SNVIT 0xf33d0030 ++#define FSTV0910_P2_TOVVIT 0xf33d000c ++#define FSTV0910_P2_HYPVIT 0xf33d0003 ++ ++/*P2_VSTATUSVIT*/ ++#define RSTV0910_P2_VSTATUSVIT 0xf33e ++#define FSTV0910_P2_VITERBI_ON 0xf33e0080 ++#define FSTV0910_P2_END_LOOPVIT 0xf33e0040 ++#define FSTV0910_P2_VITERBI_DEPRF 0xf33e0020 ++#define FSTV0910_P2_PRFVIT 0xf33e0010 ++#define FSTV0910_P2_LOCKEDVIT 0xf33e0008 ++#define FSTV0910_P2_VITERBI_DELOCK 0xf33e0004 ++#define FSTV0910_P2_VIT_DEMODSEL 0xf33e0002 ++#define FSTV0910_P2_VITERBI_COMPOUT 0xf33e0001 ++ ++/*P2_VTHINUSE*/ ++#define RSTV0910_P2_VTHINUSE 0xf33f ++#define FSTV0910_P2_VIT_INUSE 0xf33f00ff ++ ++/*P2_KDIV12*/ ++#define RSTV0910_P2_KDIV12 0xf340 ++#define FSTV0910_P2_KDIV12_MANUAL 0xf3400080 ++#define FSTV0910_P2_K_DIVIDER_12 0xf340007f ++ ++/*P2_KDIV23*/ ++#define RSTV0910_P2_KDIV23 0xf341 ++#define FSTV0910_P2_KDIV23_MANUAL 0xf3410080 ++#define FSTV0910_P2_K_DIVIDER_23 0xf341007f ++ ++/*P2_KDIV34*/ ++#define RSTV0910_P2_KDIV34 0xf342 ++#define FSTV0910_P2_KDIV34_MANUAL 0xf3420080 ++#define FSTV0910_P2_K_DIVIDER_34 0xf342007f ++ ++/*P2_KDIV56*/ ++#define RSTV0910_P2_KDIV56 0xf343 ++#define FSTV0910_P2_KDIV56_MANUAL 0xf3430080 ++#define FSTV0910_P2_K_DIVIDER_56 0xf343007f ++ ++/*P2_KDIV67*/ ++#define RSTV0910_P2_KDIV67 0xf344 ++#define FSTV0910_P2_KDIV67_MANUAL 0xf3440080 ++#define FSTV0910_P2_K_DIVIDER_67 0xf344007f ++ ++/*P2_KDIV78*/ ++#define RSTV0910_P2_KDIV78 0xf345 ++#define FSTV0910_P2_KDIV78_MANUAL 0xf3450080 ++#define FSTV0910_P2_K_DIVIDER_78 0xf345007f ++ ++/*P2_PDELCTRL0*/ ++#define RSTV0910_P2_PDELCTRL0 0xf34f ++#define FSTV0910_P2_ISIOBS_MODE 0xf34f0030 ++#define FSTV0910_P2_PDELDIS_BITWISE 0xf34f0004 ++ ++/*P2_PDELCTRL1*/ ++#define RSTV0910_P2_PDELCTRL1 0xf350 ++#define FSTV0910_P2_INV_MISMASK 0xf3500080 ++#define FSTV0910_P2_FORCE_ACCEPTED 0xf3500040 ++#define FSTV0910_P2_FILTER_EN 0xf3500020 ++#define FSTV0910_P2_FORCE_PKTDELINUSE 0xf3500010 ++#define FSTV0910_P2_HYSTEN 0xf3500008 ++#define FSTV0910_P2_HYSTSWRST 0xf3500004 ++#define FSTV0910_P2_EN_MIS00 0xf3500002 ++#define FSTV0910_P2_ALGOSWRST 0xf3500001 ++ ++/*P2_PDELCTRL2*/ ++#define RSTV0910_P2_PDELCTRL2 0xf351 ++#define FSTV0910_P2_FORCE_CONTINUOUS 0xf3510080 ++#define FSTV0910_P2_RESET_UPKO_COUNT 0xf3510040 ++#define FSTV0910_P2_USER_PKTDELIN_NB 0xf3510020 ++#define FSTV0910_P2_DATA_UNBBSCRAMBLED 0xf3510008 ++#define FSTV0910_P2_FORCE_LONGPKT 0xf3510004 ++#define FSTV0910_P2_FRAME_MODE 0xf3510002 ++ ++/*P2_HYSTTHRESH*/ ++#define RSTV0910_P2_HYSTTHRESH 0xf354 ++#define FSTV0910_P2_DELIN_LOCKTHRES 0xf35400f0 ++#define FSTV0910_P2_DELIN_UNLOCKTHRES 0xf354000f ++ ++/*P2_ISIENTRY*/ ++#define RSTV0910_P2_ISIENTRY 0xf35e ++#define FSTV0910_P2_ISI_ENTRY 0xf35e00ff ++ ++/*P2_ISIBITENA*/ ++#define RSTV0910_P2_ISIBITENA 0xf35f ++#define FSTV0910_P2_ISI_BIT_EN 0xf35f00ff ++ ++/*P2_MATSTR1*/ ++#define RSTV0910_P2_MATSTR1 0xf360 ++#define FSTV0910_P2_MATYPE_CURRENT1 0xf36000ff ++ ++/*P2_MATSTR0*/ ++#define RSTV0910_P2_MATSTR0 0xf361 ++#define FSTV0910_P2_MATYPE_CURRENT0 0xf36100ff ++ ++/*P2_UPLSTR1*/ ++#define RSTV0910_P2_UPLSTR1 0xf362 ++#define FSTV0910_P2_UPL_CURRENT1 0xf36200ff ++ ++/*P2_UPLSTR0*/ ++#define RSTV0910_P2_UPLSTR0 0xf363 ++#define FSTV0910_P2_UPL_CURRENT0 0xf36300ff ++ ++/*P2_DFLSTR1*/ ++#define RSTV0910_P2_DFLSTR1 0xf364 ++#define FSTV0910_P2_DFL_CURRENT1 0xf36400ff ++ ++/*P2_DFLSTR0*/ ++#define RSTV0910_P2_DFLSTR0 0xf365 ++#define FSTV0910_P2_DFL_CURRENT0 0xf36500ff ++ ++/*P2_SYNCSTR*/ ++#define RSTV0910_P2_SYNCSTR 0xf366 ++#define FSTV0910_P2_SYNC_CURRENT 0xf36600ff ++ ++/*P2_SYNCDSTR1*/ ++#define RSTV0910_P2_SYNCDSTR1 0xf367 ++#define FSTV0910_P2_SYNCD_CURRENT1 0xf36700ff ++ ++/*P2_SYNCDSTR0*/ ++#define RSTV0910_P2_SYNCDSTR0 0xf368 ++#define FSTV0910_P2_SYNCD_CURRENT0 0xf36800ff ++ ++/*P2_PDELSTATUS1*/ ++#define RSTV0910_P2_PDELSTATUS1 0xf369 ++#define FSTV0910_P2_PKTDELIN_DELOCK 0xf3690080 ++#define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3690040 ++#define FSTV0910_P2_CONTINUOUS_STREAM 0xf3690020 ++#define FSTV0910_P2_UNACCEPTED_STREAM 0xf3690010 ++#define FSTV0910_P2_BCH_ERROR_FLAG 0xf3690008 ++#define FSTV0910_P2_BBHCRCKO 0xf3690004 ++#define FSTV0910_P2_PKTDELIN_LOCK 0xf3690002 ++#define FSTV0910_P2_FIRST_LOCK 0xf3690001 ++ ++/*P2_PDELSTATUS2*/ ++#define RSTV0910_P2_PDELSTATUS2 0xf36a ++#define FSTV0910_P2_PKTDEL_DEMODSEL 0xf36a0080 ++#define FSTV0910_P2_FRAME_MODCOD 0xf36a007c ++#define FSTV0910_P2_FRAME_TYPE 0xf36a0003 ++ ++/*P2_BBFCRCKO1*/ ++#define RSTV0910_P2_BBFCRCKO1 0xf36b ++#define FSTV0910_P2_BBHCRC_KOCNT1 0xf36b00ff ++ ++/*P2_BBFCRCKO0*/ ++#define RSTV0910_P2_BBFCRCKO0 0xf36c ++#define FSTV0910_P2_BBHCRC_KOCNT0 0xf36c00ff ++ ++/*P2_UPCRCKO1*/ ++#define RSTV0910_P2_UPCRCKO1 0xf36d ++#define FSTV0910_P2_PKTCRC_KOCNT1 0xf36d00ff ++ ++/*P2_UPCRCKO0*/ ++#define RSTV0910_P2_UPCRCKO0 0xf36e ++#define FSTV0910_P2_PKTCRC_KOCNT0 0xf36e00ff ++ ++/*P2_PDELCTRL3*/ ++#define RSTV0910_P2_PDELCTRL3 0xf36f ++#define FSTV0910_P2_PKTDEL_CONTFAIL 0xf36f0080 ++#define FSTV0910_P2_PKTDEL_ENLONGPKT 0xf36f0040 ++#define FSTV0910_P2_NOFIFO_BCHERR 0xf36f0020 ++#define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f0010 ++#define FSTV0910_P2_SATURATE_BBPKTKO 0xf36f0004 ++#define FSTV0910_P2_PKTDEL_BCHERRCONT 0xf36f0002 ++#define FSTV0910_P2_ETHERNET_DISFCS 0xf36f0001 ++ ++/*P2_TSSTATEM*/ ++#define RSTV0910_P2_TSSTATEM 0xf370 ++#define FSTV0910_P2_TSDIL_ON 0xf3700080 ++#define FSTV0910_P2_TSSKIPRS_ON 0xf3700040 ++#define FSTV0910_P2_TSRS_ON 0xf3700020 ++#define FSTV0910_P2_TSDESCRAMB_ON 0xf3700010 ++#define FSTV0910_P2_TSFRAME_MODE 0xf3700008 ++#define FSTV0910_P2_TS_DISABLE 0xf3700004 ++#define FSTV0910_P2_TSACM_MODE 0xf3700002 ++#define FSTV0910_P2_TSOUT_NOSYNC 0xf3700001 ++ ++/*P2_TSCFGH*/ ++#define RSTV0910_P2_TSCFGH 0xf372 ++#define FSTV0910_P2_TSFIFO_DVBCI 0xf3720080 ++#define FSTV0910_P2_TSFIFO_SERIAL 0xf3720040 ++#define FSTV0910_P2_TSFIFO_TEIUPDATE 0xf3720020 ++#define FSTV0910_P2_TSFIFO_DUTY50 0xf3720010 ++#define FSTV0910_P2_TSFIFO_HSGNLOUT 0xf3720008 ++#define FSTV0910_P2_TSFIFO_ERRMODE 0xf3720006 ++#define FSTV0910_P2_RST_HWARE 0xf3720001 ++ ++/*P2_TSCFGM*/ ++#define RSTV0910_P2_TSCFGM 0xf373 ++#define FSTV0910_P2_TSFIFO_MANSPEED 0xf37300c0 ++#define FSTV0910_P2_TSFIFO_PERMDATA 0xf3730020 ++#define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3730010 ++#define FSTV0910_P2_NPD_SPECDVBS2 0xf3730004 ++#define FSTV0910_P2_TSFIFO_DPUNACTIVE 0xf3730002 ++#define FSTV0910_P2_TSFIFO_INVDATA 0xf3730001 ++ ++/*P2_TSCFGL*/ ++#define RSTV0910_P2_TSCFGL 0xf374 ++#define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 ++#define FSTV0910_P2_BCHERROR_MODE 0xf3740030 ++#define FSTV0910_P2_TSFIFO_NSGNL2DATA 0xf3740008 ++#define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3740004 ++#define FSTV0910_P2_TSFIFO_BITSPEED 0xf3740003 ++ ++/*P2_TSINSDELH*/ ++#define RSTV0910_P2_TSINSDELH 0xf376 ++#define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3760080 ++#define FSTV0910_P2_TSDEL_XXHEADER 0xf3760040 ++#define FSTV0910_P2_TSDEL_BBHEADER 0xf3760020 ++#define FSTV0910_P2_TSDEL_DATAFIELD 0xf3760010 ++#define FSTV0910_P2_TSINSDEL_ISCR 0xf3760008 ++#define FSTV0910_P2_TSINSDEL_NPD 0xf3760004 ++#define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3760002 ++#define FSTV0910_P2_TSINSDEL_CRC8 0xf3760001 ++ ++/*P2_TSDIVN*/ ++#define RSTV0910_P2_TSDIVN 0xf379 ++#define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37900c0 ++#define FSTV0910_P2_BYTE_OVERSAMPLING 0xf3790038 ++#define FSTV0910_P2_TSFIFO_RISEOK 0xf3790007 ++ ++/*P2_TSCFG4*/ ++#define RSTV0910_P2_TSCFG4 0xf37a ++#define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0 ++#define FSTV0910_P2_TSFIFO_HIERSEL 0xf37a0020 ++#define FSTV0910_P2_TSFIFO_SPECTOKEN 0xf37a0010 ++#define FSTV0910_P2_TSFIFO_MAXMODE 0xf37a0008 ++#define FSTV0910_P2_TSFIFO_FRFORCEPKT 0xf37a0004 ++#define FSTV0910_P2_EXT_FECSPYIN 0xf37a0002 ++#define FSTV0910_P2_TSFIFO_DELSPEEDUP 0xf37a0001 ++ ++/*P2_TSSPEED*/ ++#define RSTV0910_P2_TSSPEED 0xf380 ++#define FSTV0910_P2_TSFIFO_OUTSPEED 0xf38000ff ++ ++/*P2_TSSTATUS*/ ++#define RSTV0910_P2_TSSTATUS 0xf381 ++#define FSTV0910_P2_TSFIFO_LINEOK 0xf3810080 ++#define FSTV0910_P2_TSFIFO_ERROR 0xf3810040 ++#define FSTV0910_P2_TSFIFO_DATA7 0xf3810020 ++#define FSTV0910_P2_TSFIFO_NOSYNC 0xf3810010 ++#define FSTV0910_P2_ISCR_INITIALIZED 0xf3810008 ++#define FSTV0910_P2_TSREGUL_ERROR 0xf3810004 ++#define FSTV0910_P2_SOFFIFO_UNREGUL 0xf3810002 ++#define FSTV0910_P2_DIL_READY 0xf3810001 ++ ++/*P2_TSSTATUS2*/ ++#define RSTV0910_P2_TSSTATUS2 0xf382 ++#define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3820080 ++#define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3820040 ++#define FSTV0910_P2_DILXX_RESET 0xf3820020 ++#define FSTV0910_P2_TSSPEED_IMPOSSIBLE 0xf3820010 ++#define FSTV0910_P2_TSFIFO_LINENOK 0xf3820008 ++#define FSTV0910_P2_TSFIFO_MUXSTREAM 0xf3820004 ++#define FSTV0910_P2_SCRAMBDETECT 0xf3820002 ++#define FSTV0910_P2_ULDTV67_FALSELOCK 0xf3820001 ++ ++/*P2_TSBITRATE1*/ ++#define RSTV0910_P2_TSBITRATE1 0xf383 ++#define FSTV0910_P2_TSFIFO_BITRATE1 0xf38300ff ++ ++/*P2_TSBITRATE0*/ ++#define RSTV0910_P2_TSBITRATE0 0xf384 ++#define FSTV0910_P2_TSFIFO_BITRATE0 0xf38400ff ++ ++/*P2_ERRCTRL1*/ ++#define RSTV0910_P2_ERRCTRL1 0xf398 ++#define FSTV0910_P2_ERR_SOURCE1 0xf39800f0 ++#define FSTV0910_P2_NUM_EVENT1 0xf3980007 ++ ++/*P2_ERRCNT12*/ ++#define RSTV0910_P2_ERRCNT12 0xf399 ++#define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3990080 ++#define FSTV0910_P2_ERR_CNT12 0xf399007f ++ ++/*P2_ERRCNT11*/ ++#define RSTV0910_P2_ERRCNT11 0xf39a ++#define FSTV0910_P2_ERR_CNT11 0xf39a00ff ++ ++/*P2_ERRCNT10*/ ++#define RSTV0910_P2_ERRCNT10 0xf39b ++#define FSTV0910_P2_ERR_CNT10 0xf39b00ff ++ ++/*P2_ERRCTRL2*/ ++#define RSTV0910_P2_ERRCTRL2 0xf39c ++#define FSTV0910_P2_ERR_SOURCE2 0xf39c00f0 ++#define FSTV0910_P2_NUM_EVENT2 0xf39c0007 ++ ++/*P2_ERRCNT22*/ ++#define RSTV0910_P2_ERRCNT22 0xf39d ++#define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d0080 ++#define FSTV0910_P2_ERR_CNT22 0xf39d007f ++ ++/*P2_ERRCNT21*/ ++#define RSTV0910_P2_ERRCNT21 0xf39e ++#define FSTV0910_P2_ERR_CNT21 0xf39e00ff ++ ++/*P2_ERRCNT20*/ ++#define RSTV0910_P2_ERRCNT20 0xf39f ++#define FSTV0910_P2_ERR_CNT20 0xf39f00ff ++ ++/*P2_FECSPY*/ ++#define RSTV0910_P2_FECSPY 0xf3a0 ++#define FSTV0910_P2_SPY_ENABLE 0xf3a00080 ++#define FSTV0910_P2_NO_SYNCBYTE 0xf3a00040 ++#define FSTV0910_P2_SERIAL_MODE 0xf3a00020 ++#define FSTV0910_P2_UNUSUAL_PACKET 0xf3a00010 ++#define FSTV0910_P2_BERMETER_DATAMODE 0xf3a0000c ++#define FSTV0910_P2_BERMETER_LMODE 0xf3a00002 ++#define FSTV0910_P2_BERMETER_RESET 0xf3a00001 ++ ++/*P2_FSPYCFG*/ ++#define RSTV0910_P2_FSPYCFG 0xf3a1 ++#define FSTV0910_P2_FECSPY_INPUT 0xf3a100c0 ++#define FSTV0910_P2_RST_ON_ERROR 0xf3a10020 ++#define FSTV0910_P2_ONE_SHOT 0xf3a10010 ++#define FSTV0910_P2_I2C_MODE 0xf3a1000c ++#define FSTV0910_P2_SPY_HYSTERESIS 0xf3a10003 ++ ++/*P2_FSPYDATA*/ ++#define RSTV0910_P2_FSPYDATA 0xf3a2 ++#define FSTV0910_P2_SPY_STUFFING 0xf3a20080 ++#define FSTV0910_P2_NOERROR_PKTJITTER 0xf3a20040 ++#define FSTV0910_P2_SPY_CNULLPKT 0xf3a20020 ++#define FSTV0910_P2_SPY_OUTDATA_MODE 0xf3a2001f ++ ++/*P2_FSPYOUT*/ ++#define RSTV0910_P2_FSPYOUT 0xf3a3 ++#define FSTV0910_P2_FSPY_DIRECT 0xf3a30080 ++#define FSTV0910_P2_SPY_OUTDATA_BUS 0xf3a30038 ++#define FSTV0910_P2_STUFF_MODE 0xf3a30007 ++ ++/*P2_FSTATUS*/ ++#define RSTV0910_P2_FSTATUS 0xf3a4 ++#define FSTV0910_P2_SPY_ENDSIM 0xf3a40080 ++#define FSTV0910_P2_VALID_SIM 0xf3a40040 ++#define FSTV0910_P2_FOUND_SIGNAL 0xf3a40020 ++#define FSTV0910_P2_DSS_SYNCBYTE 0xf3a40010 ++#define FSTV0910_P2_RESULT_STATE 0xf3a4000f ++ ++/*P2_FBERCPT4*/ ++#define RSTV0910_P2_FBERCPT4 0xf3a8 ++#define FSTV0910_P2_FBERMETER_CPT4 0xf3a800ff ++ ++/*P2_FBERCPT3*/ ++#define RSTV0910_P2_FBERCPT3 0xf3a9 ++#define FSTV0910_P2_FBERMETER_CPT3 0xf3a900ff ++ ++/*P2_FBERCPT2*/ ++#define RSTV0910_P2_FBERCPT2 0xf3aa ++#define FSTV0910_P2_FBERMETER_CPT2 0xf3aa00ff ++ ++/*P2_FBERCPT1*/ ++#define RSTV0910_P2_FBERCPT1 0xf3ab ++#define FSTV0910_P2_FBERMETER_CPT1 0xf3ab00ff ++ ++/*P2_FBERCPT0*/ ++#define RSTV0910_P2_FBERCPT0 0xf3ac ++#define FSTV0910_P2_FBERMETER_CPT0 0xf3ac00ff ++ ++/*P2_FBERERR2*/ ++#define RSTV0910_P2_FBERERR2 0xf3ad ++#define FSTV0910_P2_FBERMETER_ERR2 0xf3ad00ff ++ ++/*P2_FBERERR1*/ ++#define RSTV0910_P2_FBERERR1 0xf3ae ++#define FSTV0910_P2_FBERMETER_ERR1 0xf3ae00ff ++ ++/*P2_FBERERR0*/ ++#define RSTV0910_P2_FBERERR0 0xf3af ++#define FSTV0910_P2_FBERMETER_ERR0 0xf3af00ff ++ ++/*P2_FSPYBER*/ ++#define RSTV0910_P2_FSPYBER 0xf3b2 ++#define FSTV0910_P2_FSPYOBS_XORREAD 0xf3b20040 ++#define FSTV0910_P2_FSPYBER_OBSMODE 0xf3b20020 ++#define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b20010 ++#define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b20008 ++#define FSTV0910_P2_FSPYBER_CTIME 0xf3b20007 ++ ++/*P2_SFERROR*/ ++#define RSTV0910_P2_SFERROR 0xf3c1 ++#define FSTV0910_P2_SFEC_REGERR_VIT 0xf3c100ff ++ ++/*P2_SFECSTATUS*/ ++#define RSTV0910_P2_SFECSTATUS 0xf3c3 ++#define FSTV0910_P2_SFEC_ON 0xf3c30080 ++#define FSTV0910_P2_SFEC_OFF 0xf3c30040 ++#define FSTV0910_P2_LOCKEDSFEC 0xf3c30008 ++#define FSTV0910_P2_SFEC_DELOCK 0xf3c30004 ++#define FSTV0910_P2_SFEC_DEMODSEL 0xf3c30002 ++#define FSTV0910_P2_SFEC_OVFON 0xf3c30001 ++ ++/*P2_SFKDIV12*/ ++#define RSTV0910_P2_SFKDIV12 0xf3c4 ++#define FSTV0910_P2_SFECKDIV12_MAN 0xf3c40080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_12 0xf3c4007f ++ ++/*P2_SFKDIV23*/ ++#define RSTV0910_P2_SFKDIV23 0xf3c5 ++#define FSTV0910_P2_SFECKDIV23_MAN 0xf3c50080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_23 0xf3c5007f ++ ++/*P2_SFKDIV34*/ ++#define RSTV0910_P2_SFKDIV34 0xf3c6 ++#define FSTV0910_P2_SFECKDIV34_MAN 0xf3c60080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_34 0xf3c6007f ++ ++/*P2_SFKDIV56*/ ++#define RSTV0910_P2_SFKDIV56 0xf3c7 ++#define FSTV0910_P2_SFECKDIV56_MAN 0xf3c70080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_56 0xf3c7007f ++ ++/*P2_SFKDIV67*/ ++#define RSTV0910_P2_SFKDIV67 0xf3c8 ++#define FSTV0910_P2_SFECKDIV67_MAN 0xf3c80080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_67 0xf3c8007f ++ ++/*P2_SFKDIV78*/ ++#define RSTV0910_P2_SFKDIV78 0xf3c9 ++#define FSTV0910_P2_SFECKDIV78_MAN 0xf3c90080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_78 0xf3c9007f ++ ++/*P2_SFSTATUS*/ ++#define RSTV0910_P2_SFSTATUS 0xf3cc ++#define FSTV0910_P2_SFEC_LINEOK 0xf3cc0080 ++#define FSTV0910_P2_SFEC_ERROR 0xf3cc0040 ++#define FSTV0910_P2_SFEC_DATA7 0xf3cc0020 ++#define FSTV0910_P2_SFEC_PKTDNBRFAIL 0xf3cc0010 ++#define FSTV0910_P2_TSSFEC_DEMODSEL 0xf3cc0008 ++#define FSTV0910_P2_SFEC_NOSYNC 0xf3cc0004 ++#define FSTV0910_P2_SFEC_UNREGULA 0xf3cc0002 ++#define FSTV0910_P2_SFEC_READY 0xf3cc0001 ++ ++/*P2_SFDLYSET2*/ ++#define RSTV0910_P2_SFDLYSET2 0xf3d0 ++#define FSTV0910_P2_SFEC_OFFSET 0xf3d000c0 ++#define FSTV0910_P2_RST_SFEC 0xf3d00008 ++#define FSTV0910_P2_DILDLINE_ERROR 0xf3d00004 ++#define FSTV0910_P2_SFEC_DISABLE 0xf3d00002 ++#define FSTV0910_P2_SFEC_UNREGUL 0xf3d00001 ++ ++/*P2_SFERRCTRL*/ ++#define RSTV0910_P2_SFERRCTRL 0xf3d8 ++#define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d800f0 ++#define FSTV0910_P2_SFEC_NUM_EVENT 0xf3d80007 ++ ++/*P2_SFERRCNT2*/ ++#define RSTV0910_P2_SFERRCNT2 0xf3d9 ++#define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d90080 ++#define FSTV0910_P2_SFEC_ERR_CNT2 0xf3d9007f ++ ++/*P2_SFERRCNT1*/ ++#define RSTV0910_P2_SFERRCNT1 0xf3da ++#define FSTV0910_P2_SFEC_ERR_CNT1 0xf3da00ff ++ ++/*P2_SFERRCNT0*/ ++#define RSTV0910_P2_SFERRCNT0 0xf3db ++#define FSTV0910_P2_SFEC_ERR_CNT0 0xf3db00ff ++ ++/*P1_IQCONST*/ ++#define RSTV0910_P1_IQCONST 0xf400 ++#define FSTV0910_P1_CONSTEL_SELECT 0xf4000060 ++#define FSTV0910_P1_IQSYMB_SEL 0xf400001f ++ ++/*P1_NOSCFG*/ ++#define RSTV0910_P1_NOSCFG 0xf401 ++#define FSTV0910_P1_DIS_ACMRATIO 0xf4010080 ++#define FSTV0910_P1_NOSIN_EGALSEL 0xf4010040 ++#define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4010020 ++#define FSTV0910_P1_NOSPLH_BETA 0xf4010018 ++#define FSTV0910_P1_NOSDATA_BETA 0xf4010007 ++ ++/*P1_ISYMB*/ ++#define RSTV0910_P1_ISYMB 0xf402 ++#define FSTV0910_P1_I_SYMBOL 0xf40201ff ++ ++/*P1_QSYMB*/ ++#define RSTV0910_P1_QSYMB 0xf403 ++#define FSTV0910_P1_Q_SYMBOL 0xf40301ff ++ ++/*P1_AGC1CFG*/ ++#define RSTV0910_P1_AGC1CFG 0xf404 ++#define FSTV0910_P1_DC_FROZEN 0xf4040080 ++#define FSTV0910_P1_DC_CORRECT 0xf4040040 ++#define FSTV0910_P1_AMM_FROZEN 0xf4040020 ++#define FSTV0910_P1_AMM_CORRECT 0xf4040010 ++#define FSTV0910_P1_QUAD_FROZEN 0xf4040008 ++#define FSTV0910_P1_QUAD_CORRECT 0xf4040004 ++#define FSTV0910_P1_DCCOMP_SLOW 0xf4040002 ++#define FSTV0910_P1_IQMISM_SLOW 0xf4040001 ++ ++/*P1_AGC1CN*/ ++#define RSTV0910_P1_AGC1CN 0xf406 ++#define FSTV0910_P1_AGC1_LOCKED 0xf4060080 ++#define FSTV0910_P1_AGC1_OVERFLOW 0xf4060040 ++#define FSTV0910_P1_AGC1_NOSLOWLK 0xf4060020 ++#define FSTV0910_P1_AGC1_MINPOWER 0xf4060010 ++#define FSTV0910_P1_AGCOUT_FAST 0xf4060008 ++#define FSTV0910_P1_AGCIQ_BETA 0xf4060007 ++ ++/*P1_AGC1REF*/ ++#define RSTV0910_P1_AGC1REF 0xf407 ++#define FSTV0910_P1_AGCIQ_REF 0xf40700ff ++ ++/*P1_IDCCOMP*/ ++#define RSTV0910_P1_IDCCOMP 0xf408 ++#define FSTV0910_P1_IAVERAGE_ADJ 0xf40801ff ++ ++/*P1_QDCCOMP*/ ++#define RSTV0910_P1_QDCCOMP 0xf409 ++#define FSTV0910_P1_QAVERAGE_ADJ 0xf40901ff ++ ++/*P1_POWERI*/ ++#define RSTV0910_P1_POWERI 0xf40a ++#define FSTV0910_P1_POWER_I 0xf40a00ff ++ ++/*P1_POWERQ*/ ++#define RSTV0910_P1_POWERQ 0xf40b ++#define FSTV0910_P1_POWER_Q 0xf40b00ff ++ ++/*P1_AGC1AMM*/ ++#define RSTV0910_P1_AGC1AMM 0xf40c ++#define FSTV0910_P1_AMM_VALUE 0xf40c00ff ++ ++/*P1_AGC1QUAD*/ ++#define RSTV0910_P1_AGC1QUAD 0xf40d ++#define FSTV0910_P1_QUAD_VALUE 0xf40d01ff ++ ++/*P1_AGCIQIN1*/ ++#define RSTV0910_P1_AGCIQIN1 0xf40e ++#define FSTV0910_P1_AGCIQ_VALUE1 0xf40e00ff ++ ++/*P1_AGCIQIN0*/ ++#define RSTV0910_P1_AGCIQIN0 0xf40f ++#define FSTV0910_P1_AGCIQ_VALUE0 0xf40f00ff ++ ++/*P1_DEMOD*/ ++#define RSTV0910_P1_DEMOD 0xf410 ++#define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4100080 ++#define FSTV0910_P1_SPECINV_CONTROL 0xf4100030 ++#define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4100004 ++#define FSTV0910_P1_ROLLOFF_CONTROL 0xf4100003 ++ ++/*P1_DMDMODCOD*/ ++#define RSTV0910_P1_DMDMODCOD 0xf411 ++#define FSTV0910_P1_MANUAL_MODCOD 0xf4110080 ++#define FSTV0910_P1_DEMOD_MODCOD 0xf411007c ++#define FSTV0910_P1_DEMOD_TYPE 0xf4110003 ++ ++/*P1_DSTATUS*/ ++#define RSTV0910_P1_DSTATUS 0xf412 ++#define FSTV0910_P1_CAR_LOCK 0xf4120080 ++#define FSTV0910_P1_TMGLOCK_QUALITY 0xf4120060 ++#define FSTV0910_P1_SDVBS1_ENABLE 0xf4120010 ++#define FSTV0910_P1_LOCK_DEFINITIF 0xf4120008 ++#define FSTV0910_P1_TIMING_IS_LOCKED 0xf4120004 ++#define FSTV0910_P1_DEMOD_SYSCFG 0xf4120002 ++#define FSTV0910_P1_OVADC_DETECT 0xf4120001 ++ ++/*P1_DSTATUS2*/ ++#define RSTV0910_P1_DSTATUS2 0xf413 ++#define FSTV0910_P1_DEMOD_DELOCK 0xf4130080 ++#define FSTV0910_P1_DEMOD_TIMEOUT 0xf4130040 ++#define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4130020 ++#define FSTV0910_P1_POLYPH_SATEVENT 0xf4130010 ++#define FSTV0910_P1_AGC1_NOSIGNALACK 0xf4130008 ++#define FSTV0910_P1_AGC2_OVERFLOW 0xf4130004 ++#define FSTV0910_P1_CFR_OVERFLOW 0xf4130002 ++#define FSTV0910_P1_GAMMA_OVERUNDER 0xf4130001 ++ ++/*P1_DMDCFGMD*/ ++#define RSTV0910_P1_DMDCFGMD 0xf414 ++#define FSTV0910_P1_DVBS2_ENABLE 0xf4140080 ++#define FSTV0910_P1_DVBS1_ENABLE 0xf4140040 ++#define FSTV0910_P1_SCAN_ENABLE 0xf4140010 ++#define FSTV0910_P1_CFR_AUTOSCAN 0xf4140008 ++#define FSTV0910_P1_NOFORCE_RELOCK 0xf4140004 ++#define FSTV0910_P1_TUN_RNG 0xf4140003 ++ ++/*P1_DMDCFG2*/ ++#define RSTV0910_P1_DMDCFG2 0xf415 ++#define FSTV0910_P1_AGC1_WAITLOCK 0xf4150080 ++#define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4150040 ++#define FSTV0910_P1_BLINDPEA_MODE 0xf4150020 ++#define FSTV0910_P1_INFINITE_RELOCK 0xf4150010 ++#define FSTV0910_P1_BWOFFSET_COLDWARM 0xf4150008 ++#define FSTV0910_P1_TMGLOCK_NSCANSTOP 0xf4150004 ++#define FSTV0910_P1_COARSE_LK3MODE 0xf4150002 ++#define FSTV0910_P1_COARSE_LK2MODE 0xf4150001 ++ ++/*P1_DMDISTATE*/ ++#define RSTV0910_P1_DMDISTATE 0xf416 ++#define FSTV0910_P1_I2C_NORESETDMODE 0xf4160080 ++#define FSTV0910_P1_FORCE_ETAPED 0xf4160040 ++#define FSTV0910_P1_SDMDRST_DIRCLK 0xf4160020 ++#define FSTV0910_P1_I2C_DEMOD_MODE 0xf416001f ++ ++/*P1_DMDT0M*/ ++#define RSTV0910_P1_DMDT0M 0xf417 ++#define FSTV0910_P1_DMDT0_MIN 0xf41700ff ++ ++/*P1_DMDSTATE*/ ++#define RSTV0910_P1_DMDSTATE 0xf41b ++#define FSTV0910_P1_DEMOD_LOCKED 0xf41b0080 ++#define FSTV0910_P1_HEADER_MODE 0xf41b0060 ++#define FSTV0910_P1_DEMOD_MODE 0xf41b001f ++ ++/*P1_DMDFLYW*/ ++#define RSTV0910_P1_DMDFLYW 0xf41c ++#define FSTV0910_P1_I2C_IRQVAL 0xf41c00f0 ++#define FSTV0910_P1_FLYWHEEL_CPT 0xf41c000f ++ ++/*P1_DSTATUS3*/ ++#define RSTV0910_P1_DSTATUS3 0xf41d ++#define FSTV0910_P1_CFR_ZIGZAG 0xf41d0080 ++#define FSTV0910_P1_DEMOD_CFGMODE 0xf41d0060 ++#define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d0010 ++#define FSTV0910_P1_RELOCK_MODE 0xf41d0008 ++#define FSTV0910_P1_DEMOD_FAIL 0xf41d0004 ++#define FSTV0910_P1_ETAPE1A_DVBXMEM 0xf41d0003 ++ ++/*P1_DMDCFG3*/ ++#define RSTV0910_P1_DMDCFG3 0xf41e ++#define FSTV0910_P1_DVBS1_TMGWAIT 0xf41e0080 ++#define FSTV0910_P1_NO_BWCENTERING 0xf41e0040 ++#define FSTV0910_P1_INV_SEQSRCH 0xf41e0020 ++#define FSTV0910_P1_DIS_SFRUPLOW_TRK 0xf41e0010 ++#define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e0008 ++#define FSTV0910_P1_LOCKTIME_MODE 0xf41e0007 ++ ++/*P1_DMDCFG4*/ ++#define RSTV0910_P1_DMDCFG4 0xf41f ++#define FSTV0910_P1_DIS_VITLOCK 0xf41f0080 ++#define FSTV0910_P1_S1S2TOUT_FAST 0xf41f0040 ++#define FSTV0910_P1_DEMOD_FASTLOCK 0xf41f0020 ++#define FSTV0910_P1_S1HIER_ENABLE 0xf41f0010 ++#define FSTV0910_P1_TUNER_NRELAUNCH 0xf41f0008 ++#define FSTV0910_P1_DIS_CLKENABLE 0xf41f0004 ++#define FSTV0910_P1_DIS_HDRDIVLOCK 0xf41f0002 ++#define FSTV0910_P1_NO_TNRWBINIT 0xf41f0001 ++ ++/*P1_CORRELMANT*/ ++#define RSTV0910_P1_CORRELMANT 0xf420 ++#define FSTV0910_P1_CORREL_MANT 0xf42000ff ++ ++/*P1_CORRELABS*/ ++#define RSTV0910_P1_CORRELABS 0xf421 ++#define FSTV0910_P1_CORREL_ABS 0xf42100ff ++ ++/*P1_CORRELEXP*/ ++#define RSTV0910_P1_CORRELEXP 0xf422 ++#define FSTV0910_P1_CORREL_ABSEXP 0xf42200f0 ++#define FSTV0910_P1_CORREL_EXP 0xf422000f ++ ++/*P1_PLHMODCOD*/ ++#define RSTV0910_P1_PLHMODCOD 0xf424 ++#define FSTV0910_P1_SPECINV_DEMOD 0xf4240080 ++#define FSTV0910_P1_PLH_MODCOD 0xf424007c ++#define FSTV0910_P1_PLH_TYPE 0xf4240003 ++ ++/*P1_DMDREG*/ ++#define RSTV0910_P1_DMDREG 0xf425 ++#define FSTV0910_P1_EXTPSK_MODE 0xf4250080 ++#define FSTV0910_P1_HIER_SHORTFRAME 0xf4250002 ++#define FSTV0910_P1_DECIM_PLFRAMES 0xf4250001 ++ ++/*P1_AGC2O*/ ++#define RSTV0910_P1_AGC2O 0xf42c ++#define FSTV0910_P1_CSTENV_MODE 0xf42c00c0 ++#define FSTV0910_P1_AGC2_LKSQRT 0xf42c0020 ++#define FSTV0910_P1_AGC2_LKMODE 0xf42c0010 ++#define FSTV0910_P1_AGC2_LKEQUA 0xf42c0008 ++#define FSTV0910_P1_AGC2_COEF 0xf42c0007 ++ ++/*P1_AGC2REF*/ ++#define RSTV0910_P1_AGC2REF 0xf42d ++#define FSTV0910_P1_AGC2_REF 0xf42d00ff ++ ++/*P1_AGC1ADJ*/ ++#define RSTV0910_P1_AGC1ADJ 0xf42e ++#define FSTV0910_P1_AGC1ADJ_MANUAL 0xf42e0080 ++#define FSTV0910_P1_AGC1_ADJUSTED 0xf42e007f ++ ++/*P1_AGC2I1*/ ++#define RSTV0910_P1_AGC2I1 0xf436 ++#define FSTV0910_P1_AGC2_INTEGRATOR1 0xf43600ff ++ ++/*P1_AGC2I0*/ ++#define RSTV0910_P1_AGC2I0 0xf437 ++#define FSTV0910_P1_AGC2_INTEGRATOR0 0xf43700ff ++ ++/*P1_CARCFG*/ ++#define RSTV0910_P1_CARCFG 0xf438 ++#define FSTV0910_P1_CFRUPLOW_AUTO 0xf4380080 ++#define FSTV0910_P1_CFRUPLOW_TEST 0xf4380040 ++#define FSTV0910_P1_WIDE_FREQDET 0xf4380020 ++#define FSTV0910_P1_CARHDR_NODIV8 0xf4380010 ++#define FSTV0910_P1_I2C_ROTA 0xf4380008 ++#define FSTV0910_P1_ROTAON 0xf4380004 ++#define FSTV0910_P1_PH_DET_ALGO 0xf4380003 ++ ++/*P1_ACLC*/ ++#define RSTV0910_P1_ACLC 0xf439 ++#define FSTV0910_P1_CARS1_ANOSAUTO 0xf4390040 ++#define FSTV0910_P1_CAR_ALPHA_MANT 0xf4390030 ++#define FSTV0910_P1_CAR_ALPHA_EXP 0xf439000f ++ ++/*P1_BCLC*/ ++#define RSTV0910_P1_BCLC 0xf43a ++#define FSTV0910_P1_CARS1_BNOSAUTO 0xf43a0040 ++#define FSTV0910_P1_CAR_BETA_MANT 0xf43a0030 ++#define FSTV0910_P1_CAR_BETA_EXP 0xf43a000f ++ ++/*P1_CARFREQ*/ ++#define RSTV0910_P1_CARFREQ 0xf43d ++#define FSTV0910_P1_KC_COARSE_EXP 0xf43d00f0 ++#define FSTV0910_P1_BETA_FREQ 0xf43d000f ++ ++/*P1_CARHDR*/ ++#define RSTV0910_P1_CARHDR 0xf43e ++#define FSTV0910_P1_K_FREQ_HDR 0xf43e00ff ++ ++/*P1_LDT*/ ++#define RSTV0910_P1_LDT 0xf43f ++#define FSTV0910_P1_CARLOCK_THRES 0xf43f01ff ++ ++/*P1_LDT2*/ ++#define RSTV0910_P1_LDT2 0xf440 ++#define FSTV0910_P1_CARLOCK_THRES2 0xf44001ff ++ ++/*P1_CFRICFG*/ ++#define RSTV0910_P1_CFRICFG 0xf441 ++#define FSTV0910_P1_CFRINIT_UNVALRNG 0xf4410080 ++#define FSTV0910_P1_CFRINIT_LUNVALCPT 0xf4410040 ++#define FSTV0910_P1_CFRINIT_ABORTDBL 0xf4410020 ++#define FSTV0910_P1_CFRINIT_ABORTPRED 0xf4410010 ++#define FSTV0910_P1_CFRINIT_UNVALSKIP 0xf4410008 ++#define FSTV0910_P1_CFRINIT_CSTINC 0xf4410004 ++#define FSTV0910_P1_CFRIROLL_GARDER 0xf4410002 ++#define FSTV0910_P1_NEG_CFRSTEP 0xf4410001 ++ ++/*P1_CFRUP1*/ ++#define RSTV0910_P1_CFRUP1 0xf442 ++#define FSTV0910_P1_CFR_UP1 0xf44201ff ++ ++/*P1_CFRUP0*/ ++#define RSTV0910_P1_CFRUP0 0xf443 ++#define FSTV0910_P1_CFR_UP0 0xf44300ff ++ ++/*P1_CFRIBASE1*/ ++#define RSTV0910_P1_CFRIBASE1 0xf444 ++#define FSTV0910_P1_CFRINIT_BASE1 0xf44400ff ++ ++/*P1_CFRIBASE0*/ ++#define RSTV0910_P1_CFRIBASE0 0xf445 ++#define FSTV0910_P1_CFRINIT_BASE0 0xf44500ff ++ ++/*P1_CFRLOW1*/ ++#define RSTV0910_P1_CFRLOW1 0xf446 ++#define FSTV0910_P1_CFR_LOW1 0xf44601ff ++ ++/*P1_CFRLOW0*/ ++#define RSTV0910_P1_CFRLOW0 0xf447 ++#define FSTV0910_P1_CFR_LOW0 0xf44700ff ++ ++/*P1_CFRINIT1*/ ++#define RSTV0910_P1_CFRINIT1 0xf448 ++#define FSTV0910_P1_CFR_INIT1 0xf44801ff ++ ++/*P1_CFRINIT0*/ ++#define RSTV0910_P1_CFRINIT0 0xf449 ++#define FSTV0910_P1_CFR_INIT0 0xf44900ff ++ ++/*P1_CFRINC1*/ ++#define RSTV0910_P1_CFRINC1 0xf44a ++#define FSTV0910_P1_MANUAL_CFRINC 0xf44a0080 ++#define FSTV0910_P1_CFR_INC1 0xf44a003f ++ ++/*P1_CFRINC0*/ ++#define RSTV0910_P1_CFRINC0 0xf44b ++#define FSTV0910_P1_CFR_INC0 0xf44b00ff ++ ++/*P1_CFR2*/ ++#define RSTV0910_P1_CFR2 0xf44c ++#define FSTV0910_P1_CAR_FREQ2 0xf44c01ff ++ ++/*P1_CFR1*/ ++#define RSTV0910_P1_CFR1 0xf44d ++#define FSTV0910_P1_CAR_FREQ1 0xf44d00ff ++ ++/*P1_CFR0*/ ++#define RSTV0910_P1_CFR0 0xf44e ++#define FSTV0910_P1_CAR_FREQ0 0xf44e00ff ++ ++/*P1_LDI*/ ++#define RSTV0910_P1_LDI 0xf44f ++#define FSTV0910_P1_LOCK_DET_INTEGR 0xf44f01ff ++ ++/*P1_TMGCFG*/ ++#define RSTV0910_P1_TMGCFG 0xf450 ++#define FSTV0910_P1_TMGLOCK_BETA 0xf45000c0 ++#define FSTV0910_P1_DO_TIMING_CORR 0xf4500010 ++#define FSTV0910_P1_MANUAL_SCAN 0xf450000c ++#define FSTV0910_P1_TMG_MINFREQ 0xf4500003 ++ ++/*P1_RTC*/ ++#define RSTV0910_P1_RTC 0xf451 ++#define FSTV0910_P1_TMGALPHA_EXP 0xf45100f0 ++#define FSTV0910_P1_TMGBETA_EXP 0xf451000f ++ ++/*P1_RTCS2*/ ++#define RSTV0910_P1_RTCS2 0xf452 ++#define FSTV0910_P1_TMGALPHAS2_EXP 0xf45200f0 ++#define FSTV0910_P1_TMGBETAS2_EXP 0xf452000f ++ ++/*P1_TMGTHRISE*/ ++#define RSTV0910_P1_TMGTHRISE 0xf453 ++#define FSTV0910_P1_TMGLOCK_THRISE 0xf45300ff ++ ++/*P1_TMGTHFALL*/ ++#define RSTV0910_P1_TMGTHFALL 0xf454 ++#define FSTV0910_P1_TMGLOCK_THFALL 0xf45400ff ++ ++/*P1_SFRUPRATIO*/ ++#define RSTV0910_P1_SFRUPRATIO 0xf455 ++#define FSTV0910_P1_SFR_UPRATIO 0xf45500ff ++ ++/*P1_SFRLOWRATIO*/ ++#define RSTV0910_P1_SFRLOWRATIO 0xf456 ++#define FSTV0910_P1_SFR_LOWRATIO 0xf45600ff ++ ++/*P1_KTTMG*/ ++#define RSTV0910_P1_KTTMG 0xf457 ++#define FSTV0910_P1_KT_TMG_EXP 0xf45700f0 ++ ++/*P1_KREFTMG*/ ++#define RSTV0910_P1_KREFTMG 0xf458 ++#define FSTV0910_P1_KREF_TMG 0xf45800ff ++ ++/*P1_SFRSTEP*/ ++#define RSTV0910_P1_SFRSTEP 0xf459 ++#define FSTV0910_P1_SFR_SCANSTEP 0xf45900f0 ++#define FSTV0910_P1_SFR_CENTERSTEP 0xf459000f ++ ++/*P1_TMGCFG2*/ ++#define RSTV0910_P1_TMGCFG2 0xf45a ++#define FSTV0910_P1_KREFTMG2_DECMODE 0xf45a00c0 ++#define FSTV0910_P1_DIS_AUTOSAMP 0xf45a0008 ++#define FSTV0910_P1_SCANINIT_QUART 0xf45a0004 ++#define FSTV0910_P1_NOTMG_DVBS1DERAT 0xf45a0002 ++#define FSTV0910_P1_SFRRATIO_FINE 0xf45a0001 ++ ++/*P1_KREFTMG2*/ ++#define RSTV0910_P1_KREFTMG2 0xf45b ++#define FSTV0910_P1_KREF_TMG2 0xf45b00ff ++ ++/*P1_TMGCFG3*/ ++#define RSTV0910_P1_TMGCFG3 0xf45d ++#define FSTV0910_P1_CFRINC_MODE 0xf45d0070 ++#define FSTV0910_P1_CONT_TMGCENTER 0xf45d0008 ++#define FSTV0910_P1_AUTO_GUP 0xf45d0004 ++#define FSTV0910_P1_AUTO_GLOW 0xf45d0002 ++#define FSTV0910_P1_SFRVAL_MINMODE 0xf45d0001 ++ ++/*P1_SFRINIT1*/ ++#define RSTV0910_P1_SFRINIT1 0xf45e ++#define FSTV0910_P1_SFR_INIT1 0xf45e00ff ++ ++/*P1_SFRINIT0*/ ++#define RSTV0910_P1_SFRINIT0 0xf45f ++#define FSTV0910_P1_SFR_INIT0 0xf45f00ff ++ ++/*P1_SFRUP1*/ ++#define RSTV0910_P1_SFRUP1 0xf460 ++#define FSTV0910_P1_SYMB_FREQ_UP1 0xf46000ff ++ ++/*P1_SFRUP0*/ ++#define RSTV0910_P1_SFRUP0 0xf461 ++#define FSTV0910_P1_SYMB_FREQ_UP0 0xf46100ff ++ ++/*P1_SFRLOW1*/ ++#define RSTV0910_P1_SFRLOW1 0xf462 ++#define FSTV0910_P1_SYMB_FREQ_LOW1 0xf46200ff ++ ++/*P1_SFRLOW0*/ ++#define RSTV0910_P1_SFRLOW0 0xf463 ++#define FSTV0910_P1_SYMB_FREQ_LOW0 0xf46300ff ++ ++/*P1_SFR3*/ ++#define RSTV0910_P1_SFR3 0xf464 ++#define FSTV0910_P1_SYMB_FREQ3 0xf46400ff ++ ++/*P1_SFR2*/ ++#define RSTV0910_P1_SFR2 0xf465 ++#define FSTV0910_P1_SYMB_FREQ2 0xf46500ff ++ ++/*P1_SFR1*/ ++#define RSTV0910_P1_SFR1 0xf466 ++#define FSTV0910_P1_SYMB_FREQ1 0xf46600ff ++ ++/*P1_SFR0*/ ++#define RSTV0910_P1_SFR0 0xf467 ++#define FSTV0910_P1_SYMB_FREQ0 0xf46700ff ++ ++/*P1_TMGREG2*/ ++#define RSTV0910_P1_TMGREG2 0xf468 ++#define FSTV0910_P1_TMGREG2 0xf46800ff ++ ++/*P1_TMGREG1*/ ++#define RSTV0910_P1_TMGREG1 0xf469 ++#define FSTV0910_P1_TMGREG1 0xf46900ff ++ ++/*P1_TMGREG0*/ ++#define RSTV0910_P1_TMGREG0 0xf46a ++#define FSTV0910_P1_TMGREG0 0xf46a00ff ++ ++/*P1_TMGLOCK1*/ ++#define RSTV0910_P1_TMGLOCK1 0xf46b ++#define FSTV0910_P1_TMGLOCK_LEVEL1 0xf46b01ff ++ ++/*P1_TMGLOCK0*/ ++#define RSTV0910_P1_TMGLOCK0 0xf46c ++#define FSTV0910_P1_TMGLOCK_LEVEL0 0xf46c00ff ++ ++/*P1_TMGOBS*/ ++#define RSTV0910_P1_TMGOBS 0xf46d ++#define FSTV0910_P1_ROLLOFF_STATUS 0xf46d00c0 ++#define FSTV0910_P1_SCAN_SIGN 0xf46d0030 ++#define FSTV0910_P1_TMG_SCANNING 0xf46d0008 ++#define FSTV0910_P1_CHCENTERING_MODE 0xf46d0004 ++#define FSTV0910_P1_TMG_SCANFAIL 0xf46d0002 ++ ++/*P1_EQUALCFG*/ ++#define RSTV0910_P1_EQUALCFG 0xf46f ++#define FSTV0910_P1_NOTMG_NEGALWAIT 0xf46f0080 ++#define FSTV0910_P1_EQUAL_ON 0xf46f0040 ++#define FSTV0910_P1_SEL_EQUALCOR 0xf46f0038 ++#define FSTV0910_P1_MU_EQUALDFE 0xf46f0007 ++ ++/*P1_EQUAI1*/ ++#define RSTV0910_P1_EQUAI1 0xf470 ++#define FSTV0910_P1_EQUA_ACCI1 0xf47001ff ++ ++/*P1_EQUAQ1*/ ++#define RSTV0910_P1_EQUAQ1 0xf471 ++#define FSTV0910_P1_EQUA_ACCQ1 0xf47101ff ++ ++/*P1_EQUAI2*/ ++#define RSTV0910_P1_EQUAI2 0xf472 ++#define FSTV0910_P1_EQUA_ACCI2 0xf47201ff ++ ++/*P1_EQUAQ2*/ ++#define RSTV0910_P1_EQUAQ2 0xf473 ++#define FSTV0910_P1_EQUA_ACCQ2 0xf47301ff ++ ++/*P1_EQUAI3*/ ++#define RSTV0910_P1_EQUAI3 0xf474 ++#define FSTV0910_P1_EQUA_ACCI3 0xf47401ff ++ ++/*P1_EQUAQ3*/ ++#define RSTV0910_P1_EQUAQ3 0xf475 ++#define FSTV0910_P1_EQUA_ACCQ3 0xf47501ff ++ ++/*P1_EQUAI4*/ ++#define RSTV0910_P1_EQUAI4 0xf476 ++#define FSTV0910_P1_EQUA_ACCI4 0xf47601ff ++ ++/*P1_EQUAQ4*/ ++#define RSTV0910_P1_EQUAQ4 0xf477 ++#define FSTV0910_P1_EQUA_ACCQ4 0xf47701ff ++ ++/*P1_EQUAI5*/ ++#define RSTV0910_P1_EQUAI5 0xf478 ++#define FSTV0910_P1_EQUA_ACCI5 0xf47801ff ++ ++/*P1_EQUAQ5*/ ++#define RSTV0910_P1_EQUAQ5 0xf479 ++#define FSTV0910_P1_EQUA_ACCQ5 0xf47901ff ++ ++/*P1_EQUAI6*/ ++#define RSTV0910_P1_EQUAI6 0xf47a ++#define FSTV0910_P1_EQUA_ACCI6 0xf47a01ff ++ ++/*P1_EQUAQ6*/ ++#define RSTV0910_P1_EQUAQ6 0xf47b ++#define FSTV0910_P1_EQUA_ACCQ6 0xf47b01ff ++ ++/*P1_EQUAI7*/ ++#define RSTV0910_P1_EQUAI7 0xf47c ++#define FSTV0910_P1_EQUA_ACCI7 0xf47c01ff ++ ++/*P1_EQUAQ7*/ ++#define RSTV0910_P1_EQUAQ7 0xf47d ++#define FSTV0910_P1_EQUA_ACCQ7 0xf47d01ff ++ ++/*P1_EQUAI8*/ ++#define RSTV0910_P1_EQUAI8 0xf47e ++#define FSTV0910_P1_EQUA_ACCI8 0xf47e01ff ++ ++/*P1_EQUAQ8*/ ++#define RSTV0910_P1_EQUAQ8 0xf47f ++#define FSTV0910_P1_EQUA_ACCQ8 0xf47f01ff ++ ++/*P1_NNOSDATAT1*/ ++#define RSTV0910_P1_NNOSDATAT1 0xf480 ++#define FSTV0910_P1_NOSDATAT_NORMED1 0xf48000ff ++ ++/*P1_NNOSDATAT0*/ ++#define RSTV0910_P1_NNOSDATAT0 0xf481 ++#define FSTV0910_P1_NOSDATAT_NORMED0 0xf48100ff ++ ++/*P1_NNOSDATA1*/ ++#define RSTV0910_P1_NNOSDATA1 0xf482 ++#define FSTV0910_P1_NOSDATA_NORMED1 0xf48200ff ++ ++/*P1_NNOSDATA0*/ ++#define RSTV0910_P1_NNOSDATA0 0xf483 ++#define FSTV0910_P1_NOSDATA_NORMED0 0xf48300ff ++ ++/*P1_NNOSPLHT1*/ ++#define RSTV0910_P1_NNOSPLHT1 0xf484 ++#define FSTV0910_P1_NOSPLHT_NORMED1 0xf48400ff ++ ++/*P1_NNOSPLHT0*/ ++#define RSTV0910_P1_NNOSPLHT0 0xf485 ++#define FSTV0910_P1_NOSPLHT_NORMED0 0xf48500ff ++ ++/*P1_NNOSPLH1*/ ++#define RSTV0910_P1_NNOSPLH1 0xf486 ++#define FSTV0910_P1_NOSPLH_NORMED1 0xf48600ff ++ ++/*P1_NNOSPLH0*/ ++#define RSTV0910_P1_NNOSPLH0 0xf487 ++#define FSTV0910_P1_NOSPLH_NORMED0 0xf48700ff ++ ++/*P1_NOSDATAT1*/ ++#define RSTV0910_P1_NOSDATAT1 0xf488 ++#define FSTV0910_P1_NOSDATAT_UNNORMED1 0xf48800ff ++ ++/*P1_NOSDATAT0*/ ++#define RSTV0910_P1_NOSDATAT0 0xf489 ++#define FSTV0910_P1_NOSDATAT_UNNORMED0 0xf48900ff ++ ++/*P1_NNOSFRAME1*/ ++#define RSTV0910_P1_NNOSFRAME1 0xf48a ++#define FSTV0910_P1_NOSFRAME_NORMED1 0xf48a00ff ++ ++/*P1_NNOSFRAME0*/ ++#define RSTV0910_P1_NNOSFRAME0 0xf48b ++#define FSTV0910_P1_NOSFRAME_NORMED0 0xf48b00ff ++ ++/*P1_NNOSRAD1*/ ++#define RSTV0910_P1_NNOSRAD1 0xf48c ++#define FSTV0910_P1_NOSRADIAL_NORMED1 0xf48c00ff ++ ++/*P1_NNOSRAD0*/ ++#define RSTV0910_P1_NNOSRAD0 0xf48d ++#define FSTV0910_P1_NOSRADIAL_NORMED0 0xf48d00ff ++ ++/*P1_NOSCFGF1*/ ++#define RSTV0910_P1_NOSCFGF1 0xf48e ++#define FSTV0910_P1_LOWNOISE_MESURE 0xf48e0080 ++#define FSTV0910_P1_NOS_DELFRAME 0xf48e0040 ++#define FSTV0910_P1_NOSDATA_MODE 0xf48e0030 ++#define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e000c ++#define FSTV0910_P1_FRAMESEL_TYPE 0xf48e0003 ++ ++/*P1_CAR2CFG*/ ++#define RSTV0910_P1_CAR2CFG 0xf490 ++#define FSTV0910_P1_DESCRAMB_OFF 0xf4900080 ++#define FSTV0910_P1_EN_PHNOSRAM 0xf4900020 ++#define FSTV0910_P1_STOP_CFR2UPDATE 0xf4900010 ++#define FSTV0910_P1_STOP_NCO2UPDATE 0xf4900008 ++#define FSTV0910_P1_ROTA2ON 0xf4900004 ++#define FSTV0910_P1_PH_DET_ALGO2 0xf4900003 ++ ++/*P1_CFR2CFR1*/ ++#define RSTV0910_P1_CFR2CFR1 0xf491 ++#define FSTV0910_P1_CFR2_S2CONTROL 0xf49100c0 ++#define FSTV0910_P1_EN_S2CAR2CENTER 0xf4910020 ++#define FSTV0910_P1_BCHERRCFR2_MODE 0xf4910018 ++#define FSTV0910_P1_CFR2TOCFR1_BETA 0xf4910007 ++ ++/*P1_CAR3CFG*/ ++#define RSTV0910_P1_CAR3CFG 0xf492 ++#define FSTV0910_P1_CARRIER23_MODE 0xf49200c0 ++#define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4920020 ++#define FSTV0910_P1_ABAMPLIF_MODE 0xf4920018 ++#define FSTV0910_P1_CARRIER3_ALPHA3DL 0xf4920007 ++ ++/*P1_CFR22*/ ++#define RSTV0910_P1_CFR22 0xf493 ++#define FSTV0910_P1_CAR2_FREQ2 0xf49301ff ++ ++/*P1_CFR21*/ ++#define RSTV0910_P1_CFR21 0xf494 ++#define FSTV0910_P1_CAR2_FREQ1 0xf49400ff ++ ++/*P1_CFR20*/ ++#define RSTV0910_P1_CFR20 0xf495 ++#define FSTV0910_P1_CAR2_FREQ0 0xf49500ff ++ ++/*P1_ACLC2S2Q*/ ++#define RSTV0910_P1_ACLC2S2Q 0xf497 ++#define FSTV0910_P1_ENAB_SPSKSYMB 0xf4970080 ++#define FSTV0910_P1_CAR2S2_QANOSAUTO 0xf4970040 ++#define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4970030 ++#define FSTV0910_P1_CAR2S2_Q_ALPH_E 0xf497000f ++ ++/*P1_ACLC2S28*/ ++#define RSTV0910_P1_ACLC2S28 0xf498 ++#define FSTV0910_P1_OLDI3Q_MODE 0xf4980080 ++#define FSTV0910_P1_CAR2S2_8ANOSAUTO 0xf4980040 ++#define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4980030 ++#define FSTV0910_P1_CAR2S2_8_ALPH_E 0xf498000f ++ ++/*P1_ACLC2S216A*/ ++#define RSTV0910_P1_ACLC2S216A 0xf499 ++#define FSTV0910_P1_CAR2S2_16ANOSAUTO 0xf4990040 ++#define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4990030 ++#define FSTV0910_P1_CAR2S2_16A_ALPH_E 0xf499000f ++ ++/*P1_ACLC2S232A*/ ++#define RSTV0910_P1_ACLC2S232A 0xf49a ++#define FSTV0910_P1_CAR2S2_32ANOSUATO 0xf49a0040 ++#define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a0030 ++#define FSTV0910_P1_CAR2S2_32A_ALPH_E 0xf49a000f ++ ++/*P1_BCLC2S2Q*/ ++#define RSTV0910_P1_BCLC2S2Q 0xf49c ++#define FSTV0910_P1_DVBS2S2Q_NIP 0xf49c0080 ++#define FSTV0910_P1_CAR2S2_QBNOSAUTO 0xf49c0040 ++#define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c0030 ++#define FSTV0910_P1_CAR2S2_Q_BETA_E 0xf49c000f ++ ++/*P1_BCLC2S28*/ ++#define RSTV0910_P1_BCLC2S28 0xf49d ++#define FSTV0910_P1_DVBS2S28_NIP 0xf49d0080 ++#define FSTV0910_P1_CAR2S2_8BNOSAUTO 0xf49d0040 ++#define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d0030 ++#define FSTV0910_P1_CAR2S2_8_BETA_E 0xf49d000f ++ ++/*P1_PLROOT2*/ ++#define RSTV0910_P1_PLROOT2 0xf4ac ++#define FSTV0910_P1_PLHAUTO_DISPLH 0xf4ac0040 ++#define FSTV0910_P1_PLHAUTO_FASTMODE 0xf4ac0020 ++#define FSTV0910_P1_PLHAUTO_ENABLE 0xf4ac0010 ++#define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac000c ++#define FSTV0910_P1_PLSCRAMB_ROOT2 0xf4ac0003 ++ ++/*P1_PLROOT1*/ ++#define RSTV0910_P1_PLROOT1 0xf4ad ++#define FSTV0910_P1_PLSCRAMB_ROOT1 0xf4ad00ff ++ ++/*P1_PLROOT0*/ ++#define RSTV0910_P1_PLROOT0 0xf4ae ++#define FSTV0910_P1_PLSCRAMB_ROOT0 0xf4ae00ff ++ ++/*P1_MODCODLST7*/ ++#define RSTV0910_P1_MODCODLST7 0xf4b7 ++#define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b70080 ++#define FSTV0910_P1_MODCODLST_NOSTYPE 0xf4b70040 ++#define FSTV0910_P1_DIS_8PSK_9_10 0xf4b70030 ++#define FSTV0910_P1_DIS_8P_8_9 0xf4b7000f ++ ++/*P1_MODCODLST8*/ ++#define RSTV0910_P1_MODCODLST8 0xf4b8 ++#define FSTV0910_P1_DIS_8P_5_6 0xf4b800f0 ++#define FSTV0910_P1_DIS_8P_3_4 0xf4b8000f ++ ++/*P1_MODCODLST9*/ ++#define RSTV0910_P1_MODCODLST9 0xf4b9 ++#define FSTV0910_P1_DIS_8P_2_3 0xf4b900f0 ++#define FSTV0910_P1_DIS_8P_3_5 0xf4b9000f ++ ++/*P1_MODCODLSTA*/ ++#define RSTV0910_P1_MODCODLSTA 0xf4ba ++#define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba0080 ++#define FSTV0910_P1_NOSFILTER_MODE 0xf4ba0040 ++#define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba0030 ++#define FSTV0910_P1_DIS_QP_8_9 0xf4ba000f ++ ++/*P1_MODCODLSTB*/ ++#define RSTV0910_P1_MODCODLSTB 0xf4bb ++#define FSTV0910_P1_DIS_QP_5_6 0xf4bb00f0 ++#define FSTV0910_P1_DIS_QP_4_5 0xf4bb000f ++ ++/*P1_MODCODLSTC*/ ++#define RSTV0910_P1_MODCODLSTC 0xf4bc ++#define FSTV0910_P1_DIS_QP_3_4 0xf4bc00f0 ++#define FSTV0910_P1_DIS_QP_2_3 0xf4bc000f ++ ++/*P1_MODCODLSTD*/ ++#define RSTV0910_P1_MODCODLSTD 0xf4bd ++#define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd00f0 ++#define FSTV0910_P1_DIS_QPSK_1_2 0xf4bd000f ++ ++/*P1_GAUSSR0*/ ++#define RSTV0910_P1_GAUSSR0 0xf4c0 ++#define FSTV0910_P1_EN_CCIMODE 0xf4c00080 ++#define FSTV0910_P1_R0_GAUSSIEN 0xf4c0007f ++ ++/*P1_CCIR0*/ ++#define RSTV0910_P1_CCIR0 0xf4c1 ++#define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c10080 ++#define FSTV0910_P1_R0_CCI 0xf4c1007f ++ ++/*P1_CCIQUANT*/ ++#define RSTV0910_P1_CCIQUANT 0xf4c2 ++#define FSTV0910_P1_CCI_BETA 0xf4c200e0 ++#define FSTV0910_P1_CCI_QUANT 0xf4c2001f ++ ++/*P1_CCITHRES*/ ++#define RSTV0910_P1_CCITHRES 0xf4c3 ++#define FSTV0910_P1_CCI_THRESHOLD 0xf4c300ff ++ ++/*P1_CCIACC*/ ++#define RSTV0910_P1_CCIACC 0xf4c4 ++#define FSTV0910_P1_CCI_VALUE 0xf4c400ff ++ ++/*P1_DSTATUS4*/ ++#define RSTV0910_P1_DSTATUS4 0xf4c5 ++#define FSTV0910_P1_RAINFADE_DETECT 0xf4c50080 ++#define FSTV0910_P1_NOTHRES2_FAIL 0xf4c50040 ++#define FSTV0910_P1_NOTHRES1_FAIL 0xf4c50020 ++#define FSTV0910_P1_PILOT_FAILDETECT 0xf4c50010 ++#define FSTV0910_P1_HIER_DETECT 0xf4c50008 ++#define FSTV0910_P1_DMDPROG_ERROR 0xf4c50004 ++#define FSTV0910_P1_CSTENV_DETECT 0xf4c50002 ++#define FSTV0910_P1_DETECTION_TRIAX 0xf4c50001 ++ ++/*P1_DMDRESCFG*/ ++#define RSTV0910_P1_DMDRESCFG 0xf4c6 ++#define FSTV0910_P1_DMDRES_RESET 0xf4c60080 ++#define FSTV0910_P1_DMDRES_NOISESQR 0xf4c60010 ++#define FSTV0910_P1_DMDRES_STRALL 0xf4c60008 ++#define FSTV0910_P1_DMDRES_NEWONLY 0xf4c60004 ++#define FSTV0910_P1_DMDRES_NOSTORE 0xf4c60002 ++#define FSTV0910_P1_DMDRES_AGC2MEM 0xf4c60001 ++ ++/*P1_DMDRESADR*/ ++#define RSTV0910_P1_DMDRESADR 0xf4c7 ++#define FSTV0910_P1_SUSP_PREDCANAL 0xf4c70080 ++#define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c70040 ++#define FSTV0910_P1_DMDRES_MEMFULL 0xf4c70030 ++#define FSTV0910_P1_DMDRES_RESNBR 0xf4c7000f ++ ++/*P1_DMDRESDATA7*/ ++#define RSTV0910_P1_DMDRESDATA7 0xf4c8 ++#define FSTV0910_P1_DMDRES_DATA7 0xf4c800ff ++ ++/*P1_DMDRESDATA6*/ ++#define RSTV0910_P1_DMDRESDATA6 0xf4c9 ++#define FSTV0910_P1_DMDRES_DATA6 0xf4c900ff ++ ++/*P1_DMDRESDATA5*/ ++#define RSTV0910_P1_DMDRESDATA5 0xf4ca ++#define FSTV0910_P1_DMDRES_DATA5 0xf4ca00ff ++ ++/*P1_DMDRESDATA4*/ ++#define RSTV0910_P1_DMDRESDATA4 0xf4cb ++#define FSTV0910_P1_DMDRES_DATA4 0xf4cb00ff ++ ++/*P1_DMDRESDATA3*/ ++#define RSTV0910_P1_DMDRESDATA3 0xf4cc ++#define FSTV0910_P1_DMDRES_DATA3 0xf4cc00ff ++ ++/*P1_DMDRESDATA2*/ ++#define RSTV0910_P1_DMDRESDATA2 0xf4cd ++#define FSTV0910_P1_DMDRES_DATA2 0xf4cd00ff ++ ++/*P1_DMDRESDATA1*/ ++#define RSTV0910_P1_DMDRESDATA1 0xf4ce ++#define FSTV0910_P1_DMDRES_DATA1 0xf4ce00ff ++ ++/*P1_DMDRESDATA0*/ ++#define RSTV0910_P1_DMDRESDATA0 0xf4cf ++#define FSTV0910_P1_DMDRES_DATA0 0xf4cf00ff ++ ++/*P1_FFEI1*/ ++#define RSTV0910_P1_FFEI1 0xf4d0 ++#define FSTV0910_P1_FFE_ACCI1 0xf4d001ff ++ ++/*P1_FFEQ1*/ ++#define RSTV0910_P1_FFEQ1 0xf4d1 ++#define FSTV0910_P1_FFE_ACCQ1 0xf4d101ff ++ ++/*P1_FFEI2*/ ++#define RSTV0910_P1_FFEI2 0xf4d2 ++#define FSTV0910_P1_FFE_ACCI2 0xf4d201ff ++ ++/*P1_FFEQ2*/ ++#define RSTV0910_P1_FFEQ2 0xf4d3 ++#define FSTV0910_P1_FFE_ACCQ2 0xf4d301ff ++ ++/*P1_FFEI3*/ ++#define RSTV0910_P1_FFEI3 0xf4d4 ++#define FSTV0910_P1_FFE_ACCI3 0xf4d401ff ++ ++/*P1_FFEQ3*/ ++#define RSTV0910_P1_FFEQ3 0xf4d5 ++#define FSTV0910_P1_FFE_ACCQ3 0xf4d501ff ++ ++/*P1_FFEI4*/ ++#define RSTV0910_P1_FFEI4 0xf4d6 ++#define FSTV0910_P1_FFE_ACCI4 0xf4d601ff ++ ++/*P1_FFEQ4*/ ++#define RSTV0910_P1_FFEQ4 0xf4d7 ++#define FSTV0910_P1_FFE_ACCQ4 0xf4d701ff ++ ++/*P1_FFECFG*/ ++#define RSTV0910_P1_FFECFG 0xf4d8 ++#define FSTV0910_P1_EQUALFFE_ON 0xf4d80040 ++#define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d80030 ++#define FSTV0910_P1_MU_EQUALFFE 0xf4d80007 ++ ++/*P1_TNRCFG2*/ ++#define RSTV0910_P1_TNRCFG2 0xf4e1 ++#define FSTV0910_P1_TUN_IQSWAP 0xf4e10080 ++#define FSTV0910_P1_STB6110_STEP2MHZ 0xf4e10040 ++#define FSTV0910_P1_STB6120_DBLI2C 0xf4e10020 ++#define FSTV0910_P1_TUNER_WIDEBAND 0xf4e10010 ++#define FSTV0910_P1_TUNER_OBSPAGE 0xf4e10008 ++#define FSTV0910_P1_DIS_BWCALC 0xf4e10004 ++#define FSTV0910_P1_SHORT_WAITSTATES 0xf4e10002 ++#define FSTV0910_P1_DIS_2BWAGC1 0xf4e10001 ++ ++/*P1_SMAPCOEF7*/ ++#define RSTV0910_P1_SMAPCOEF7 0xf500 ++#define FSTV0910_P1_DIS_QSCALE 0xf5000080 ++#define FSTV0910_P1_SMAPCOEF_Q_LLR12 0xf500017f ++ ++/*P1_SMAPCOEF6*/ ++#define RSTV0910_P1_SMAPCOEF6 0xf501 ++#define FSTV0910_P1_DIS_AGC2SCALE 0xf5010080 ++#define FSTV0910_P1_DIS_16IQMULT 0xf5010040 ++#define FSTV0910_P1_OLD_16APSK47 0xf5010020 ++#define FSTV0910_P1_OLD_16APSK12 0xf5010010 ++#define FSTV0910_P1_DIS_NEWSCALE 0xf5010008 ++#define FSTV0910_P1_ADJ_8PSKLLR1 0xf5010004 ++#define FSTV0910_P1_OLD_8PSKLLR1 0xf5010002 ++#define FSTV0910_P1_DIS_AB8PSK 0xf5010001 ++ ++/*P1_SMAPCOEF5*/ ++#define RSTV0910_P1_SMAPCOEF5 0xf502 ++#define FSTV0910_P1_DIS_8SCALE 0xf5020080 ++#define FSTV0910_P1_SMAPCOEF_8P_LLR23 0xf502017f ++ ++/*P1_NOSTHRES1*/ ++#define RSTV0910_P1_NOSTHRES1 0xf509 ++#define FSTV0910_P1_NOS_THRESHOLD1 0xf50900ff ++ ++/*P1_NOSTHRES2*/ ++#define RSTV0910_P1_NOSTHRES2 0xf50a ++#define FSTV0910_P1_NOS_THRESHOLD2 0xf50a00ff ++ ++/*P1_NOSDIFF1*/ ++#define RSTV0910_P1_NOSDIFF1 0xf50b ++#define FSTV0910_P1_NOSTHRES1_DIFF 0xf50b00ff ++ ++/*P1_RAINFADE*/ ++#define RSTV0910_P1_RAINFADE 0xf50c ++#define FSTV0910_P1_NOSTHRES_DATAT 0xf50c0080 ++#define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c0070 ++#define FSTV0910_P1_RAINFADE_TIMEOUT 0xf50c0007 ++ ++/*P1_NOSRAMCFG*/ ++#define RSTV0910_P1_NOSRAMCFG 0xf50d ++#define FSTV0910_P1_NOSRAM_DVBS2DATA 0xf50d0080 ++#define FSTV0910_P1_NOSRAM_QUADRAT 0xf50d0040 ++#define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d0030 ++#define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d0008 ++#define FSTV0910_P1_NOSRAM_LGNCNR1 0xf50d0007 ++ ++/*P1_NOSRAMPOS*/ ++#define RSTV0910_P1_NOSRAMPOS 0xf50e ++#define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e00f0 ++#define FSTV0910_P1_NOSRAM_VALIDE 0xf50e0004 ++#define FSTV0910_P1_NOSRAM_CNRVAL1 0xf50e0003 ++ ++/*P1_NOSRAMVAL*/ ++#define RSTV0910_P1_NOSRAMVAL 0xf50f ++#define FSTV0910_P1_NOSRAM_CNRVAL0 0xf50f00ff ++ ++/*P1_DMDPLHSTAT*/ ++#define RSTV0910_P1_DMDPLHSTAT 0xf520 ++#define FSTV0910_P1_PLH_STATISTIC 0xf52000ff ++ ++/*P1_LOCKTIME3*/ ++#define RSTV0910_P1_LOCKTIME3 0xf522 ++#define FSTV0910_P1_DEMOD_LOCKTIME3 0xf52200ff ++ ++/*P1_LOCKTIME2*/ ++#define RSTV0910_P1_LOCKTIME2 0xf523 ++#define FSTV0910_P1_DEMOD_LOCKTIME2 0xf52300ff ++ ++/*P1_LOCKTIME1*/ ++#define RSTV0910_P1_LOCKTIME1 0xf524 ++#define FSTV0910_P1_DEMOD_LOCKTIME1 0xf52400ff ++ ++/*P1_LOCKTIME0*/ ++#define RSTV0910_P1_LOCKTIME0 0xf525 ++#define FSTV0910_P1_DEMOD_LOCKTIME0 0xf52500ff ++ ++/*P1_VITSCALE*/ ++#define RSTV0910_P1_VITSCALE 0xf532 ++#define FSTV0910_P1_NVTH_NOSRANGE 0xf5320080 ++#define FSTV0910_P1_VERROR_MAXMODE 0xf5320040 ++#define FSTV0910_P1_KDIV_MODE 0xf5320030 ++#define FSTV0910_P1_NSLOWSN_LOCKED 0xf5320008 ++#define FSTV0910_P1_DELOCK_PRFLOSS 0xf5320004 ++#define FSTV0910_P1_DIS_RSFLOCK 0xf5320002 ++ ++/*P1_FECM*/ ++#define RSTV0910_P1_FECM 0xf533 ++#define FSTV0910_P1_DSS_DVB 0xf5330080 ++#define FSTV0910_P1_DEMOD_BYPASS 0xf5330040 ++#define FSTV0910_P1_CMP_SLOWMODE 0xf5330020 ++#define FSTV0910_P1_DSS_SRCH 0xf5330010 ++#define FSTV0910_P1_DIFF_MODEVIT 0xf5330004 ++#define FSTV0910_P1_SYNCVIT 0xf5330002 ++#define FSTV0910_P1_IQINV 0xf5330001 ++ ++/*P1_VTH12*/ ++#define RSTV0910_P1_VTH12 0xf534 ++#define FSTV0910_P1_VTH12 0xf53400ff ++ ++/*P1_VTH23*/ ++#define RSTV0910_P1_VTH23 0xf535 ++#define FSTV0910_P1_VTH23 0xf53500ff ++ ++/*P1_VTH34*/ ++#define RSTV0910_P1_VTH34 0xf536 ++#define FSTV0910_P1_VTH34 0xf53600ff ++ ++/*P1_VTH56*/ ++#define RSTV0910_P1_VTH56 0xf537 ++#define FSTV0910_P1_VTH56 0xf53700ff ++ ++/*P1_VTH67*/ ++#define RSTV0910_P1_VTH67 0xf538 ++#define FSTV0910_P1_VTH67 0xf53800ff ++ ++/*P1_VTH78*/ ++#define RSTV0910_P1_VTH78 0xf539 ++#define FSTV0910_P1_VTH78 0xf53900ff ++ ++/*P1_VITCURPUN*/ ++#define RSTV0910_P1_VITCURPUN 0xf53a ++#define FSTV0910_P1_CYCLESLIP_VIT 0xf53a0080 ++#define FSTV0910_P1_VIT_ROTA180 0xf53a0040 ++#define FSTV0910_P1_VIT_ROTA90 0xf53a0020 ++#define FSTV0910_P1_VIT_CURPUN 0xf53a001f ++ ++/*P1_VERROR*/ ++#define RSTV0910_P1_VERROR 0xf53b ++#define FSTV0910_P1_REGERR_VIT 0xf53b00ff ++ ++/*P1_PRVIT*/ ++#define RSTV0910_P1_PRVIT 0xf53c ++#define FSTV0910_P1_DIS_VTHLOCK 0xf53c0040 ++#define FSTV0910_P1_E7_8VIT 0xf53c0020 ++#define FSTV0910_P1_E6_7VIT 0xf53c0010 ++#define FSTV0910_P1_E5_6VIT 0xf53c0008 ++#define FSTV0910_P1_E3_4VIT 0xf53c0004 ++#define FSTV0910_P1_E2_3VIT 0xf53c0002 ++#define FSTV0910_P1_E1_2VIT 0xf53c0001 ++ ++/*P1_VAVSRVIT*/ ++#define RSTV0910_P1_VAVSRVIT 0xf53d ++#define FSTV0910_P1_AMVIT 0xf53d0080 ++#define FSTV0910_P1_FROZENVIT 0xf53d0040 ++#define FSTV0910_P1_SNVIT 0xf53d0030 ++#define FSTV0910_P1_TOVVIT 0xf53d000c ++#define FSTV0910_P1_HYPVIT 0xf53d0003 ++ ++/*P1_VSTATUSVIT*/ ++#define RSTV0910_P1_VSTATUSVIT 0xf53e ++#define FSTV0910_P1_VITERBI_ON 0xf53e0080 ++#define FSTV0910_P1_END_LOOPVIT 0xf53e0040 ++#define FSTV0910_P1_VITERBI_DEPRF 0xf53e0020 ++#define FSTV0910_P1_PRFVIT 0xf53e0010 ++#define FSTV0910_P1_LOCKEDVIT 0xf53e0008 ++#define FSTV0910_P1_VITERBI_DELOCK 0xf53e0004 ++#define FSTV0910_P1_VIT_DEMODSEL 0xf53e0002 ++#define FSTV0910_P1_VITERBI_COMPOUT 0xf53e0001 ++ ++/*P1_VTHINUSE*/ ++#define RSTV0910_P1_VTHINUSE 0xf53f ++#define FSTV0910_P1_VIT_INUSE 0xf53f00ff ++ ++/*P1_KDIV12*/ ++#define RSTV0910_P1_KDIV12 0xf540 ++#define FSTV0910_P1_KDIV12_MANUAL 0xf5400080 ++#define FSTV0910_P1_K_DIVIDER_12 0xf540007f ++ ++/*P1_KDIV23*/ ++#define RSTV0910_P1_KDIV23 0xf541 ++#define FSTV0910_P1_KDIV23_MANUAL 0xf5410080 ++#define FSTV0910_P1_K_DIVIDER_23 0xf541007f ++ ++/*P1_KDIV34*/ ++#define RSTV0910_P1_KDIV34 0xf542 ++#define FSTV0910_P1_KDIV34_MANUAL 0xf5420080 ++#define FSTV0910_P1_K_DIVIDER_34 0xf542007f ++ ++/*P1_KDIV56*/ ++#define RSTV0910_P1_KDIV56 0xf543 ++#define FSTV0910_P1_KDIV56_MANUAL 0xf5430080 ++#define FSTV0910_P1_K_DIVIDER_56 0xf543007f ++ ++/*P1_KDIV67*/ ++#define RSTV0910_P1_KDIV67 0xf544 ++#define FSTV0910_P1_KDIV67_MANUAL 0xf5440080 ++#define FSTV0910_P1_K_DIVIDER_67 0xf544007f ++ ++/*P1_KDIV78*/ ++#define RSTV0910_P1_KDIV78 0xf545 ++#define FSTV0910_P1_KDIV78_MANUAL 0xf5450080 ++#define FSTV0910_P1_K_DIVIDER_78 0xf545007f ++ ++/*P1_PDELCTRL0*/ ++#define RSTV0910_P1_PDELCTRL0 0xf54f ++#define FSTV0910_P1_ISIOBS_MODE 0xf54f0030 ++#define FSTV0910_P1_PDELDIS_BITWISE 0xf54f0004 ++ ++/*P1_PDELCTRL1*/ ++#define RSTV0910_P1_PDELCTRL1 0xf550 ++#define FSTV0910_P1_INV_MISMASK 0xf5500080 ++#define FSTV0910_P1_FORCE_ACCEPTED 0xf5500040 ++#define FSTV0910_P1_FILTER_EN 0xf5500020 ++#define FSTV0910_P1_FORCE_PKTDELINUSE 0xf5500010 ++#define FSTV0910_P1_HYSTEN 0xf5500008 ++#define FSTV0910_P1_HYSTSWRST 0xf5500004 ++#define FSTV0910_P1_EN_MIS00 0xf5500002 ++#define FSTV0910_P1_ALGOSWRST 0xf5500001 ++ ++/*P1_PDELCTRL2*/ ++#define RSTV0910_P1_PDELCTRL2 0xf551 ++#define FSTV0910_P1_FORCE_CONTINUOUS 0xf5510080 ++#define FSTV0910_P1_RESET_UPKO_COUNT 0xf5510040 ++#define FSTV0910_P1_USER_PKTDELIN_NB 0xf5510020 ++#define FSTV0910_P1_DATA_UNBBSCRAMBLED 0xf5510008 ++#define FSTV0910_P1_FORCE_LONGPKT 0xf5510004 ++#define FSTV0910_P1_FRAME_MODE 0xf5510002 ++ ++/*P1_HYSTTHRESH*/ ++#define RSTV0910_P1_HYSTTHRESH 0xf554 ++#define FSTV0910_P1_DELIN_LOCKTHRES 0xf55400f0 ++#define FSTV0910_P1_DELIN_UNLOCKTHRES 0xf554000f ++ ++/*P1_ISIENTRY*/ ++#define RSTV0910_P1_ISIENTRY 0xf55e ++#define FSTV0910_P1_ISI_ENTRY 0xf55e00ff ++ ++/*P1_ISIBITENA*/ ++#define RSTV0910_P1_ISIBITENA 0xf55f ++#define FSTV0910_P1_ISI_BIT_EN 0xf55f00ff ++ ++/*P1_MATSTR1*/ ++#define RSTV0910_P1_MATSTR1 0xf560 ++#define FSTV0910_P1_MATYPE_CURRENT1 0xf56000ff ++ ++/*P1_MATSTR0*/ ++#define RSTV0910_P1_MATSTR0 0xf561 ++#define FSTV0910_P1_MATYPE_CURRENT0 0xf56100ff ++ ++/*P1_UPLSTR1*/ ++#define RSTV0910_P1_UPLSTR1 0xf562 ++#define FSTV0910_P1_UPL_CURRENT1 0xf56200ff ++ ++/*P1_UPLSTR0*/ ++#define RSTV0910_P1_UPLSTR0 0xf563 ++#define FSTV0910_P1_UPL_CURRENT0 0xf56300ff ++ ++/*P1_DFLSTR1*/ ++#define RSTV0910_P1_DFLSTR1 0xf564 ++#define FSTV0910_P1_DFL_CURRENT1 0xf56400ff ++ ++/*P1_DFLSTR0*/ ++#define RSTV0910_P1_DFLSTR0 0xf565 ++#define FSTV0910_P1_DFL_CURRENT0 0xf56500ff ++ ++/*P1_SYNCSTR*/ ++#define RSTV0910_P1_SYNCSTR 0xf566 ++#define FSTV0910_P1_SYNC_CURRENT 0xf56600ff ++ ++/*P1_SYNCDSTR1*/ ++#define RSTV0910_P1_SYNCDSTR1 0xf567 ++#define FSTV0910_P1_SYNCD_CURRENT1 0xf56700ff ++ ++/*P1_SYNCDSTR0*/ ++#define RSTV0910_P1_SYNCDSTR0 0xf568 ++#define FSTV0910_P1_SYNCD_CURRENT0 0xf56800ff ++ ++/*P1_PDELSTATUS1*/ ++#define RSTV0910_P1_PDELSTATUS1 0xf569 ++#define FSTV0910_P1_PKTDELIN_DELOCK 0xf5690080 ++#define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5690040 ++#define FSTV0910_P1_CONTINUOUS_STREAM 0xf5690020 ++#define FSTV0910_P1_UNACCEPTED_STREAM 0xf5690010 ++#define FSTV0910_P1_BCH_ERROR_FLAG 0xf5690008 ++#define FSTV0910_P1_BBHCRCKO 0xf5690004 ++#define FSTV0910_P1_PKTDELIN_LOCK 0xf5690002 ++#define FSTV0910_P1_FIRST_LOCK 0xf5690001 ++ ++/*P1_PDELSTATUS2*/ ++#define RSTV0910_P1_PDELSTATUS2 0xf56a ++#define FSTV0910_P1_PKTDEL_DEMODSEL 0xf56a0080 ++#define FSTV0910_P1_FRAME_MODCOD 0xf56a007c ++#define FSTV0910_P1_FRAME_TYPE 0xf56a0003 ++ ++/*P1_BBFCRCKO1*/ ++#define RSTV0910_P1_BBFCRCKO1 0xf56b ++#define FSTV0910_P1_BBHCRC_KOCNT1 0xf56b00ff ++ ++/*P1_BBFCRCKO0*/ ++#define RSTV0910_P1_BBFCRCKO0 0xf56c ++#define FSTV0910_P1_BBHCRC_KOCNT0 0xf56c00ff ++ ++/*P1_UPCRCKO1*/ ++#define RSTV0910_P1_UPCRCKO1 0xf56d ++#define FSTV0910_P1_PKTCRC_KOCNT1 0xf56d00ff ++ ++/*P1_UPCRCKO0*/ ++#define RSTV0910_P1_UPCRCKO0 0xf56e ++#define FSTV0910_P1_PKTCRC_KOCNT0 0xf56e00ff ++ ++/*P1_PDELCTRL3*/ ++#define RSTV0910_P1_PDELCTRL3 0xf56f ++#define FSTV0910_P1_PKTDEL_CONTFAIL 0xf56f0080 ++#define FSTV0910_P1_PKTDEL_ENLONGPKT 0xf56f0040 ++#define FSTV0910_P1_NOFIFO_BCHERR 0xf56f0020 ++#define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f0010 ++#define FSTV0910_P1_SATURATE_BBPKTKO 0xf56f0004 ++#define FSTV0910_P1_PKTDEL_BCHERRCONT 0xf56f0002 ++#define FSTV0910_P1_ETHERNET_DISFCS 0xf56f0001 ++ ++/*P1_TSSTATEM*/ ++#define RSTV0910_P1_TSSTATEM 0xf570 ++#define FSTV0910_P1_TSDIL_ON 0xf5700080 ++#define FSTV0910_P1_TSSKIPRS_ON 0xf5700040 ++#define FSTV0910_P1_TSRS_ON 0xf5700020 ++#define FSTV0910_P1_TSDESCRAMB_ON 0xf5700010 ++#define FSTV0910_P1_TSFRAME_MODE 0xf5700008 ++#define FSTV0910_P1_TS_DISABLE 0xf5700004 ++#define FSTV0910_P1_TSACM_MODE 0xf5700002 ++#define FSTV0910_P1_TSOUT_NOSYNC 0xf5700001 ++ ++/*P1_TSCFGH*/ ++#define RSTV0910_P1_TSCFGH 0xf572 ++#define FSTV0910_P1_TSFIFO_DVBCI 0xf5720080 ++#define FSTV0910_P1_TSFIFO_SERIAL 0xf5720040 ++#define FSTV0910_P1_TSFIFO_TEIUPDATE 0xf5720020 ++#define FSTV0910_P1_TSFIFO_DUTY50 0xf5720010 ++#define FSTV0910_P1_TSFIFO_HSGNLOUT 0xf5720008 ++#define FSTV0910_P1_TSFIFO_ERRMODE 0xf5720006 ++#define FSTV0910_P1_RST_HWARE 0xf5720001 ++ ++/*P1_TSCFGM*/ ++#define RSTV0910_P1_TSCFGM 0xf573 ++#define FSTV0910_P1_TSFIFO_MANSPEED 0xf57300c0 ++#define FSTV0910_P1_TSFIFO_PERMDATA 0xf5730020 ++#define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5730010 ++#define FSTV0910_P1_NPD_SPECDVBS2 0xf5730004 ++#define FSTV0910_P1_TSFIFO_DPUNACTIVE 0xf5730002 ++#define FSTV0910_P1_TSFIFO_INVDATA 0xf5730001 ++ ++/*P1_TSCFGL*/ ++#define RSTV0910_P1_TSCFGL 0xf574 ++#define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 ++#define FSTV0910_P1_BCHERROR_MODE 0xf5740030 ++#define FSTV0910_P1_TSFIFO_NSGNL2DATA 0xf5740008 ++#define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5740004 ++#define FSTV0910_P1_TSFIFO_BITSPEED 0xf5740003 ++ ++/*P1_TSINSDELH*/ ++#define RSTV0910_P1_TSINSDELH 0xf576 ++#define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5760080 ++#define FSTV0910_P1_TSDEL_XXHEADER 0xf5760040 ++#define FSTV0910_P1_TSDEL_BBHEADER 0xf5760020 ++#define FSTV0910_P1_TSDEL_DATAFIELD 0xf5760010 ++#define FSTV0910_P1_TSINSDEL_ISCR 0xf5760008 ++#define FSTV0910_P1_TSINSDEL_NPD 0xf5760004 ++#define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5760002 ++#define FSTV0910_P1_TSINSDEL_CRC8 0xf5760001 ++ ++/*P1_TSDIVN*/ ++#define RSTV0910_P1_TSDIVN 0xf579 ++#define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57900c0 ++#define FSTV0910_P1_BYTE_OVERSAMPLING 0xf5790038 ++#define FSTV0910_P1_TSFIFO_RISEOK 0xf5790007 ++ ++/*P1_TSCFG4*/ ++#define RSTV0910_P1_TSCFG4 0xf57a ++#define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0 ++#define FSTV0910_P1_TSFIFO_HIERSEL 0xf57a0020 ++#define FSTV0910_P1_TSFIFO_SPECTOKEN 0xf57a0010 ++#define FSTV0910_P1_TSFIFO_MAXMODE 0xf57a0008 ++#define FSTV0910_P1_TSFIFO_FRFORCEPKT 0xf57a0004 ++#define FSTV0910_P1_EXT_FECSPYIN 0xf57a0002 ++#define FSTV0910_P1_TSFIFO_DELSPEEDUP 0xf57a0001 ++ ++/*P1_TSSPEED*/ ++#define RSTV0910_P1_TSSPEED 0xf580 ++#define FSTV0910_P1_TSFIFO_OUTSPEED 0xf58000ff ++ ++/*P1_TSSTATUS*/ ++#define RSTV0910_P1_TSSTATUS 0xf581 ++#define FSTV0910_P1_TSFIFO_LINEOK 0xf5810080 ++#define FSTV0910_P1_TSFIFO_ERROR 0xf5810040 ++#define FSTV0910_P1_TSFIFO_DATA7 0xf5810020 ++#define FSTV0910_P1_TSFIFO_NOSYNC 0xf5810010 ++#define FSTV0910_P1_ISCR_INITIALIZED 0xf5810008 ++#define FSTV0910_P1_TSREGUL_ERROR 0xf5810004 ++#define FSTV0910_P1_SOFFIFO_UNREGUL 0xf5810002 ++#define FSTV0910_P1_DIL_READY 0xf5810001 ++ ++/*P1_TSSTATUS2*/ ++#define RSTV0910_P1_TSSTATUS2 0xf582 ++#define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5820080 ++#define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5820040 ++#define FSTV0910_P1_DILXX_RESET 0xf5820020 ++#define FSTV0910_P1_TSSPEED_IMPOSSIBLE 0xf5820010 ++#define FSTV0910_P1_TSFIFO_LINENOK 0xf5820008 ++#define FSTV0910_P1_TSFIFO_MUXSTREAM 0xf5820004 ++#define FSTV0910_P1_SCRAMBDETECT 0xf5820002 ++#define FSTV0910_P1_ULDTV67_FALSELOCK 0xf5820001 ++ ++/*P1_TSBITRATE1*/ ++#define RSTV0910_P1_TSBITRATE1 0xf583 ++#define FSTV0910_P1_TSFIFO_BITRATE1 0xf58300ff ++ ++/*P1_TSBITRATE0*/ ++#define RSTV0910_P1_TSBITRATE0 0xf584 ++#define FSTV0910_P1_TSFIFO_BITRATE0 0xf58400ff ++ ++/*P1_ERRCTRL1*/ ++#define RSTV0910_P1_ERRCTRL1 0xf598 ++#define FSTV0910_P1_ERR_SOURCE1 0xf59800f0 ++#define FSTV0910_P1_NUM_EVENT1 0xf5980007 ++ ++/*P1_ERRCNT12*/ ++#define RSTV0910_P1_ERRCNT12 0xf599 ++#define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5990080 ++#define FSTV0910_P1_ERR_CNT12 0xf599007f ++ ++/*P1_ERRCNT11*/ ++#define RSTV0910_P1_ERRCNT11 0xf59a ++#define FSTV0910_P1_ERR_CNT11 0xf59a00ff ++ ++/*P1_ERRCNT10*/ ++#define RSTV0910_P1_ERRCNT10 0xf59b ++#define FSTV0910_P1_ERR_CNT10 0xf59b00ff ++ ++/*P1_ERRCTRL2*/ ++#define RSTV0910_P1_ERRCTRL2 0xf59c ++#define FSTV0910_P1_ERR_SOURCE2 0xf59c00f0 ++#define FSTV0910_P1_NUM_EVENT2 0xf59c0007 ++ ++/*P1_ERRCNT22*/ ++#define RSTV0910_P1_ERRCNT22 0xf59d ++#define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d0080 ++#define FSTV0910_P1_ERR_CNT22 0xf59d007f ++ ++/*P1_ERRCNT21*/ ++#define RSTV0910_P1_ERRCNT21 0xf59e ++#define FSTV0910_P1_ERR_CNT21 0xf59e00ff ++ ++/*P1_ERRCNT20*/ ++#define RSTV0910_P1_ERRCNT20 0xf59f ++#define FSTV0910_P1_ERR_CNT20 0xf59f00ff ++ ++/*P1_FECSPY*/ ++#define RSTV0910_P1_FECSPY 0xf5a0 ++#define FSTV0910_P1_SPY_ENABLE 0xf5a00080 ++#define FSTV0910_P1_NO_SYNCBYTE 0xf5a00040 ++#define FSTV0910_P1_SERIAL_MODE 0xf5a00020 ++#define FSTV0910_P1_UNUSUAL_PACKET 0xf5a00010 ++#define FSTV0910_P1_BERMETER_DATAMODE 0xf5a0000c ++#define FSTV0910_P1_BERMETER_LMODE 0xf5a00002 ++#define FSTV0910_P1_BERMETER_RESET 0xf5a00001 ++ ++/*P1_FSPYCFG*/ ++#define RSTV0910_P1_FSPYCFG 0xf5a1 ++#define FSTV0910_P1_FECSPY_INPUT 0xf5a100c0 ++#define FSTV0910_P1_RST_ON_ERROR 0xf5a10020 ++#define FSTV0910_P1_ONE_SHOT 0xf5a10010 ++#define FSTV0910_P1_I2C_MODE 0xf5a1000c ++#define FSTV0910_P1_SPY_HYSTERESIS 0xf5a10003 ++ ++/*P1_FSPYDATA*/ ++#define RSTV0910_P1_FSPYDATA 0xf5a2 ++#define FSTV0910_P1_SPY_STUFFING 0xf5a20080 ++#define FSTV0910_P1_NOERROR_PKTJITTER 0xf5a20040 ++#define FSTV0910_P1_SPY_CNULLPKT 0xf5a20020 ++#define FSTV0910_P1_SPY_OUTDATA_MODE 0xf5a2001f ++ ++/*P1_FSPYOUT*/ ++#define RSTV0910_P1_FSPYOUT 0xf5a3 ++#define FSTV0910_P1_FSPY_DIRECT 0xf5a30080 ++#define FSTV0910_P1_SPY_OUTDATA_BUS 0xf5a30038 ++#define FSTV0910_P1_STUFF_MODE 0xf5a30007 ++ ++/*P1_FSTATUS*/ ++#define RSTV0910_P1_FSTATUS 0xf5a4 ++#define FSTV0910_P1_SPY_ENDSIM 0xf5a40080 ++#define FSTV0910_P1_VALID_SIM 0xf5a40040 ++#define FSTV0910_P1_FOUND_SIGNAL 0xf5a40020 ++#define FSTV0910_P1_DSS_SYNCBYTE 0xf5a40010 ++#define FSTV0910_P1_RESULT_STATE 0xf5a4000f ++ ++/*P1_FBERCPT4*/ ++#define RSTV0910_P1_FBERCPT4 0xf5a8 ++#define FSTV0910_P1_FBERMETER_CPT4 0xf5a800ff ++ ++/*P1_FBERCPT3*/ ++#define RSTV0910_P1_FBERCPT3 0xf5a9 ++#define FSTV0910_P1_FBERMETER_CPT3 0xf5a900ff ++ ++/*P1_FBERCPT2*/ ++#define RSTV0910_P1_FBERCPT2 0xf5aa ++#define FSTV0910_P1_FBERMETER_CPT2 0xf5aa00ff ++ ++/*P1_FBERCPT1*/ ++#define RSTV0910_P1_FBERCPT1 0xf5ab ++#define FSTV0910_P1_FBERMETER_CPT1 0xf5ab00ff ++ ++/*P1_FBERCPT0*/ ++#define RSTV0910_P1_FBERCPT0 0xf5ac ++#define FSTV0910_P1_FBERMETER_CPT0 0xf5ac00ff ++ ++/*P1_FBERERR2*/ ++#define RSTV0910_P1_FBERERR2 0xf5ad ++#define FSTV0910_P1_FBERMETER_ERR2 0xf5ad00ff ++ ++/*P1_FBERERR1*/ ++#define RSTV0910_P1_FBERERR1 0xf5ae ++#define FSTV0910_P1_FBERMETER_ERR1 0xf5ae00ff ++ ++/*P1_FBERERR0*/ ++#define RSTV0910_P1_FBERERR0 0xf5af ++#define FSTV0910_P1_FBERMETER_ERR0 0xf5af00ff ++ ++/*P1_FSPYBER*/ ++#define RSTV0910_P1_FSPYBER 0xf5b2 ++#define FSTV0910_P1_FSPYOBS_XORREAD 0xf5b20040 ++#define FSTV0910_P1_FSPYBER_OBSMODE 0xf5b20020 ++#define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b20010 ++#define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b20008 ++#define FSTV0910_P1_FSPYBER_CTIME 0xf5b20007 ++ ++/*P1_SFERROR*/ ++#define RSTV0910_P1_SFERROR 0xf5c1 ++#define FSTV0910_P1_SFEC_REGERR_VIT 0xf5c100ff ++ ++/*P1_SFECSTATUS*/ ++#define RSTV0910_P1_SFECSTATUS 0xf5c3 ++#define FSTV0910_P1_SFEC_ON 0xf5c30080 ++#define FSTV0910_P1_SFEC_OFF 0xf5c30040 ++#define FSTV0910_P1_LOCKEDSFEC 0xf5c30008 ++#define FSTV0910_P1_SFEC_DELOCK 0xf5c30004 ++#define FSTV0910_P1_SFEC_DEMODSEL 0xf5c30002 ++#define FSTV0910_P1_SFEC_OVFON 0xf5c30001 ++ ++/*P1_SFKDIV12*/ ++#define RSTV0910_P1_SFKDIV12 0xf5c4 ++#define FSTV0910_P1_SFECKDIV12_MAN 0xf5c40080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_12 0xf5c4007f ++ ++/*P1_SFKDIV23*/ ++#define RSTV0910_P1_SFKDIV23 0xf5c5 ++#define FSTV0910_P1_SFECKDIV23_MAN 0xf5c50080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_23 0xf5c5007f ++ ++/*P1_SFKDIV34*/ ++#define RSTV0910_P1_SFKDIV34 0xf5c6 ++#define FSTV0910_P1_SFECKDIV34_MAN 0xf5c60080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_34 0xf5c6007f ++ ++/*P1_SFKDIV56*/ ++#define RSTV0910_P1_SFKDIV56 0xf5c7 ++#define FSTV0910_P1_SFECKDIV56_MAN 0xf5c70080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_56 0xf5c7007f ++ ++/*P1_SFKDIV67*/ ++#define RSTV0910_P1_SFKDIV67 0xf5c8 ++#define FSTV0910_P1_SFECKDIV67_MAN 0xf5c80080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_67 0xf5c8007f ++ ++/*P1_SFKDIV78*/ ++#define RSTV0910_P1_SFKDIV78 0xf5c9 ++#define FSTV0910_P1_SFECKDIV78_MAN 0xf5c90080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_78 0xf5c9007f ++ ++/*P1_SFSTATUS*/ ++#define RSTV0910_P1_SFSTATUS 0xf5cc ++#define FSTV0910_P1_SFEC_LINEOK 0xf5cc0080 ++#define FSTV0910_P1_SFEC_ERROR 0xf5cc0040 ++#define FSTV0910_P1_SFEC_DATA7 0xf5cc0020 ++#define FSTV0910_P1_SFEC_PKTDNBRFAIL 0xf5cc0010 ++#define FSTV0910_P1_TSSFEC_DEMODSEL 0xf5cc0008 ++#define FSTV0910_P1_SFEC_NOSYNC 0xf5cc0004 ++#define FSTV0910_P1_SFEC_UNREGULA 0xf5cc0002 ++#define FSTV0910_P1_SFEC_READY 0xf5cc0001 ++ ++/*P1_SFDLYSET2*/ ++#define RSTV0910_P1_SFDLYSET2 0xf5d0 ++#define FSTV0910_P1_SFEC_OFFSET 0xf5d000c0 ++#define FSTV0910_P1_RST_SFEC 0xf5d00008 ++#define FSTV0910_P1_DILDLINE_ERROR 0xf5d00004 ++#define FSTV0910_P1_SFEC_DISABLE 0xf5d00002 ++#define FSTV0910_P1_SFEC_UNREGUL 0xf5d00001 ++ ++/*P1_SFERRCTRL*/ ++#define RSTV0910_P1_SFERRCTRL 0xf5d8 ++#define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d800f0 ++#define FSTV0910_P1_SFEC_NUM_EVENT 0xf5d80007 ++ ++/*P1_SFERRCNT2*/ ++#define RSTV0910_P1_SFERRCNT2 0xf5d9 ++#define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d90080 ++#define FSTV0910_P1_SFEC_ERR_CNT2 0xf5d9007f ++ ++/*P1_SFERRCNT1*/ ++#define RSTV0910_P1_SFERRCNT1 0xf5da ++#define FSTV0910_P1_SFEC_ERR_CNT1 0xf5da00ff ++ ++/*P1_SFERRCNT0*/ ++#define RSTV0910_P1_SFERRCNT0 0xf5db ++#define FSTV0910_P1_SFEC_ERR_CNT0 0xf5db00ff ++ ++/*TSGENERAL*/ ++#define RSTV0910_TSGENERAL 0xf630 ++#define FSTV0910_EN_LGNERROR 0xf6300080 ++#define FSTV0910_TSFIFO_DISTS2PAR 0xf6300040 ++#define FSTV0910_MUXSTREAM_COMPMOSE 0xf6300030 ++#define FSTV0910_MUXSTREAM_OUTMODE 0xf6300008 ++#define FSTV0910_TSFIFO_PERMPARAL 0xf6300006 ++#define FSTV0910_RST_REEDSOLO 0xf6300001 ++ ++/*P1_DISIRQCFG*/ ++#define RSTV0910_P1_DISIRQCFG 0xf700 ++#define FSTV0910_P1_ENRXEND 0xf7000040 ++#define FSTV0910_P1_ENRXFIFO8B 0xf7000020 ++#define FSTV0910_P1_ENTRFINISH 0xf7000010 ++#define FSTV0910_P1_ENTIMEOUT 0xf7000008 ++#define FSTV0910_P1_ENTXEND 0xf7000004 ++#define FSTV0910_P1_ENTXFIFO64B 0xf7000002 ++#define FSTV0910_P1_ENGAPBURST 0xf7000001 ++ ++/*P1_DISIRQSTAT*/ ++#define RSTV0910_P1_DISIRQSTAT 0xf701 ++#define FSTV0910_P1_IRQRXEND 0xf7010040 ++#define FSTV0910_P1_IRQRXFIFO8B 0xf7010020 ++#define FSTV0910_P1_IRQTRFINISH 0xf7010010 ++#define FSTV0910_P1_IRQTIMEOUT 0xf7010008 ++#define FSTV0910_P1_IRQTXEND 0xf7010004 ++#define FSTV0910_P1_IRQTXFIFO64B 0xf7010002 ++#define FSTV0910_P1_IRQGAPBURST 0xf7010001 ++ ++/*P1_DISTXCFG*/ ++#define RSTV0910_P1_DISTXCFG 0xf702 ++#define FSTV0910_P1_DISTX_RESET 0xf7020080 ++#define FSTV0910_P1_TIM_OFF 0xf7020040 ++#define FSTV0910_P1_TIM_CMD 0xf7020030 ++#define FSTV0910_P1_ENVELOP 0xf7020008 ++#define FSTV0910_P1_DIS_PRECHARGE 0xf7020004 ++#define FSTV0910_P1_DISEQC_MODE 0xf7020003 ++ ++/*P1_DISTXSTATUS*/ ++#define RSTV0910_P1_DISTXSTATUS 0xf703 ++#define FSTV0910_P1_TX_FIFO_FULL 0xf7030040 ++#define FSTV0910_P1_TX_IDLE 0xf7030020 ++#define FSTV0910_P1_GAP_BURST 0xf7030010 ++#define FSTV0910_P1_TX_FIFO64B 0xf7030008 ++#define FSTV0910_P1_TX_END 0xf7030004 ++#define FSTV0910_P1_TR_TIMEOUT 0xf7030002 ++#define FSTV0910_P1_TR_FINISH 0xf7030001 ++ ++/*P1_DISTXBYTES*/ ++#define RSTV0910_P1_DISTXBYTES 0xf704 ++#define FSTV0910_P1_TXFIFO_BYTES 0xf70400ff ++ ++/*P1_DISTXFIFO*/ ++#define RSTV0910_P1_DISTXFIFO 0xf705 ++#define FSTV0910_P1_DISEQC_TX_FIFO 0xf70500ff ++ ++/*P1_DISTXF22*/ ++#define RSTV0910_P1_DISTXF22 0xf706 ++#define FSTV0910_P1_F22TX 0xf70600ff ++ ++/*P1_DISTIMEOCFG*/ ++#define RSTV0910_P1_DISTIMEOCFG 0xf708 ++#define FSTV0910_P1_RXCHOICE 0xf7080006 ++#define FSTV0910_P1_TIMEOUT_OFF 0xf7080001 ++ ++/*P1_DISTIMEOUT*/ ++#define RSTV0910_P1_DISTIMEOUT 0xf709 ++#define FSTV0910_P1_TIMEOUT_COUNT 0xf70900ff ++ ++/*P1_DISRXCFG*/ ++#define RSTV0910_P1_DISRXCFG 0xf70a ++#define FSTV0910_P1_DISRX_RESET 0xf70a0080 ++#define FSTV0910_P1_EXTENVELOP 0xf70a0040 ++#define FSTV0910_P1_PINSELECT 0xf70a0038 ++#define FSTV0910_P1_IGNORE_SHORT22K 0xf70a0004 ++#define FSTV0910_P1_SIGNED_RXIN 0xf70a0002 ++#define FSTV0910_P1_DISRX_ON 0xf70a0001 ++ ++/*P1_DISRXSTAT1*/ ++#define RSTV0910_P1_DISRXSTAT1 0xf70b ++#define FSTV0910_P1_RXEND 0xf70b0080 ++#define FSTV0910_P1_RXACTIVE 0xf70b0040 ++#define FSTV0910_P1_RXDETECT 0xf70b0020 ++#define FSTV0910_P1_CONTTONE 0xf70b0010 ++#define FSTV0910_P1_8BFIFOREADY 0xf70b0008 ++#define FSTV0910_P1_FIFOEMPTY 0xf70b0004 ++ ++/*P1_DISRXSTAT0*/ ++#define RSTV0910_P1_DISRXSTAT0 0xf70c ++#define FSTV0910_P1_RXFAIL 0xf70c0080 ++#define FSTV0910_P1_FIFOPFAIL 0xf70c0040 ++#define FSTV0910_P1_RXNONBYTE 0xf70c0020 ++#define FSTV0910_P1_FIFOOVF 0xf70c0010 ++#define FSTV0910_P1_SHORT22K 0xf70c0008 ++#define FSTV0910_P1_RXMSGLOST 0xf70c0004 ++ ++/*P1_DISRXBYTES*/ ++#define RSTV0910_P1_DISRXBYTES 0xf70d ++#define FSTV0910_P1_RXFIFO_BYTES 0xf70d001f ++ ++/*P1_DISRXPARITY1*/ ++#define RSTV0910_P1_DISRXPARITY1 0xf70e ++#define FSTV0910_P1_DISRX_PARITY1 0xf70e00ff ++ ++/*P1_DISRXPARITY0*/ ++#define RSTV0910_P1_DISRXPARITY0 0xf70f ++#define FSTV0910_P1_DISRX_PARITY0 0xf70f00ff ++ ++/*P1_DISRXFIFO*/ ++#define RSTV0910_P1_DISRXFIFO 0xf710 ++#define FSTV0910_P1_DISEQC_RX_FIFO 0xf71000ff ++ ++/*P1_DISRXDC1*/ ++#define RSTV0910_P1_DISRXDC1 0xf711 ++#define FSTV0910_P1_DC_VALUE1 0xf7110103 ++ ++/*P1_DISRXDC0*/ ++#define RSTV0910_P1_DISRXDC0 0xf712 ++#define FSTV0910_P1_DC_VALUE0 0xf71200ff ++ ++/*P1_DISRXF221*/ ++#define RSTV0910_P1_DISRXF221 0xf714 ++#define FSTV0910_P1_F22RX1 0xf714000f ++ ++/*P1_DISRXF220*/ ++#define RSTV0910_P1_DISRXF220 0xf715 ++#define FSTV0910_P1_F22RX0 0xf71500ff ++ ++/*P1_DISRXF100*/ ++#define RSTV0910_P1_DISRXF100 0xf716 ++#define FSTV0910_P1_F100RX 0xf71600ff ++ ++/*P1_DISRXSHORT22K*/ ++#define RSTV0910_P1_DISRXSHORT22K 0xf71c ++#define FSTV0910_P1_SHORT22K_LENGTH 0xf71c001f ++ ++/*P1_ACRPRESC*/ ++#define RSTV0910_P1_ACRPRESC 0xf71e ++#define FSTV0910_P1_ACR_CODFRDY 0xf71e0008 ++#define FSTV0910_P1_ACR_PRESC 0xf71e0007 ++ ++/*P1_ACRDIV*/ ++#define RSTV0910_P1_ACRDIV 0xf71f ++#define FSTV0910_P1_ACR_DIV 0xf71f00ff ++ ++/*P2_DISIRQCFG*/ ++#define RSTV0910_P2_DISIRQCFG 0xf740 ++#define FSTV0910_P2_ENRXEND 0xf7400040 ++#define FSTV0910_P2_ENRXFIFO8B 0xf7400020 ++#define FSTV0910_P2_ENTRFINISH 0xf7400010 ++#define FSTV0910_P2_ENTIMEOUT 0xf7400008 ++#define FSTV0910_P2_ENTXEND 0xf7400004 ++#define FSTV0910_P2_ENTXFIFO64B 0xf7400002 ++#define FSTV0910_P2_ENGAPBURST 0xf7400001 ++ ++/*P2_DISIRQSTAT*/ ++#define RSTV0910_P2_DISIRQSTAT 0xf741 ++#define FSTV0910_P2_IRQRXEND 0xf7410040 ++#define FSTV0910_P2_IRQRXFIFO8B 0xf7410020 ++#define FSTV0910_P2_IRQTRFINISH 0xf7410010 ++#define FSTV0910_P2_IRQTIMEOUT 0xf7410008 ++#define FSTV0910_P2_IRQTXEND 0xf7410004 ++#define FSTV0910_P2_IRQTXFIFO64B 0xf7410002 ++#define FSTV0910_P2_IRQGAPBURST 0xf7410001 ++ ++/*P2_DISTXCFG*/ ++#define RSTV0910_P2_DISTXCFG 0xf742 ++#define FSTV0910_P2_DISTX_RESET 0xf7420080 ++#define FSTV0910_P2_TIM_OFF 0xf7420040 ++#define FSTV0910_P2_TIM_CMD 0xf7420030 ++#define FSTV0910_P2_ENVELOP 0xf7420008 ++#define FSTV0910_P2_DIS_PRECHARGE 0xf7420004 ++#define FSTV0910_P2_DISEQC_MODE 0xf7420003 ++ ++/*P2_DISTXSTATUS*/ ++#define RSTV0910_P2_DISTXSTATUS 0xf743 ++#define FSTV0910_P2_TX_FIFO_FULL 0xf7430040 ++#define FSTV0910_P2_TX_IDLE 0xf7430020 ++#define FSTV0910_P2_GAP_BURST 0xf7430010 ++#define FSTV0910_P2_TX_FIFO64B 0xf7430008 ++#define FSTV0910_P2_TX_END 0xf7430004 ++#define FSTV0910_P2_TR_TIMEOUT 0xf7430002 ++#define FSTV0910_P2_TR_FINISH 0xf7430001 ++ ++/*P2_DISTXBYTES*/ ++#define RSTV0910_P2_DISTXBYTES 0xf744 ++#define FSTV0910_P2_TXFIFO_BYTES 0xf74400ff ++ ++/*P2_DISTXFIFO*/ ++#define RSTV0910_P2_DISTXFIFO 0xf745 ++#define FSTV0910_P2_DISEQC_TX_FIFO 0xf74500ff ++ ++/*P2_DISTXF22*/ ++#define RSTV0910_P2_DISTXF22 0xf746 ++#define FSTV0910_P2_F22TX 0xf74600ff ++ ++/*P2_DISTIMEOCFG*/ ++#define RSTV0910_P2_DISTIMEOCFG 0xf748 ++#define FSTV0910_P2_RXCHOICE 0xf7480006 ++#define FSTV0910_P2_TIMEOUT_OFF 0xf7480001 ++ ++/*P2_DISTIMEOUT*/ ++#define RSTV0910_P2_DISTIMEOUT 0xf749 ++#define FSTV0910_P2_TIMEOUT_COUNT 0xf74900ff ++ ++/*P2_DISRXCFG*/ ++#define RSTV0910_P2_DISRXCFG 0xf74a ++#define FSTV0910_P2_DISRX_RESET 0xf74a0080 ++#define FSTV0910_P2_EXTENVELOP 0xf74a0040 ++#define FSTV0910_P2_PINSELECT 0xf74a0038 ++#define FSTV0910_P2_IGNORE_SHORT22K 0xf74a0004 ++#define FSTV0910_P2_SIGNED_RXIN 0xf74a0002 ++#define FSTV0910_P2_DISRX_ON 0xf74a0001 ++ ++/*P2_DISRXSTAT1*/ ++#define RSTV0910_P2_DISRXSTAT1 0xf74b ++#define FSTV0910_P2_RXEND 0xf74b0080 ++#define FSTV0910_P2_RXACTIVE 0xf74b0040 ++#define FSTV0910_P2_RXDETECT 0xf74b0020 ++#define FSTV0910_P2_CONTTONE 0xf74b0010 ++#define FSTV0910_P2_8BFIFOREADY 0xf74b0008 ++#define FSTV0910_P2_FIFOEMPTY 0xf74b0004 ++ ++/*P2_DISRXSTAT0*/ ++#define RSTV0910_P2_DISRXSTAT0 0xf74c ++#define FSTV0910_P2_RXFAIL 0xf74c0080 ++#define FSTV0910_P2_FIFOPFAIL 0xf74c0040 ++#define FSTV0910_P2_RXNONBYTE 0xf74c0020 ++#define FSTV0910_P2_FIFOOVF 0xf74c0010 ++#define FSTV0910_P2_SHORT22K 0xf74c0008 ++#define FSTV0910_P2_RXMSGLOST 0xf74c0004 ++ ++/*P2_DISRXBYTES*/ ++#define RSTV0910_P2_DISRXBYTES 0xf74d ++#define FSTV0910_P2_RXFIFO_BYTES 0xf74d001f ++ ++/*P2_DISRXPARITY1*/ ++#define RSTV0910_P2_DISRXPARITY1 0xf74e ++#define FSTV0910_P2_DISRX_PARITY1 0xf74e00ff ++ ++/*P2_DISRXPARITY0*/ ++#define RSTV0910_P2_DISRXPARITY0 0xf74f ++#define FSTV0910_P2_DISRX_PARITY0 0xf74f00ff ++ ++/*P2_DISRXFIFO*/ ++#define RSTV0910_P2_DISRXFIFO 0xf750 ++#define FSTV0910_P2_DISEQC_RX_FIFO 0xf75000ff ++ ++/*P2_DISRXDC1*/ ++#define RSTV0910_P2_DISRXDC1 0xf751 ++#define FSTV0910_P2_DC_VALUE1 0xf7510103 ++ ++/*P2_DISRXDC0*/ ++#define RSTV0910_P2_DISRXDC0 0xf752 ++#define FSTV0910_P2_DC_VALUE0 0xf75200ff ++ ++/*P2_DISRXF221*/ ++#define RSTV0910_P2_DISRXF221 0xf754 ++#define FSTV0910_P2_F22RX1 0xf754000f ++ ++/*P2_DISRXF220*/ ++#define RSTV0910_P2_DISRXF220 0xf755 ++#define FSTV0910_P2_F22RX0 0xf75500ff ++ ++/*P2_DISRXF100*/ ++#define RSTV0910_P2_DISRXF100 0xf756 ++#define FSTV0910_P2_F100RX 0xf75600ff ++ ++/*P2_DISRXSHORT22K*/ ++#define RSTV0910_P2_DISRXSHORT22K 0xf75c ++#define FSTV0910_P2_SHORT22K_LENGTH 0xf75c001f ++ ++/*P2_ACRPRESC*/ ++#define RSTV0910_P2_ACRPRESC 0xf75e ++#define FSTV0910_P2_ACR_CODFRDY 0xf75e0008 ++#define FSTV0910_P2_ACR_PRESC 0xf75e0007 ++ ++/*P2_ACRDIV*/ ++#define RSTV0910_P2_ACRDIV 0xf75f ++#define FSTV0910_P2_ACR_DIV 0xf75f00ff ++ ++/*P1_NBITER_NF4*/ ++#define RSTV0910_P1_NBITER_NF4 0xfa03 ++#define FSTV0910_P1_NBITER_NF_QPSK_1_2 0xfa0300ff ++ ++/*P1_NBITER_NF5*/ ++#define RSTV0910_P1_NBITER_NF5 0xfa04 ++#define FSTV0910_P1_NBITER_NF_QPSK_3_5 0xfa0400ff ++ ++/*P1_NBITER_NF6*/ ++#define RSTV0910_P1_NBITER_NF6 0xfa05 ++#define FSTV0910_P1_NBITER_NF_QPSK_2_3 0xfa0500ff ++ ++/*P1_NBITER_NF7*/ ++#define RSTV0910_P1_NBITER_NF7 0xfa06 ++#define FSTV0910_P1_NBITER_NF_QPSK_3_4 0xfa0600ff ++ ++/*P1_NBITER_NF8*/ ++#define RSTV0910_P1_NBITER_NF8 0xfa07 ++#define FSTV0910_P1_NBITER_NF_QPSK_4_5 0xfa0700ff ++ ++/*P1_NBITER_NF9*/ ++#define RSTV0910_P1_NBITER_NF9 0xfa08 ++#define FSTV0910_P1_NBITER_NF_QPSK_5_6 0xfa0800ff ++ ++/*P1_NBITER_NF10*/ ++#define RSTV0910_P1_NBITER_NF10 0xfa09 ++#define FSTV0910_P1_NBITER_NF_QPSK_8_9 0xfa0900ff ++ ++/*P1_NBITER_NF11*/ ++#define RSTV0910_P1_NBITER_NF11 0xfa0a ++#define FSTV0910_P1_NBITER_NF_QPSK_9_10 0xfa0a00ff ++ ++/*P1_NBITER_NF12*/ ++#define RSTV0910_P1_NBITER_NF12 0xfa0b ++#define FSTV0910_P1_NBITER_NF_8PSK_3_5 0xfa0b00ff ++ ++/*P1_NBITER_NF13*/ ++#define RSTV0910_P1_NBITER_NF13 0xfa0c ++#define FSTV0910_P1_NBITER_NF_8PSK_2_3 0xfa0c00ff ++ ++/*P1_NBITER_NF14*/ ++#define RSTV0910_P1_NBITER_NF14 0xfa0d ++#define FSTV0910_P1_NBITER_NF_8PSK_3_4 0xfa0d00ff ++ ++/*P1_NBITER_NF15*/ ++#define RSTV0910_P1_NBITER_NF15 0xfa0e ++#define FSTV0910_P1_NBITER_NF_8PSK_5_6 0xfa0e00ff ++ ++/*P1_NBITER_NF16*/ ++#define RSTV0910_P1_NBITER_NF16 0xfa0f ++#define FSTV0910_P1_NBITER_NF_8PSK_8_9 0xfa0f00ff ++ ++/*P1_NBITER_NF17*/ ++#define RSTV0910_P1_NBITER_NF17 0xfa10 ++#define FSTV0910_P1_NBITER_NF_8PSK_9_10 0xfa1000ff ++ ++/*GAINLLR_NF4*/ ++#define RSTV0910_GAINLLR_NF4 0xfa43 ++#define FSTV0910_GAINLLR_NF_QPSK_1_2 0xfa43007f ++ ++/*GAINLLR_NF5*/ ++#define RSTV0910_GAINLLR_NF5 0xfa44 ++#define FSTV0910_GAINLLR_NF_QPSK_3_5 0xfa44007f ++ ++/*GAINLLR_NF6*/ ++#define RSTV0910_GAINLLR_NF6 0xfa45 ++#define FSTV0910_GAINLLR_NF_QPSK_2_3 0xfa45007f ++ ++/*GAINLLR_NF7*/ ++#define RSTV0910_GAINLLR_NF7 0xfa46 ++#define FSTV0910_GAINLLR_NF_QPSK_3_4 0xfa46007f ++ ++/*GAINLLR_NF8*/ ++#define RSTV0910_GAINLLR_NF8 0xfa47 ++#define FSTV0910_GAINLLR_NF_QPSK_4_5 0xfa47007f ++ ++/*GAINLLR_NF9*/ ++#define RSTV0910_GAINLLR_NF9 0xfa48 ++#define FSTV0910_GAINLLR_NF_QPSK_5_6 0xfa48007f ++ ++/*GAINLLR_NF10*/ ++#define RSTV0910_GAINLLR_NF10 0xfa49 ++#define FSTV0910_GAINLLR_NF_QPSK_8_9 0xfa49007f ++ ++/*GAINLLR_NF11*/ ++#define RSTV0910_GAINLLR_NF11 0xfa4a ++#define FSTV0910_GAINLLR_NF_QPSK_9_10 0xfa4a007f ++ ++/*GAINLLR_NF12*/ ++#define RSTV0910_GAINLLR_NF12 0xfa4b ++#define FSTV0910_GAINLLR_NF_8PSK_3_5 0xfa4b007f ++ ++/*GAINLLR_NF13*/ ++#define RSTV0910_GAINLLR_NF13 0xfa4c ++#define FSTV0910_GAINLLR_NF_8PSK_2_3 0xfa4c007f ++ ++/*GAINLLR_NF14*/ ++#define RSTV0910_GAINLLR_NF14 0xfa4d ++#define FSTV0910_GAINLLR_NF_8PSK_3_4 0xfa4d007f ++ ++/*GAINLLR_NF15*/ ++#define RSTV0910_GAINLLR_NF15 0xfa4e ++#define FSTV0910_GAINLLR_NF_8PSK_5_6 0xfa4e007f ++ ++/*GAINLLR_NF16*/ ++#define RSTV0910_GAINLLR_NF16 0xfa4f ++#define FSTV0910_GAINLLR_NF_8PSK_8_9 0xfa4f007f ++ ++/*GAINLLR_NF17*/ ++#define RSTV0910_GAINLLR_NF17 0xfa50 ++#define FSTV0910_GAINLLR_NF_8PSK_9_10 0xfa50007f ++ ++/*CFGEXT*/ ++#define RSTV0910_CFGEXT 0xfa80 ++#define FSTV0910_BYPFIFOBCH 0xfa800080 ++#define FSTV0910_BYPBCH 0xfa800040 ++#define FSTV0910_BYPLDPC 0xfa800020 ++#define FSTV0910_BYPFIFOBCHF 0xfa800010 ++#define FSTV0910_INVLLRSIGN 0xfa800008 ++#define FSTV0910_SHORTMULT 0xfa800004 ++#define FSTV0910_ENSTOPDEC 0xfa800002 ++ ++/*GENCFG*/ ++#define RSTV0910_GENCFG 0xfa86 ++#define FSTV0910_LEG_ITER 0xfa860040 ++#define FSTV0910_NOSHFRD1 0xfa860020 ++#define FSTV0910_BROADCAST 0xfa860010 ++#define FSTV0910_NOSHFRD2 0xfa860008 ++#define FSTV0910_BCHERRFLAG 0xfa860004 ++#define FSTV0910_CROSSINPUT 0xfa860002 ++#define FSTV0910_DDEMOD 0xfa860001 ++ ++/*LDPCERR1*/ ++#define RSTV0910_LDPCERR1 0xfa96 ++#define FSTV0910_LDPC_ERRORS1 0xfa9600ff ++ ++/*LDPCERR0*/ ++#define RSTV0910_LDPCERR0 0xfa97 ++#define FSTV0910_LDPC_ERRORS0 0xfa9700ff ++ ++/*BCHERR*/ ++#define RSTV0910_BCHERR 0xfa98 ++#define FSTV0910_ERRORFLAG 0xfa980010 ++#define FSTV0910_BCH_ERRORS_COUNTER 0xfa98000f ++ ++/*P1_MAXEXTRAITER*/ ++#define RSTV0910_P1_MAXEXTRAITER 0xfab1 ++#define FSTV0910_P1_MAX_EXTRA_ITER 0xfab100ff ++ ++/*P2_MAXEXTRAITER*/ ++#define RSTV0910_P2_MAXEXTRAITER 0xfab6 ++#define FSTV0910_P2_MAX_EXTRA_ITER 0xfab600ff ++ ++/*P1_STATUSITER*/ ++#define RSTV0910_P1_STATUSITER 0xfabc ++#define FSTV0910_P1_STATUS_ITER 0xfabc00ff ++ ++/*P1_STATUSMAXITER*/ ++#define RSTV0910_P1_STATUSMAXITER 0xfabd ++#define FSTV0910_P1_STATUS_MAX_ITER 0xfabd00ff ++ ++/*P2_STATUSITER*/ ++#define RSTV0910_P2_STATUSITER 0xfabe ++#define FSTV0910_P2_STATUS_ITER 0xfabe00ff ++ ++/*P2_STATUSMAXITER*/ ++#define RSTV0910_P2_STATUSMAXITER 0xfabf ++#define FSTV0910_P2_STATUS_MAX_ITER 0xfabf00ff ++ ++/*P2_NBITER_NF4*/ ++#define RSTV0910_P2_NBITER_NF4 0xfac3 ++#define FSTV0910_P2_NBITER_NF_QPSK_1_2 0xfac300ff ++ ++/*P2_NBITER_NF5*/ ++#define RSTV0910_P2_NBITER_NF5 0xfac4 ++#define FSTV0910_P2_NBITER_NF_QPSK_3_5 0xfac400ff ++ ++/*P2_NBITER_NF6*/ ++#define RSTV0910_P2_NBITER_NF6 0xfac5 ++#define FSTV0910_P2_NBITER_NF_QPSK_2_3 0xfac500ff ++ ++/*P2_NBITER_NF7*/ ++#define RSTV0910_P2_NBITER_NF7 0xfac6 ++#define FSTV0910_P2_NBITER_NF_QPSK_3_4 0xfac600ff ++ ++/*P2_NBITER_NF8*/ ++#define RSTV0910_P2_NBITER_NF8 0xfac7 ++#define FSTV0910_P2_NBITER_NF_QPSK_4_5 0xfac700ff ++ ++/*P2_NBITER_NF9*/ ++#define RSTV0910_P2_NBITER_NF9 0xfac8 ++#define FSTV0910_P2_NBITER_NF_QPSK_5_6 0xfac800ff ++ ++/*P2_NBITER_NF10*/ ++#define RSTV0910_P2_NBITER_NF10 0xfac9 ++#define FSTV0910_P2_NBITER_NF_QPSK_8_9 0xfac900ff ++ ++/*P2_NBITER_NF11*/ ++#define RSTV0910_P2_NBITER_NF11 0xfaca ++#define FSTV0910_P2_NBITER_NF_QPSK_9_10 0xfaca00ff ++ ++/*P2_NBITER_NF12*/ ++#define RSTV0910_P2_NBITER_NF12 0xfacb ++#define FSTV0910_P2_NBITER_NF_8PSK_3_5 0xfacb00ff ++ ++/*P2_NBITER_NF13*/ ++#define RSTV0910_P2_NBITER_NF13 0xfacc ++#define FSTV0910_P2_NBITER_NF_8PSK_2_3 0xfacc00ff ++ ++/*P2_NBITER_NF14*/ ++#define RSTV0910_P2_NBITER_NF14 0xfacd ++#define FSTV0910_P2_NBITER_NF_8PSK_3_4 0xfacd00ff ++ ++/*P2_NBITER_NF15*/ ++#define RSTV0910_P2_NBITER_NF15 0xface ++#define FSTV0910_P2_NBITER_NF_8PSK_5_6 0xface00ff ++ ++/*P2_NBITER_NF16*/ ++#define RSTV0910_P2_NBITER_NF16 0xfacf ++#define FSTV0910_P2_NBITER_NF_8PSK_8_9 0xfacf00ff ++ ++/*P2_NBITER_NF17*/ ++#define RSTV0910_P2_NBITER_NF17 0xfad0 ++#define FSTV0910_P2_NBITER_NF_8PSK_9_10 0xfad000ff ++ ++/*TSTRES0*/ ++#define RSTV0910_TSTRES0 0xff11 ++#define FSTV0910_FRESFEC 0xff110080 ++#define FSTV0910_FRESTS 0xff110040 ++#define FSTV0910_FRESVIT1 0xff110020 ++#define FSTV0910_FRESVIT2 0xff110010 ++#define FSTV0910_FRESSYM1 0xff110008 ++#define FSTV0910_FRESSYM2 0xff110004 ++#define FSTV0910_FRESMAS 0xff110002 ++#define FSTV0910_FRESINT 0xff110001 ++ ++/*P2_TCTL4*/ ++#define RSTV0910_P2_TCTL4 0xff28 ++#define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2800c0 ++#define FSTV0910_P2_TSTINV_PHERR 0xff280020 ++#define FSTV0910_P2_EN_PLHCALC 0xff280010 ++#define FSTV0910_P2_TETA3L_RSTTETA3D 0xff280008 ++#define FSTV0910_P2_DIS_FORCEBETA2 0xff280004 ++#define FSTV0910_P2_CAR3_NOTRACEBACK 0xff280002 ++#define FSTV0910_P2_CAR3_NOFORWARD 0xff280001 ++ ++/*P1_TCTL4*/ ++#define RSTV0910_P1_TCTL4 0xff48 ++#define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4800c0 ++#define FSTV0910_P1_TSTINV_PHERR 0xff480020 ++#define FSTV0910_P1_EN_PLHCALC 0xff480010 ++#define FSTV0910_P1_TETA3L_RSTTETA3D 0xff480008 ++#define FSTV0910_P1_DIS_FORCEBETA2 0xff480004 ++#define FSTV0910_P1_CAR3_NOTRACEBACK 0xff480002 ++#define FSTV0910_P1_CAR3_NOFORWARD 0xff480001 ++ ++#define STV0910_NBREGS 735 ++#define STV0910_NBFIELDS 1776 +diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c +new file mode 100644 +index 0000000..fbd6365 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv6111.c +@@ -0,0 +1,450 @@ ++/* ++ * Driver for the ST STV6111 tuner ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++ ++struct stv { ++ struct i2c_adapter *i2c; ++ u8 adr; ++ ++ u8 reg[11]; ++ u32 ref_freq; ++}; ++ ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ pr_err("stv6111: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("stv6111: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int write_regs(struct stv *state, int reg, int len) ++{ ++ u8 d[12]; ++ ++ memcpy(&d[1], &state->reg[reg], len); ++ d[0] = reg; ++ return i2c_write(state->i2c, state->adr, d, len + 1); ++} ++ ++#if 0 ++static int write_reg(struct stv *state, u8 reg, u8 val) ++{ ++ u8 d[2] = {reg, val}; ++ ++ return i2c_write(state->i2c, state->adr, d, 2); ++} ++#endif ++ ++static int read_reg(struct stv *state, u8 reg, u8 *val) ++{ ++ return i2c_read(state->i2c, state->adr, ®, 1, val, 1); ++} ++ ++static int read_regs(struct stv *state, u8 reg, u8 *val, int len) ++{ ++ return i2c_read(state->i2c, state->adr, ®, 1, val, len); ++} ++ ++static void dump_regs(struct stv *state) ++{ ++ u8 d[11], *c = &state->reg[0]; ++ ++ read_regs(state, 0, d, 11); ++ pr_info("stv6111_regs = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], ++ d[8], d[9], d[10]); ++ pr_info("reg[] = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], ++ c[8], c[9], c[10]); ++} ++ ++static int wait_for_call_done(struct stv *state, u8 mask) ++{ ++ int status = 0; ++ u32 LockRetryCount = 10; ++ ++ while (LockRetryCount > 0) { ++ u8 Status; ++ ++ status = read_reg(state, 9, &Status); ++ if (status < 0) ++ return status; ++ ++ if ((Status & mask) == 0) ++ break; ++ usleep_range(4000, 6000); ++ LockRetryCount -= 1; ++ ++ status = -1; ++ } ++ return status; ++} ++ ++static void init_state(struct stv *state) ++{ ++ u32 clkdiv = 0; ++ u32 agcmode = 0; ++ u32 agcref = 2; ++ u32 agcset = 0xffffffff; ++ u32 bbmode = 0xffffffff; ++ ++ state->reg[0] = 0x08; ++ state->reg[1] = 0x41; ++ state->reg[2] = 0x8f; ++ state->reg[3] = 0x00; ++ state->reg[4] = 0xce; ++ state->reg[5] = 0x54; ++ state->reg[6] = 0x55; ++ state->reg[7] = 0x45; ++ state->reg[8] = 0x46; ++ state->reg[9] = 0xbd; ++ state->reg[10] = 0x11; ++ ++ state->ref_freq = 16000; ++ ++ ++ if (clkdiv <= 3) ++ state->reg[0x00] |= (clkdiv & 0x03); ++ if (agcmode <= 3) { ++ state->reg[0x03] |= (agcmode << 5); ++ if (agcmode == 0x01) ++ state->reg[0x01] |= 0x30; ++ } ++ if (bbmode <= 3) ++ state->reg[0x01] = (state->reg[0x01] & ~0x30) | (bbmode << 4); ++ if (agcref <= 7) ++ state->reg[0x03] |= agcref; ++ if (agcset <= 31) ++ state->reg[0x02] = (state->reg[0x02] & ~0x1F) | agcset | 0x40; ++} ++ ++static int attach_init(struct stv *state) ++{ ++ if (write_regs(state, 0, 11)) ++ return -1; ++ pr_info("attach_init OK\n"); ++ dump_regs(state); ++ return 0; ++} ++ ++static int sleep(struct dvb_frontend *fe) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ ++ pr_info("tuner sleep\n"); ++ return 0; ++} ++ ++static int init(struct dvb_frontend *fe) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ pr_info("init\n"); ++ return 0; ++} ++ ++static int release(struct dvb_frontend *fe) ++{ ++ kfree(fe->tuner_priv); ++ fe->tuner_priv = NULL; ++ return 0; ++} ++ ++static int set_bandwidth(struct dvb_frontend *fe, u32 CutOffFrequency) ++{ ++ struct stv *state = fe->tuner_priv; ++ u32 index = (CutOffFrequency + 999999) / 1000000; ++ ++ if (index < 6) ++ index = 6; ++ if (index > 50) ++ index = 50; ++ if ((state->reg[0x08] & ~0xFC) == ((index-6) << 2)) ++ return 0; ++ ++ state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index-6) << 2); ++ state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08; ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ write_regs(state, 0x08, 2); ++ wait_for_call_done(state, 0x08); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ return 0; ++} ++ ++static int set_lof(struct stv *state, u32 LocalFrequency, u32 CutOffFrequency) ++{ ++ u32 index = (CutOffFrequency + 999999) / 1000000; ++ u32 Frequency = (LocalFrequency + 500) / 1000; ++ u32 p = 1, psel = 0, fvco, div, frac; ++ u8 Icp, tmp; ++ ++ pr_info("F = %u, COF = %u\n", Frequency, CutOffFrequency); ++ if (index < 6) ++ index = 6; ++ if (index > 50) ++ index = 50; ++ ++ if (Frequency <= 1300000) { ++ p = 4; ++ psel = 1; ++ } else { ++ p = 2; ++ psel = 0; ++ } ++ fvco = Frequency * p; ++ div = fvco / state->ref_freq; ++ frac = fvco % state->ref_freq; ++ frac = MulDiv32(frac, 0x40000, state->ref_freq); ++ ++ Icp = 0; ++ if (fvco < 2700000) ++ Icp = 0; ++ else if (fvco < 2950000) ++ Icp = 1; ++ else if (fvco < 3300000) ++ Icp = 2; ++ else if (fvco < 3700000) ++ Icp = 3; ++ else if (fvco < 4200000) ++ Icp = 5; ++ else if (fvco < 4800000) ++ Icp = 6; ++ else ++ Icp = 7; ++ ++ state->reg[0x02] |= 0x80; /* LNA IIP3 Mode */ ++ ++ state->reg[0x03] = (state->reg[0x03] & ~0x80) | (psel << 7); ++ state->reg[0x04] = (div & 0xFF); ++ state->reg[0x05] = (((div >> 8) & 0x01) | ((frac & 0x7F) << 1)) & 0xff; ++ state->reg[0x06] = ((frac >> 7) & 0xFF); ++ state->reg[0x07] = (state->reg[0x07] & ~0x07) | ((frac >> 15) & 0x07); ++ state->reg[0x07] = (state->reg[0x07] & ~0xE0) | (Icp << 5); ++ ++ state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2); ++ /* Start cal vco,CF */ ++ state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x0C; ++ write_regs(state, 2, 8); ++ ++ wait_for_call_done(state, 0x0C); ++ ++ usleep_range(10000, 12000); ++ ++ read_reg(state, 0x03, &tmp); ++ if (tmp & 0x10) { ++ state->reg[0x02] &= ~0x80; /* LNA NF Mode */ ++ write_regs(state, 2, 1); ++ } ++ read_reg(state, 0x08, &tmp); ++ ++ dump_regs(state); ++ return 0; ++} ++ ++static int set_params(struct dvb_frontend *fe) ++{ ++ struct stv *state = fe->tuner_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ int status; ++ u32 freq, symb, cutoff; ++ ++ if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2) ++ return -EINVAL; ++ ++ freq = p->frequency * 1000; ++ symb = p->symbol_rate; ++ cutoff = 5000000 + MulDiv32(p->symbol_rate, 135, 200); ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ set_lof(state, freq, cutoff); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ return status; ++} ++ ++static int get_frequency(struct dvb_frontend *fe, u32 *frequency) ++{ ++ *frequency = 0; ++ return 0; ++} ++ ++static u32 AGC_Gain[] = { ++ 000, /* 0.0 */ ++ 000, /* 0.1 */ ++ 1000, /* 0.2 */ ++ 2000, /* 0.3 */ ++ 3000, /* 0.4 */ ++ 4000, /* 0.5 */ ++ 5000, /* 0.6 */ ++ 6000, /* 0.7 */ ++ 7000, /* 0.8 */ ++ 14000, /* 0.9 */ ++ 20000, /* 1.0 */ ++ 27000, /* 1.1 */ ++ 32000, /* 1.2 */ ++ 37000, /* 1.3 */ ++ 42000, /* 1.4 */ ++ 47000, /* 1.5 */ ++ 50000, /* 1.6 */ ++ 53000, /* 1.7 */ ++ 56000, /* 1.8 */ ++ 58000, /* 1.9 */ ++ 60000, /* 2.0 */ ++ 62000, /* 2.1 */ ++ 63000, /* 2.2 */ ++ 64000, /* 2.3 */ ++ 64500, /* 2.4 */ ++ 65000, /* 2.5 */ ++ 65500, /* 2.6 */ ++ 66000, /* 2.7 */ ++ 66500, /* 2.8 */ ++ 67000, /* 2.9 */ ++}; ++ ++static int get_rf_strength(struct dvb_frontend *fe, u16 *st) ++{ ++ *st = 0; ++#if 0 ++ struct stv *state = fe->tuner_priv; ++ s32 Gain; ++ u32 Index = RFAgc / 100; ++ if (Index >= (sizeof(AGC_Gain) / sizeof(AGC_Gain[0]) - 1)) ++ Gain = AGC_Gain[sizeof(AGC_Gain) / sizeof(AGC_Gain[0]) - 1]; ++ else ++ Gain = AGC_Gain[Index] + ++ ((AGC_Gain[Index+1] - AGC_Gain[Index]) * ++ (RFAgc % 100)) / 100; ++ *st = Gain; ++#endif ++ return 0; ++} ++ ++static int get_if(struct dvb_frontend *fe, u32 *frequency) ++{ ++ *frequency = 0; ++ return 0; ++} ++ ++static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) ++{ ++ return 0; ++} ++ ++static struct dvb_tuner_ops tuner_ops = { ++ .info = { ++ .name = "STV6111", ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_step = 0 ++ }, ++ .init = init, ++ .sleep = sleep, ++ .set_params = set_params, ++ .release = release, ++ .get_frequency = get_frequency, ++ .get_if_frequency = get_if, ++ .get_bandwidth = get_bandwidth, ++ .get_rf_strength = get_rf_strength, ++ .set_bandwidth = set_bandwidth, ++}; ++ ++struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr) ++{ ++ struct stv *state; ++ int stat; ++ ++ state = kzalloc(sizeof(struct stv), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ state->adr = adr; ++ state->i2c = i2c; ++ memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops)); ++ init_state(state); ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ stat = attach_init(state); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ if (stat < 0) { ++ kfree(state); ++ return 0; ++ } ++ fe->tuner_priv = state; ++ return fe; ++} ++EXPORT_SYMBOL_GPL(stv6111_attach); ++ ++MODULE_DESCRIPTION("STV6111 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * Local variables: ++ * c-basic-offset: 8 ++ * End: ++ */ +diff --git a/drivers/media/dvb-frontends/stv6111.h b/drivers/media/dvb-frontends/stv6111.h +new file mode 100644 +index 0000000..31d200c +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv6111.h +@@ -0,0 +1,5 @@ ++#ifndef _STV6111_H_ ++#define _STV6111_H_ ++struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr); ++#endif +diff --git a/drivers/media/dvb-frontends/tda18212dd.c b/drivers/media/dvb-frontends/tda18212dd.c +new file mode 100644 +index 0000000..7d99fd5 +--- /dev/null ++++ b/drivers/media/dvb-frontends/tda18212dd.c +@@ -0,0 +1,974 @@ ++/* ++ * tda18212: Driver for the TDA18212 tuner ++ * ++ * Copyright (C) 2011-2013 Digital Devices GmbH ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++ ++#ifndef CHK_ERROR ++#define CHK_ERROR(s) if ((status = s) < 0) break ++#endif ++ ++#define MASTER_PSM_AGC1 0 ++#define MASTER_AGC1_6_15dB 1 ++ ++#define SLAVE_PSM_AGC1 1 ++#define SLAVE_AGC1_6_15dB 0 ++ ++/* 0 = 2 Vpp ... 2 = 1 Vpp, 7 = 0.5 Vpp */ ++#define IF_LEVEL_DVBC 2 ++#define IF_LEVEL_DVBT 2 ++ ++enum { ++ ID_1 = 0x00, ++ ID_2 = 0x01, ++ ID_3 = 0x02, ++ THERMO_1, ++ THERMO_2, ++ POWER_STATE_1, ++ POWER_STATE_2, ++ INPUT_POWER_LEVEL, ++ IRQ_STATUS, ++ IRQ_ENABLE, ++ IRQ_CLEAR, ++ IRQ_SET, ++ AGC1_1, ++ AGC2_1, ++ AGCK_1, ++ RF_AGC_1, ++ IR_MIXER_1 = 0x10, ++ AGC5_1, ++ IF_AGC, ++ IF_1, ++ REFERENCE, ++ IF_FREQUENCY_1, ++ RF_FREQUENCY_1, ++ RF_FREQUENCY_2, ++ RF_FREQUENCY_3, ++ MSM_1, ++ MSM_2, ++ PSM_1, ++ DCC_1, ++ FLO_MAX, ++ IR_CAL_1, ++ IR_CAL_2, ++ IR_CAL_3 = 0x20, ++ IR_CAL_4, ++ VSYNC_MGT, ++ IR_MIXER_2, ++ AGC1_2, ++ AGC5_2, ++ RF_CAL_1, ++ RF_CAL_2, ++ RF_CAL_3, ++ RF_CAL_4, ++ RF_CAL_5, ++ RF_CAL_6, ++ RF_FILTER_1, ++ RF_FILTER_2, ++ RF_FILTER_3, ++ RF_BAND_PASS_FILTER, ++ CP_CURRENT = 0x30, ++ AGC_DET_OUT = 0x31, ++ RF_AGC_GAIN_1 = 0x32, ++ RF_AGC_GAIN_2 = 0x33, ++ IF_AGC_GAIN = 0x34, ++ POWER_1 = 0x35, ++ POWER_2 = 0x36, ++ MISC_1, ++ RFCAL_LOG_1, ++ RFCAL_LOG_2, ++ RFCAL_LOG_3, ++ RFCAL_LOG_4, ++ RFCAL_LOG_5, ++ RFCAL_LOG_6, ++ RFCAL_LOG_7, ++ RFCAL_LOG_8, ++ RFCAL_LOG_9 = 0x40, ++ RFCAL_LOG_10 = 0x41, ++ RFCAL_LOG_11 = 0x42, ++ RFCAL_LOG_12 = 0x43, ++ REG_MAX, ++}; ++ ++enum HF_Standard { ++ HF_None = 0, HF_B, HF_DK, HF_G, HF_I, HF_L, HF_L1, HF_MN, HF_FM_Radio, ++ HF_AnalogMax, HF_DVBT_6MHZ, HF_DVBT_7MHZ, HF_DVBT_8MHZ, ++ HF_DVBT, HF_ATSC, HF_DVBC_6MHZ, HF_DVBC_7MHZ, ++ HF_DVBC_8MHZ, HF_DVBC ++}; ++ ++struct SStandardParams { ++ s32 m_IFFrequency; ++ u32 m_BandWidth; ++ u8 m_IF_1; /* FF IF_HP_fc:2 IF_Notch:1 LP_FC_Offset:2 LP_FC:3 */ ++ u8 m_IR_MIXER_2; /* 03 :6 HI_Pass:1 DC_Notch:1 */ ++ u8 m_AGC1_1; /* 0F :4 AGC1_Top:4 */ ++ u8 m_AGC2_1; /* 0F :4 AGC2_Top:4 */ ++ /*EF RF_AGC_Adapt:1 RF_AGC_Adapt_Top:2 :1 RF_Atten_3dB:1 RF_AGC_Top:3 */ ++ u8 m_RF_AGC_1_Low; ++ /*EF RF_AGC_Adapt:1 RF_AGC_Adapt_Top:2 :1 RF_Atten_3dB:1 RF_AGC_Top:3 */ ++ u8 m_RF_AGC_1_High; ++ u8 m_IR_MIXER_1; /* 0F :4 IR_mixer_Top:4 */ ++ u8 m_AGC5_1; /* 1F :3 AGC5_Ana AGC5_Top:4 */ ++ u8 m_AGCK_1; /* 0F :4 AGCK_Step:2 AGCK_Mode:2 */ ++ u8 m_PSM_1; /* 20 :2 PSM_StoB:1 :5 */ ++ bool m_AGC1_Freeze; ++ bool m_LTO_STO_immune; ++}; ++ ++#if 0 ++static struct SStandardParams ++m_StandardTable[HF_DVBC_8MHZ - HF_DVBT_6MHZ + 1] = { ++ { 3250000, 6000000, 0x20, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_6MHZ */ ++ { 3500000, 7000000, 0x31, 0x01, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_7MHZ */ ++ { 4000000, 8000000, 0x22, 0x01, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_8MHZ */ ++ { 0000000, 0, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, false, false }, /* HF_DVBT (Unused) */ ++ { 3250000, 6000000, 0x20, 0x03, 0x0A, 0x07, 0x6D, ++ 0x6D, 0x0E, 0x0E, 0x02, 0x20, false, false }, /* HF_ATSC */ ++ { 3600000, 6000000, 0x10, 0x01, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_6MHZ */ ++ { 5000000, 7000000, 0x93, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, ++ /* HF_DVBC_7MHZ (not documented by NXP, use same settings as 8 MHZ) */ ++ { 5000000, 8000000, 0x43, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_8MHZ */ ++}; ++#else ++static struct SStandardParams ++m_StandardTable[HF_DVBC_8MHZ - HF_DVBT_6MHZ + 1] = { ++ { 4000000, 6000000, 0x41, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_6MHZ */ ++ { 4500000, 7000000, 0x42, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_7MHZ */ ++ { 5000000, 8000000, 0x43, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_8MHZ */ ++ /* ------------------------------ */ ++ { 0000000, 0, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, false, false }, /* HF_DVBT (Unused)*/ ++ { 3250000, 6000000, 0x20, 0x03, 0x0A, 0x07, 0x6D, ++ 0x6D, 0x0E, 0x0E, 0x02, 0x20, false, false }, /* HF_ATSC */ ++ { 3600000, 6000000, 0x10, 0x01, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_6MHZ */ ++ { 5000000, 7000000, 0x93, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, ++ /* HF_DVBC_7MHZ (not documented by NXP, use same settings as 8 MHZ) */ ++ { 5000000, 8000000, 0x43, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_8MHZ */ ++}; ++#endif ++ ++struct tda_state { ++ struct i2c_adapter *i2c; ++ u8 adr; ++ ++ enum HF_Standard m_Standard; ++ u32 m_Frequency; ++ u32 IF; ++ ++ bool m_isMaster; ++ bool m_bPowerMeasurement; ++ bool m_bLTEnable; ++ bool m_bEnableFreeze; ++ ++ u16 m_ID; ++ ++ s32 m_SettlingTime; ++ ++ u8 m_IFLevelDVBC; ++ u8 m_IFLevelDVBT; ++ u8 Regs[REG_MAX]; ++ u8 m_LastPowerLevel; ++}; ++ ++static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, ++ .buf = data, .len = len} }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ pr_err("tda18212dd: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("tda18212: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int write_regs(struct tda_state *state, ++ u8 SubAddr, u8 *Regs, u16 nRegs) ++{ ++ u8 data[REG_MAX + 1]; ++ ++ data[0] = SubAddr; ++ memcpy(data + 1, Regs, nRegs); ++ return i2c_write(state->i2c, state->adr, data, nRegs + 1); ++} ++ ++static int write_reg(struct tda_state *state, u8 SubAddr, u8 Reg) ++{ ++ u8 msg[2] = {SubAddr, Reg}; ++ ++ return i2c_write(state->i2c, state->adr, msg, 2); ++} ++ ++static int Read(struct tda_state *state, u8 *Regs) ++{ ++ return i2c_readn(state->i2c, state->adr, Regs, REG_MAX); ++} ++ ++static int update_regs(struct tda_state *state, u8 RegFrom, u8 RegTo) ++{ ++ return write_regs(state, RegFrom, ++ &state->Regs[RegFrom], RegTo-RegFrom + 1); ++} ++ ++static int update_reg(struct tda_state *state, u8 Reg) ++{ ++ return write_reg(state, Reg, state->Regs[Reg]); ++} ++ ++ ++static int read_regs(struct tda_state *state, ++ u8 SubAddr, u8 *Regs, u16 nRegs) ++{ ++ return i2c_read(state->i2c, state->adr, ++ &SubAddr, 1, Regs, nRegs); ++} ++ ++static int read_reg(struct tda_state *state, ++ u8 SubAddr, u8 *Reg) ++{ ++ return i2c_read(state->i2c, state->adr, ++ &SubAddr, 1, Reg, 1); ++} ++ ++static int read_reg1(struct tda_state *state, u8 Reg) ++{ ++ return read_reg(state, Reg, &state->Regs[Reg]); ++} ++ ++static void init_state(struct tda_state *state) ++{ ++ u32 ulIFLevelDVBC = IF_LEVEL_DVBC; ++ u32 ulIFLevelDVBT = IF_LEVEL_DVBT; ++ u32 ulPowerMeasurement = 1; ++ u32 ulLTEnable = 1; ++ u32 ulEnableFreeze = 0; ++ ++ state->m_Frequency = 0; ++ state->m_isMaster = true; ++ state->m_ID = 0; ++ state->m_LastPowerLevel = 0xFF; ++ state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07); ++ state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07); ++ state->m_bPowerMeasurement = (ulPowerMeasurement != 0); ++ state->m_bLTEnable = (ulLTEnable != 0); ++ state->m_bEnableFreeze = (ulEnableFreeze != 0); ++} ++ ++static int StartCalibration(struct tda_state *state) ++{ ++ int status = 0; ++ do { ++ state->Regs[POWER_2] &= ~0x02; /* RSSI CK = 31.25 kHz */ ++ CHK_ERROR(update_reg(state, POWER_2)); ++ ++ /* AGC1 Do Step = 2 */ ++ state->Regs[AGC1_2] = (state->Regs[AGC1_2] & ~0x60) | 0x40; ++ CHK_ERROR(update_reg(state, AGC1_2)); /* AGC */ ++ ++ /* AGC2 Do Step = 1 */ ++ state->Regs[RF_FILTER_3] = ++ (state->Regs[RF_FILTER_3] & ~0xC0) | 0x40; ++ CHK_ERROR(update_reg(state, RF_FILTER_3)); ++ ++ /* AGCs Assym Up Step = 3 // Datasheet sets all bits to 1! */ ++ state->Regs[AGCK_1] |= 0xC0; ++ CHK_ERROR(update_reg(state, AGCK_1)); ++ ++ /* AGCs Assym Do Step = 2 */ ++ state->Regs[AGC5_1] = (state->Regs[AGC5_1] & ~0x60) | 0x40; ++ CHK_ERROR(update_reg(state, AGC5_1)); ++ ++ state->Regs[IRQ_CLEAR] |= 0x80; /* Reset IRQ */ ++ CHK_ERROR(update_reg(state, IRQ_CLEAR)); ++ ++ state->Regs[MSM_1] = 0x3B; /* Set Calibration */ ++ state->Regs[MSM_2] = 0x01; /* Start MSM */ ++ CHK_ERROR(update_regs(state, MSM_1, MSM_2)); ++ state->Regs[MSM_2] = 0x00; ++ } while (0); ++ return status; ++} ++ ++static int FinishCalibration(struct tda_state *state) ++{ ++ int status = 0; ++ u8 RFCal_Log[12]; ++ ++ do { ++ u8 IRQ = 0; ++ int Timeout = 150; /* 1.5 s */ ++ while (true) { ++ CHK_ERROR(read_reg(state, IRQ_STATUS, &IRQ)); ++ if ((IRQ & 0x80) != 0) ++ break; ++ Timeout -= 1; ++ if (Timeout == 0) { ++ status = -1; ++ break; ++ } ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ state->Regs[FLO_MAX] = 0x0A; ++ CHK_ERROR(update_reg(state, FLO_MAX)); ++ ++ state->Regs[AGC1_1] &= ~0xC0; ++ if (state->m_bLTEnable) ++ state->Regs[AGC1_1] |= 0x80; /* LTEnable */ ++ ++ state->Regs[AGC1_1] |= (state->m_isMaster ? ++ MASTER_AGC1_6_15dB : ++ SLAVE_AGC1_6_15dB) << 6; ++ CHK_ERROR(update_reg(state, AGC1_1)); ++ ++ state->Regs[PSM_1] &= ~0xC0; ++ state->Regs[PSM_1] |= (state->m_isMaster ? ++ MASTER_PSM_AGC1 : SLAVE_PSM_AGC1) << 6; ++ CHK_ERROR(update_reg(state, PSM_1)); ++ ++ state->Regs[REFERENCE] |= 0x03; /* XTOUT = 3 */ ++ CHK_ERROR(update_reg(state, REFERENCE)); ++ ++ CHK_ERROR(read_regs(state, RFCAL_LOG_1, ++ RFCal_Log, sizeof(RFCal_Log))); ++ } while (0); ++ return status; ++} ++ ++static int PowerOn(struct tda_state *state) ++{ ++ state->Regs[POWER_STATE_2] &= ~0x0F; ++ update_reg(state, POWER_STATE_2); ++ /* Digital clock source = Sigma Delta */ ++ state->Regs[REFERENCE] |= 0x40; ++ update_reg(state, REFERENCE); ++ return 0; ++} ++ ++static int Standby(struct tda_state *state) ++{ ++ int status = 0; ++ ++ do { ++ /* Digital clock source = Quarz */ ++ state->Regs[REFERENCE] &= ~0x40; ++ CHK_ERROR(update_reg(state, REFERENCE)); ++ ++ state->Regs[POWER_STATE_2] &= ~0x0F; ++ state->Regs[POWER_STATE_2] |= state->m_isMaster ? 0x08 : 0x0E; ++ CHK_ERROR(update_reg(state, POWER_STATE_2)); ++ } while (0); ++ return status; ++} ++ ++static int attach_init(struct tda_state *state) ++{ ++ int stat = 0; ++ u8 Id[2]; ++ u8 PowerState = 0x00; ++ ++ state->m_Standard = HF_None; ++ ++ /* first read after cold reset sometimes fails on some cards, ++ try twice */ ++ stat = read_regs(state, ID_1, Id, sizeof(Id)); ++ stat = read_regs(state, ID_1, Id, sizeof(Id)); ++ if (stat < 0) ++ return -1; ++ ++ state->m_ID = ((Id[0] & 0x7F) << 8) | Id[1]; ++ state->m_isMaster = ((Id[0] & 0x80) != 0); ++ if (!state->m_isMaster) ++ state->m_bLTEnable = false; ++ ++ pr_info("tda18212dd: ChipID %04x %s\n", state->m_ID, ++ state->m_isMaster ? "master" : "slave"); ++ ++ if (state->m_ID != 18212) ++ return -1; ++ ++ stat = read_reg(state, POWER_STATE_1 , &PowerState); ++ if (stat < 0) ++ return stat; ++ ++ pr_info("tda18212dd: PowerState %02x\n", PowerState); ++ ++ if (state->m_isMaster) { ++ if (PowerState & 0x02) { ++ /* msleep for XTAL Calibration ++ (on a PC this should be long done) */ ++ u8 IRQStatus = 0; ++ int Timeout = 10; ++ ++ while (Timeout > 0) { ++ read_reg(state, IRQ_STATUS, &IRQStatus); ++ if (IRQStatus & 0x20) ++ break; ++ Timeout -= 1; ++ usleep_range(10000, 12000); ++ } ++ if ((IRQStatus & 0x20) == 0) ++ stat = -ETIMEDOUT; ++ } ++ } else { ++ write_reg(state, FLO_MAX, 0x00); ++ write_reg(state, CP_CURRENT, 0x68); ++ } ++ Read(state, state->Regs); ++ ++ PowerOn(state); ++ StartCalibration(state); ++ FinishCalibration(state); ++ Standby(state); ++ ++ { ++ u8 RFCal_Log[12]; ++ ++ read_regs(state, RFCAL_LOG_1, RFCal_Log, sizeof(RFCal_Log)); ++ pr_info("RFCal Log: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ RFCal_Log[0], RFCal_Log[1], ++ RFCal_Log[2], RFCal_Log[3], ++ RFCal_Log[4], RFCal_Log[5], ++ RFCal_Log[6], RFCal_Log[7], ++ RFCal_Log[8], RFCal_Log[9], ++ RFCal_Log[10], RFCal_Log[11]); ++ } ++ return stat; ++} ++ ++static int PowerMeasurement(struct tda_state *state, u8 *pPowerLevel) ++{ ++ int status = 0; ++ ++ do { ++ u8 IRQ = 0; ++ int Timeout = 70; /* 700 ms */ ++ ++ state->Regs[IRQ_CLEAR] |= 0x80; /* Reset IRQ */ ++ CHK_ERROR(update_reg(state, IRQ_CLEAR)); ++ ++ state->Regs[MSM_1] = 0x80; /* power measurement */ ++ state->Regs[MSM_2] = 0x01; /* Start MSM */ ++ CHK_ERROR(update_regs(state, MSM_1, MSM_2)); ++ state->Regs[MSM_2] = 0x00; ++ ++ while (true) { ++ CHK_ERROR(read_reg(state, IRQ_STATUS, &IRQ)); ++ if ((IRQ & 0x80) != 0) ++ break; ++ Timeout -= 1; ++ if (Timeout == 0) { ++ status = -1; ++ break; ++ } ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ CHK_ERROR(read_reg1(state, INPUT_POWER_LEVEL)); ++ *pPowerLevel = state->Regs[INPUT_POWER_LEVEL] & 0x7F; ++ ++ if (*pPowerLevel > 110) ++ *pPowerLevel = 110; ++ } while (0); ++ /* pr_info("PL %d\n", *pPowerLevel); */ ++ return status; ++} ++ ++static int SetFrequency(struct tda_state *state, u32 Frequency, ++ enum HF_Standard Standard) ++{ ++ int status = 0; ++ struct SStandardParams *StandardParams; ++ u32 f = Frequency / 1000; ++ u8 IRQ = 0; ++ int Timeout = 25; /* 250 ms */ ++ u32 fRatio = Frequency / 16000000; ++ u32 fDelta = Frequency - fRatio * 16000000; ++ ++ if (Standard < HF_DVBT_6MHZ || Standard > HF_DVBC_8MHZ) ++ return -EINVAL; ++ StandardParams = &m_StandardTable[Standard - HF_DVBT_6MHZ]; ++ ++ if (StandardParams->m_IFFrequency == 0) ++ return -EINVAL; ++ state->m_Standard = HF_None; ++ state->m_Frequency = 0; ++ ++ do { ++ /* IF Level */ ++ state->Regs[IF_AGC] = (Standard >= HF_DVBC_6MHZ) ? ++ state->m_IFLevelDVBC : state->m_IFLevelDVBT; ++ CHK_ERROR(update_reg(state, IF_AGC)); ++ ++ /* Standard setup */ ++ state->Regs[IF_1] = StandardParams->m_IF_1; ++ CHK_ERROR(update_reg(state, IF_1)); ++ ++ state->Regs[IR_MIXER_2] = (state->Regs[IR_MIXER_2] & ~0x03) | ++ StandardParams->m_IR_MIXER_2; ++ CHK_ERROR(update_reg(state, IR_MIXER_2)); ++ ++ state->Regs[AGC1_1] = (state->Regs[AGC1_1] & ~0x0F) | ++ StandardParams->m_AGC1_1; ++ CHK_ERROR(update_reg(state, AGC1_1)); ++ ++ state->Regs[AGC2_1] = (state->Regs[AGC2_1] & ~0x0F) | ++ StandardParams->m_AGC2_1; ++ CHK_ERROR(update_reg(state, AGC2_1)); ++ ++ state->Regs[RF_AGC_1] &= ~0xEF; ++ if (Frequency < 291000000) ++ state->Regs[RF_AGC_1] |= StandardParams->m_RF_AGC_1_Low; ++ else ++ state->Regs[RF_AGC_1] |= ++ StandardParams->m_RF_AGC_1_High; ++ CHK_ERROR(update_reg(state, RF_AGC_1)); ++ ++ state->Regs[IR_MIXER_1] = ++ (state->Regs[IR_MIXER_1] & ~0x0F) | ++ StandardParams->m_IR_MIXER_1; ++ CHK_ERROR(update_reg(state, IR_MIXER_1)); ++ ++ state->Regs[AGC5_1] = (state->Regs[AGC5_1] & ~0x1F) | ++ StandardParams->m_AGC5_1; ++ CHK_ERROR(update_reg(state, AGC5_1)); ++ ++ state->Regs[AGCK_1] = (state->Regs[AGCK_1] & ~0x0F) | ++ StandardParams->m_AGCK_1; ++ CHK_ERROR(update_reg(state, AGCK_1)); ++ ++ state->Regs[PSM_1] = (state->Regs[PSM_1] & ~0x20) | ++ StandardParams->m_PSM_1; ++ CHK_ERROR(update_reg(state, PSM_1)); ++ ++ state->Regs[IF_FREQUENCY_1] = (StandardParams->m_IFFrequency / ++ 50000); ++ CHK_ERROR(update_reg(state, IF_FREQUENCY_1)); ++ ++ if (state->m_isMaster && StandardParams->m_LTO_STO_immune) { ++ u8 tmp; ++ u8 RF_Filter_Gain; ++ ++ CHK_ERROR(read_reg(state, RF_AGC_GAIN_1, &tmp)); ++ RF_Filter_Gain = (tmp & 0x30) >> 4; ++ ++ state->Regs[RF_FILTER_1] = ++ (state->Regs[RF_FILTER_1] & ~0x0C) | ++ (RF_Filter_Gain << 2); ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ ++ state->Regs[RF_FILTER_1] |= 0x10; /* Force */ ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ ++ while (RF_Filter_Gain != 0) { ++ RF_Filter_Gain -= 1; ++ state->Regs[RF_FILTER_1] = ++ (state->Regs[RF_FILTER_1] & ~0x0C) | ++ (RF_Filter_Gain << 2); ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ state->Regs[RF_AGC_1] |= 0x08; ++ CHK_ERROR(update_reg(state, RF_AGC_1)); ++ } ++ ++ state->Regs[IRQ_CLEAR] |= 0x80; /* Reset IRQ */ ++ CHK_ERROR(update_reg(state, IRQ_CLEAR)); ++ ++ CHK_ERROR(PowerOn(state)); ++ ++ state->Regs[RF_FREQUENCY_1] = ((f >> 16) & 0xFF); ++ state->Regs[RF_FREQUENCY_2] = ((f >> 8) & 0xFF); ++ state->Regs[RF_FREQUENCY_3] = (f & 0xFF); ++ CHK_ERROR(update_regs(state, RF_FREQUENCY_1, RF_FREQUENCY_3)); ++ ++ state->Regs[MSM_1] = 0x41; /* Tune */ ++ state->Regs[MSM_2] = 0x01; /* Start MSM */ ++ CHK_ERROR(update_regs(state, MSM_1, MSM_2)); ++ state->Regs[MSM_2] = 0x00; ++ ++ while (true) { ++ CHK_ERROR(read_reg(state, IRQ_STATUS, &IRQ)); ++ if ((IRQ & 0x80) != 0) ++ break; ++ Timeout -= 1; ++ if (Timeout == 0) { ++ status = -1; ++ break; ++ } ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ if (state->m_isMaster && StandardParams->m_LTO_STO_immune) { ++ state->Regs[RF_AGC_1] &= ~0x08; ++ CHK_ERROR(update_reg(state, RF_AGC_1)); ++ ++ msleep(50); ++ ++ state->Regs[RF_FILTER_1] &= ~0x10; /* remove force */ ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ } ++ ++ /* Spur reduction */ ++ ++ if (Frequency < 72000000) ++ state->Regs[REFERENCE] |= 0x40; /* Set digital clock */ ++ else if (Frequency < 104000000) ++ state->Regs[REFERENCE] &= ~0x40; /*Clear digital clock*/ ++ else if (Frequency < 120000000) ++ state->Regs[REFERENCE] |= 0x40; /* Set digital clock */ ++ else { ++ if (fDelta <= 8000000) { ++ /* Clear or set digital clock */ ++ if (fRatio & 1) ++ state->Regs[REFERENCE] &= ~0x40; ++ else ++ state->Regs[REFERENCE] |= 0x40; ++ } else { ++ /* Set or clear digital clock */ ++ if (fRatio & 1) ++ state->Regs[REFERENCE] |= 0x40; ++ else ++ state->Regs[REFERENCE] &= ~0x40; ++ } ++ ++ } ++ CHK_ERROR(update_reg(state, REFERENCE)); ++ ++ if (StandardParams->m_AGC1_Freeze && state->m_bEnableFreeze) { ++ u8 tmp; ++ int AGC1GainMin = 0; ++ int nSteps = 10; ++ int Step = 0; ++ ++ CHK_ERROR(read_reg(state, AGC1_2, &tmp)); ++ if ((tmp & 0x80) == 0) { ++ state->Regs[AGC1_2] |= 0x80; /* Loop off */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ state->Regs[AGC1_2] |= 0x10; /* Force gain */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } ++ /* Adapt */ ++ if (state->Regs[AGC1_1] & 0x40) { /* AGC1_6_15dB set */ ++ AGC1GainMin = 6; ++ nSteps = 4; ++ } ++ while (Step < nSteps) { ++ int Down = 0; ++ int Up = 0, i; ++ u8 AGC1_Gain; ++ ++ Step = Step + 1; ++ ++ for (i = 0; i < 40; i += 1) { ++ CHK_ERROR(read_reg(state, AGC_DET_OUT, ++ &tmp)); ++ Up += (tmp & 0x02) ? 1 : -4; ++ Down += (tmp & 0x01) ? 14 : -1; ++ usleep_range(1000, 2000); ++ } ++ CHK_ERROR(status); ++ AGC1_Gain = (state->Regs[AGC1_2] & 0x0F); ++ if (Up >= 15 && AGC1_Gain != 9) { ++ state->Regs[AGC1_2] = ++ (state->Regs[AGC1_2] & ~0x0F) | ++ (AGC1_Gain + 1); ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } else if (Down >= 10 && ++ AGC1_Gain != AGC1GainMin) { ++ state->Regs[AGC1_2] = ++ (state->Regs[AGC1_2] & ~0x0F) | ++ (AGC1_Gain - 1); ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } else ++ Step = nSteps; ++ } ++ } else { ++ state->Regs[AGC1_2] &= ~0x10; /* unforce gain */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ state->Regs[AGC1_2] &= ~0x80; /* Loop on */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } ++ ++ state->m_Standard = Standard; ++ state->m_Frequency = Frequency; ++ ++ if (state->m_bPowerMeasurement) ++ PowerMeasurement(state, &state->m_LastPowerLevel); ++ } while (0); ++ ++ return status; ++} ++ ++static int sleep(struct dvb_frontend *fe) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ Standby(state); ++ return 0; ++} ++ ++static int init(struct dvb_frontend *fe) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ return 0; ++} ++ ++static int release(struct dvb_frontend *fe) ++{ ++ kfree(fe->tuner_priv); ++ fe->tuner_priv = NULL; ++ return 0; ++} ++ ++#ifndef USE_API3 ++static int set_params(struct dvb_frontend *fe) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ int status = 0; ++ int Standard; ++ u32 bw; ++ ++ bw = (p->bandwidth_hz + 999999) / 1000000; ++ state->m_Frequency = p->frequency; ++ /*pr_info("tuner bw=%u freq=%u\n", bw, state->m_Frequency);*/ ++ if (p->delivery_system == SYS_DVBT || ++ p->delivery_system == SYS_DVBT2 || ++ p->delivery_system == SYS_ISDBT) { ++ switch (bw) { ++ case 6: ++ Standard = HF_DVBT_6MHZ; ++ break; ++ case 7: ++ Standard = HF_DVBT_7MHZ; ++ break; ++ default: ++ case 8: ++ Standard = HF_DVBT_8MHZ; ++ break; ++ } ++ } else if (p->delivery_system == SYS_DVBC_ANNEX_A) { ++ switch (bw) { ++ case 6: ++ Standard = HF_DVBC_6MHZ; ++ break; ++ case 7: ++ Standard = HF_DVBC_7MHZ; ++ break; ++ default: ++ case 8: ++ Standard = HF_DVBC_8MHZ; ++ break; ++ } ++ } else ++ return -EINVAL; ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ SetFrequency(state, state->m_Frequency, Standard); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ ++ return status; ++} ++#else ++static int set_params(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *params) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ int status = 0; ++ int Standard; ++ ++ state->m_Frequency = params->frequency; ++ ++ if (fe->ops.info.type == FE_OFDM) ++ switch (params->u.ofdm.bandwidth) { ++ case BANDWIDTH_6_MHZ: ++ Standard = HF_DVBT_6MHZ; ++ break; ++ case BANDWIDTH_7_MHZ: ++ Standard = HF_DVBT_7MHZ; ++ break; ++ default: ++ case BANDWIDTH_8_MHZ: ++ Standard = HF_DVBT_8MHZ; ++ break; ++ } ++ else if (fe->ops.info.type == FE_QAM) { ++ Standard = HF_DVBC_8MHZ; ++ } else ++ return -EINVAL; ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ SetFrequency(state, state->m_Frequency, Standard); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ ++ return status; ++} ++#endif ++ ++static int get_frequency(struct dvb_frontend *fe, u32 *frequency) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ *frequency = state->IF; ++ return 0; ++} ++ ++static int get_rf_strength(struct dvb_frontend *fe, u16 *st) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ *st = state->m_LastPowerLevel; ++ return 0; ++} ++ ++static int get_if(struct dvb_frontend *fe, u32 *frequency) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ state->IF = 0; ++ if (state->m_Standard < HF_DVBT_6MHZ || ++ state->m_Standard > HF_DVBC_8MHZ) ++ return 0; ++ state->IF = m_StandardTable[state->m_Standard - ++ HF_DVBT_6MHZ].m_IFFrequency; ++ *frequency = state->IF; ++ return 0; ++} ++ ++static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ /* *bandwidth = priv->bandwidth; */ ++ return 0; ++} ++ ++ ++static struct dvb_tuner_ops tuner_ops = { ++ .info = { ++ .name = "NXP TDA18212", ++ .frequency_min = 47125000, ++ .frequency_max = 865000000, ++ .frequency_step = 62500 ++ }, ++ .init = init, ++ .sleep = sleep, ++ .set_params = set_params, ++ .release = release, ++ .get_frequency = get_frequency, ++ .get_if_frequency = get_if, ++ .get_bandwidth = get_bandwidth, ++ .get_rf_strength = get_rf_strength, ++}; ++ ++struct dvb_frontend *tda18212dd_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr) ++{ ++ struct tda_state *state; ++ int stat; ++ ++ state = kzalloc(sizeof(struct tda_state), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ state->adr = adr; ++ state->i2c = i2c; ++ memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops)); ++ init_state(state); ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ stat = attach_init(state); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ if (stat < 0) { ++ kfree(state); ++ return 0; ++ } ++ fe->tuner_priv = state; ++ return fe; ++} ++EXPORT_SYMBOL_GPL(tda18212dd_attach); ++ ++MODULE_DESCRIPTION("TDA18212 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * Local variables: ++ * c-basic-offset: 8 ++ * End: ++ */ +diff --git a/drivers/media/dvb-frontends/tda18212dd.h b/drivers/media/dvb-frontends/tda18212dd.h +new file mode 100644 +index 0000000..687fab4a +--- /dev/null ++++ b/drivers/media/dvb-frontends/tda18212dd.h +@@ -0,0 +1,5 @@ ++#ifndef _TDA18212DD_H_ ++#define _TDA18212DD_H_ ++struct dvb_frontend *tda18212dd_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr); ++#endif +diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c +index de0a1c1..ad7c72e 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd.c ++++ b/drivers/media/dvb-frontends/tda18271c2dd.c +@@ -32,10 +32,6 @@ + #include + + #include "dvb_frontend.h" +-#include "tda18271c2dd.h" +- +-/* Max transfer size done by I2C transfer functions */ +-#define MAX_XFER_SIZE 64 + + struct SStandardParam { + s32 m_IFFrequency; +@@ -142,18 +138,11 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) + static int WriteRegs(struct tda_state *state, + u8 SubAddr, u8 *Regs, u16 nRegs) + { +- u8 data[MAX_XFER_SIZE]; +- +- if (1 + nRegs > sizeof(data)) { +- printk(KERN_WARNING +- "%s: i2c wr: len=%d is too big!\n", +- KBUILD_MODNAME, nRegs); +- return -EINVAL; +- } ++ u8 data[nRegs+1]; + + data[0] = SubAddr; + memcpy(data + 1, Regs, nRegs); +- return i2c_write(state->i2c, state->adr, data, nRegs + 1); ++ return i2c_write(state->i2c, state->adr, data, nRegs+1); + } + + static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg) +@@ -1030,7 +1019,7 @@ static int ChannelConfiguration(struct tda_state *state, + state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; + + if ((Standard == HF_FM_Radio) && state->m_bFMInput) +- state->m_Regs[EP4] |= 0x80; ++ state->m_Regs[EP4] |= 80; + + state->m_Regs[MPD] &= ~0x80; + if (Standard > HF_AnalogMax) +diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h +index 7ebd8ea..31f7926 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd.h ++++ b/drivers/media/dvb-frontends/tda18271c2dd.h +@@ -1,9 +1,7 @@ + #ifndef _TDA18271C2DD_H_ + #define _TDA18271C2DD_H_ +- +-#include +- +-#if IS_REACHABLE(CONFIG_DVB_TDA18271C2DD) ++#if defined(CONFIG_DVB_TDA18271C2DD) || (defined(CONFIG_DVB_TDA18271C2DD_MODULE) \ ++ && defined(MODULE)) + struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 adr); + #else +diff --git a/drivers/media/dvb-frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h +index f3bca5c..b87661b 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd_maps.h ++++ b/drivers/media/dvb-frontends/tda18271c2dd_maps.h +@@ -5,7 +5,7 @@ enum HF_S { + HF_DVBC_8MHZ, HF_DVBC + }; + +-static struct SStandardParam m_StandardTable[] = { ++struct SStandardParam m_StandardTable[] = { + { 0, 0, 0x00, 0x00 }, /* HF_None */ + { 6000000, 7000000, 0x1D, 0x2C }, /* HF_B, */ + { 6900000, 8000000, 0x1E, 0x2C }, /* HF_DK, */ +@@ -27,7 +27,7 @@ static struct SStandardParam m_StandardTable[] = { + { 0, 0, 0x00, 0x00 }, /* HF_DVBC (Unused) */ + }; + +-static struct SMap m_BP_Filter_Map[] = { ++struct SMap m_BP_Filter_Map[] = { + { 62000000, 0x00 }, + { 84000000, 0x01 }, + { 100000000, 0x02 }, +@@ -799,14 +799,14 @@ static struct SRFBandMap m_RF_Band_Map[7] = { + { 865000000, 489500000, 697500000, 842000000}, + }; + +-static u8 m_Thermometer_Map_1[16] = { ++u8 m_Thermometer_Map_1[16] = { + 60, 62, 66, 64, + 74, 72, 68, 70, + 90, 88, 84, 86, + 76, 78, 82, 80, + }; + +-static u8 m_Thermometer_Map_2[16] = { ++u8 m_Thermometer_Map_2[16] = { + 92, 94, 98, 96, + 106, 104, 100, 102, + 122, 120, 116, 118, +diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig +index 44e5dc1..d283008 100644 +--- a/drivers/media/pci/ddbridge/Kconfig ++++ b/drivers/media/pci/ddbridge/Kconfig +@@ -1,18 +1,23 @@ + config DVB_DDBRIDGE + tristate "Digital Devices bridge support" + depends on DVB_CORE && PCI && I2C ++ select DVB_CXD2099 + select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT + select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT + ---help--- + Support for cards with the Digital Devices PCI express bridge: + - Octopus PCIe Bridge + - Octopus mini PCIe Bridge + - Octopus LE +- - DuoFlex S2 Octopus +- - DuoFlex CT Octopus +- - cineS2(v6) ++ - DuoFlex S2 ++ - DuoFlex CT ++ - cineS2(v6.x) ++ - cineCT(v6.x, v7) + + Say Y if you own such a card and want to use it. +diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile +index 7446c8b..2610161 100644 +--- a/drivers/media/pci/ddbridge/Makefile ++++ b/drivers/media/pci/ddbridge/Makefile +@@ -2,8 +2,6 @@ + # Makefile for the ddbridge device driver + # + +-ddbridge-objs := ddbridge-core.o +- + obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o + + ccflags-y += -Idrivers/media/dvb-core/ +diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c +index 9e3492e..c2fc010 100644 +--- a/drivers/media/pci/ddbridge/ddbridge-core.c ++++ b/drivers/media/pci/ddbridge/ddbridge-core.c +@@ -1,7 +1,8 @@ + /* +- * ddbridge.c: Digital Devices PCIe bridge driver ++ * ddbridge-core.c: Digital Devices bridge core functions + * +- * Copyright (C) 2010-2011 Digital Devices GmbH ++ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Ralph Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -21,268 +22,245 @@ + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "ddbridge.h" +- +-#include "ddbridge-regs.h" +- +-#include "tda18271c2dd.h" +-#include "stv6110x.h" +-#include "stv090x.h" +-#include "lnbh24.h" +-#include "drxk.h" ++DEFINE_MUTEX(redirect_lock); ++ ++static int ci_bitrate = 72000; ++module_param(ci_bitrate, int, 0444); ++MODULE_PARM_DESC(ci_bitrate, " Bitrate for output to CI."); ++ ++static int ts_loop = -1; ++module_param(ts_loop, int, 0444); ++MODULE_PARM_DESC(ts_loop, "TS in/out test loop on port ts_loop"); ++ ++static int vlan; ++module_param(vlan, int, 0444); ++MODULE_PARM_DESC(vlan, "VLAN and QoS IDs enabled"); ++ ++static int tt; ++module_param(tt, int, 0444); ++MODULE_PARM_DESC(tt, ""); ++ ++#define DDB_MAX_ADAPTER 32 ++static struct ddb *ddbs[DDB_MAX_ADAPTER]; + + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +-/* MSI had problems with lost interrupts, fixed but needs testing */ +-#undef CONFIG_PCI_MSI ++#include "ddbridge-mod.c" ++#include "ddbridge-i2c.c" ++#include "ddbridge-ns.c" + +-/******************************************************************************/ + +-static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) ++static void ddb_set_dma_table(struct ddb *dev, struct ddb_dma *dma) + { +- struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, +- .buf = val, .len = 1 } }; +- return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; +-} ++ u32 i, base; ++ u64 mem; + +-static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) +-{ +- struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, +- .buf = ®, .len = 1 }, +- {.addr = adr, .flags = I2C_M_RD, +- .buf = val, .len = 1 } }; +- return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++ if (!dma) ++ return; ++ base = DMA_BASE_ADDRESS_TABLE + dma->nr * 0x100; ++ for (i = 0; i < dma->num; i++) { ++ mem = dma->pbuf[i]; ++ ddbwritel(dev, mem & 0xffffffff, base + i * 8); ++ ddbwritel(dev, mem >> 32, base + i * 8 + 4); ++ } ++ dma->bufreg = (dma->div << 16) | ++ ((dma->num & 0x1f) << 11) | ++ ((dma->size >> 7) & 0x7ff); + } + +-static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, +- u16 reg, u8 *val) ++static void ddb_set_dma_tables(struct ddb *dev) + { +- u8 msg[2] = {reg>>8, reg&0xff}; +- struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, +- .buf = msg, .len = 2}, +- {.addr = adr, .flags = I2C_M_RD, +- .buf = val, .len = 1} }; +- return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++ u32 i; ++ ++ for (i = 0; i < dev->info->port_num * 2; i++) ++ ddb_set_dma_table(dev, dev->input[i].dma); ++ for (i = 0; i < dev->info->port_num; i++) ++ ddb_set_dma_table(dev, dev->output[i].dma); + } + +-static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void ddb_redirect_dma(struct ddb *dev, ++ struct ddb_dma *sdma, ++ struct ddb_dma *ddma) + { +- struct ddb *dev = i2c->dev; +- int stat; +- u32 val; ++ u32 i, base; ++ u64 mem; + +- i2c->done = 0; +- ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); +- stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); +- if (stat <= 0) { +- printk(KERN_ERR "I2C timeout\n"); +- { /* MSI debugging*/ +- u32 istat = ddbreadl(INTERRUPT_STATUS); +- printk(KERN_ERR "IRS %08x\n", istat); +- ddbwritel(istat, INTERRUPT_ACK); +- } +- return -EIO; ++ sdma->bufreg = ddma->bufreg; ++ base = DMA_BASE_ADDRESS_TABLE + sdma->nr * 0x100; ++ for (i = 0; i < ddma->num; i++) { ++ mem = ddma->pbuf[i]; ++ ddbwritel(dev, mem & 0xffffffff, base + i * 8); ++ ddbwritel(dev, mem >> 32, base + i * 8 + 4); + } +- val = ddbreadl(i2c->regs+I2C_COMMAND); +- if (val & 0x70000) +- return -EIO; +- return 0; + } + +-static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, +- struct i2c_msg msg[], int num) ++static int ddb_unredirect(struct ddb_port *port) + { +- struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); +- struct ddb *dev = i2c->dev; +- u8 addr = 0; +- +- if (num) +- addr = msg[0].addr; ++ struct ddb_input *oredi, *iredi = 0; ++ struct ddb_output *iredo = 0; + +- if (num == 2 && msg[1].flags & I2C_M_RD && +- !(msg[0].flags & I2C_M_RD)) { +- memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, +- msg[0].buf, msg[0].len); +- ddbwritel(msg[0].len|(msg[1].len << 16), +- i2c->regs+I2C_TASKLENGTH); +- if (!ddb_i2c_cmd(i2c, addr, 1)) { +- memcpy_fromio(msg[1].buf, +- dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, +- msg[1].len); +- return num; +- } +- } +- +- if (num == 1 && !(msg[0].flags & I2C_M_RD)) { +- ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); +- ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); +- if (!ddb_i2c_cmd(i2c, addr, 2)) +- return num; ++ /*pr_info("unredirect %d.%d\n", port->dev->nr, port->nr);*/ ++ mutex_lock(&redirect_lock); ++ if (port->output->dma->running) { ++ mutex_unlock(&redirect_lock); ++ return -EBUSY; + } +- if (num == 1 && (msg[0].flags & I2C_M_RD)) { +- ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); +- if (!ddb_i2c_cmd(i2c, addr, 3)) { +- ddbcpyfrom(msg[0].buf, +- I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); +- return num; ++ oredi = port->output->redi; ++ if (!oredi) ++ goto done; ++ if (port->input[0]) { ++ iredi = port->input[0]->redi; ++ iredo = port->input[0]->redo; ++ ++ if (iredo) { ++ iredo->port->output->redi = oredi; ++ if (iredo->port->input[0]) { ++ iredo->port->input[0]->redi = iredi; ++ ddb_redirect_dma(oredi->port->dev, ++ oredi->dma, iredo->dma); ++ } ++ port->input[0]->redo = 0; ++ ddb_set_dma_table(port->dev, port->input[0]->dma); + } ++ oredi->redi = iredi; ++ port->input[0]->redi = 0; + } +- return -EIO; +-} ++ oredi->redo = 0; ++ port->output->redi = 0; + ++ ddb_set_dma_table(oredi->port->dev, oredi->dma); ++done: ++ mutex_unlock(&redirect_lock); ++ return 0; ++} + +-static u32 ddb_i2c_functionality(struct i2c_adapter *adap) ++static int ddb_redirect(u32 i, u32 p) + { +- return I2C_FUNC_SMBUS_EMUL; +-} ++ struct ddb *idev = ddbs[(i >> 4) & 0x1f]; ++ struct ddb_input *input, *input2; ++ struct ddb *pdev = ddbs[(p >> 4) & 0x1f]; ++ struct ddb_port *port; + +-static struct i2c_algorithm ddb_i2c_algo = { +- .master_xfer = ddb_i2c_master_xfer, +- .functionality = ddb_i2c_functionality, +-}; ++ if (!idev->has_dma || !pdev->has_dma) ++ return -EINVAL; ++ if (!idev || !pdev) ++ return -EINVAL; + +-static void ddb_i2c_release(struct ddb *dev) +-{ +- int i; +- struct ddb_i2c *i2c; +- struct i2c_adapter *adap; ++ port = &pdev->port[p & 0x0f]; ++ if (!port->output) ++ return -EINVAL; ++ if (ddb_unredirect(port)) ++ return -EBUSY; + +- for (i = 0; i < dev->info->port_num; i++) { +- i2c = &dev->i2c[i]; +- adap = &i2c->adap; +- i2c_del_adapter(adap); +- } +-} ++ if (i == 8) ++ return 0; + +-static int ddb_i2c_init(struct ddb *dev) +-{ +- int i, j, stat = 0; +- struct ddb_i2c *i2c; +- struct i2c_adapter *adap; ++ input = &idev->input[i & 7]; ++ if (!input) ++ return -EINVAL; + +- for (i = 0; i < dev->info->port_num; i++) { +- i2c = &dev->i2c[i]; +- i2c->dev = dev; +- i2c->nr = i; +- i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); +- i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); +- i2c->regs = 0x80 + i * 0x20; +- ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); +- ddbwritel((i2c->rbuf << 16) | i2c->wbuf, +- i2c->regs + I2C_TASKADDRESS); +- init_waitqueue_head(&i2c->wq); +- +- adap = &i2c->adap; +- i2c_set_adapdata(adap, i2c); +-#ifdef I2C_ADAP_CLASS_TV_DIGITAL +- adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; +-#else +-#ifdef I2C_CLASS_TV_ANALOG +- adap->class = I2C_CLASS_TV_ANALOG; +-#endif +-#endif +- strcpy(adap->name, "ddbridge"); +- adap->algo = &ddb_i2c_algo; +- adap->algo_data = (void *)i2c; +- adap->dev.parent = &dev->pdev->dev; +- stat = i2c_add_adapter(adap); +- if (stat) +- break; ++ mutex_lock(&redirect_lock); ++ if (port->output->dma->running || input->dma->running) { ++ mutex_unlock(&redirect_lock); ++ return -EBUSY; + } +- if (stat) +- for (j = 0; j < i; j++) { +- i2c = &dev->i2c[j]; +- adap = &i2c->adap; +- i2c_del_adapter(adap); +- } +- return stat; +-} ++ input2 = port->input[0]; ++ if (input2) { ++ if (input->redi) { ++ input2->redi = input->redi; ++ input->redi = 0; ++ } else ++ input2->redi = input; ++ } ++ input->redo = port->output; ++ port->output->redi = input; + ++ ddb_redirect_dma(input->port->dev, input->dma, port->output->dma); ++ mutex_unlock(&redirect_lock); ++ return 0; ++} + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + +-#if 0 +-static void set_table(struct ddb *dev, u32 off, +- dma_addr_t *pbuf, u32 num) ++#ifdef DDB_ALT_DMA ++static void dma_free(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { +- u32 i, base; +- u64 mem; ++ int i; + +- base = DMA_BASE_ADDRESS_TABLE + off; +- for (i = 0; i < num; i++) { +- mem = pbuf[i]; +- ddbwritel(mem & 0xffffffff, base + i * 8); +- ddbwritel(mem >> 32, base + i * 8 + 4); ++ if (!dma) ++ return; ++ for (i = 0; i < dma->num; i++) { ++ if (dma->vbuf[i]) { ++ dma_unmap_single(&pdev->dev, dma->pbuf[i], ++ dma->size, ++ dir ? DMA_TO_DEVICE : ++ DMA_FROM_DEVICE); ++ kfree(dma->vbuf[i]); ++ dma->vbuf[i] = 0; ++ } + } + } +-#endif + +-static void ddb_address_table(struct ddb *dev) ++static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { +- u32 i, j, base; +- u64 mem; +- dma_addr_t *pbuf; ++ int i; + +- for (i = 0; i < dev->info->port_num * 2; i++) { +- base = DMA_BASE_ADDRESS_TABLE + i * 0x100; +- pbuf = dev->input[i].pbuf; +- for (j = 0; j < dev->input[i].dma_buf_num; j++) { +- mem = pbuf[j]; +- ddbwritel(mem & 0xffffffff, base + j * 8); +- ddbwritel(mem >> 32, base + j * 8 + 4); +- } +- } +- for (i = 0; i < dev->info->port_num; i++) { +- base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100; +- pbuf = dev->output[i].pbuf; +- for (j = 0; j < dev->output[i].dma_buf_num; j++) { +- mem = pbuf[j]; +- ddbwritel(mem & 0xffffffff, base + j * 8); +- ddbwritel(mem >> 32, base + j * 8 + 4); ++ if (!dma) ++ return 0; ++ for (i = 0; i < dma->num; i++) { ++ dma->vbuf[i] = kmalloc(dma->size, __GFP_REPEAT); ++ if (!dma->vbuf[i]) ++ return -ENOMEM; ++ dma->pbuf[i] = dma_map_single(&pdev->dev, dma->vbuf[i], ++ dma->size, ++ dir ? DMA_TO_DEVICE : ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma->pbuf[i])) { ++ kfree(dma->vbuf[i]); ++ return -ENOMEM; + } + } ++ return 0; + } ++#else + +-static void io_free(struct pci_dev *pdev, u8 **vbuf, +- dma_addr_t *pbuf, u32 size, int num) ++static void dma_free(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { + int i; + +- for (i = 0; i < num; i++) { +- if (vbuf[i]) { +- pci_free_consistent(pdev, size, vbuf[i], pbuf[i]); +- vbuf[i] = NULL; ++ if (!dma) ++ return; ++ for (i = 0; i < dma->num; i++) { ++ if (dma->vbuf[i]) { ++ pci_free_consistent(pdev, dma->size, ++ dma->vbuf[i], dma->pbuf[i]); ++ dma->vbuf[i] = 0; + } + } + } + +-static int io_alloc(struct pci_dev *pdev, u8 **vbuf, +- dma_addr_t *pbuf, u32 size, int num) ++static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { + int i; + +- for (i = 0; i < num; i++) { +- vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]); +- if (!vbuf[i]) ++ if (!dma) ++ return 0; ++ for (i = 0; i < dma->num; i++) { ++ dma->vbuf[i] = pci_alloc_consistent(pdev, dma->size, ++ &dma->pbuf[i]); ++ if (!dma->vbuf[i]) + return -ENOMEM; + } + return 0; + } ++#endif + + static int ddb_buffers_alloc(struct ddb *dev) + { +@@ -293,34 +271,24 @@ static int ddb_buffers_alloc(struct ddb *dev) + port = &dev->port[i]; + switch (port->class) { + case DDB_PORT_TUNER: +- if (io_alloc(dev->pdev, port->input[0]->vbuf, +- port->input[0]->pbuf, +- port->input[0]->dma_buf_size, +- port->input[0]->dma_buf_num) < 0) ++ if (dma_alloc(dev->pdev, port->input[0]->dma, 0) < 0) + return -1; +- if (io_alloc(dev->pdev, port->input[1]->vbuf, +- port->input[1]->pbuf, +- port->input[1]->dma_buf_size, +- port->input[1]->dma_buf_num) < 0) ++ if (dma_alloc(dev->pdev, port->input[1]->dma, 0) < 0) + return -1; + break; + case DDB_PORT_CI: +- if (io_alloc(dev->pdev, port->input[0]->vbuf, +- port->input[0]->pbuf, +- port->input[0]->dma_buf_size, +- port->input[0]->dma_buf_num) < 0) ++ case DDB_PORT_LOOP: ++ if (dma_alloc(dev->pdev, port->input[0]->dma, 0) < 0) + return -1; +- if (io_alloc(dev->pdev, port->output->vbuf, +- port->output->pbuf, +- port->output->dma_buf_size, +- port->output->dma_buf_num) < 0) ++ case DDB_PORT_MOD: ++ if (dma_alloc(dev->pdev, port->output->dma, 1) < 0) + return -1; + break; + default: + break; + } + } +- ddb_address_table(dev); ++ ddb_set_dma_tables(dev); + return 0; + } + +@@ -331,287 +299,839 @@ static void ddb_buffers_free(struct ddb *dev) + + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; +- io_free(dev->pdev, port->input[0]->vbuf, +- port->input[0]->pbuf, +- port->input[0]->dma_buf_size, +- port->input[0]->dma_buf_num); +- io_free(dev->pdev, port->input[1]->vbuf, +- port->input[1]->pbuf, +- port->input[1]->dma_buf_size, +- port->input[1]->dma_buf_num); +- io_free(dev->pdev, port->output->vbuf, +- port->output->pbuf, +- port->output->dma_buf_size, +- port->output->dma_buf_num); ++ ++ if (port->input[0]) ++ dma_free(dev->pdev, port->input[0]->dma, 0); ++ if (port->input[1]) ++ dma_free(dev->pdev, port->input[1]->dma, 0); ++ if (port->output) ++ dma_free(dev->pdev, port->output->dma, 1); + } + } + +-static void ddb_input_start(struct ddb_input *input) ++static void ddb_output_start(struct ddb_output *output) + { +- struct ddb *dev = input->port->dev; ++ struct ddb *dev = output->port->dev; ++ u32 con2; + +- spin_lock_irq(&input->lock); +- input->cbuf = 0; +- input->coff = 0; ++ con2 = ((output->port->obr << 13) + 71999) / 72000; ++ con2 = (con2 << 16) | output->port->gap; + +- /* reset */ +- ddbwritel(0, TS_INPUT_CONTROL(input->nr)); +- ddbwritel(2, TS_INPUT_CONTROL(input->nr)); +- ddbwritel(0, TS_INPUT_CONTROL(input->nr)); ++ if (output->dma) { ++ spin_lock_irq(&output->dma->lock); ++ output->dma->cbuf = 0; ++ output->dma->coff = 0; ++ output->dma->stat = 0; ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma->nr)); ++ } ++ if (output->port->class == DDB_PORT_MOD) ++ ddbridge_mod_output_start(output); ++ else { ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 2, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 0x3c, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, con2, TS_OUTPUT_CONTROL2(output->nr)); ++ } ++ if (output->dma) { ++ ddbwritel(dev, output->dma->bufreg, ++ DMA_BUFFER_SIZE(output->dma->nr)); ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma->nr)); ++ ddbwritel(dev, 1, DMA_BASE_READ); ++ ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma->nr)); ++ } ++ if (output->port->class != DDB_PORT_MOD) { ++ if (output->port->input[0]->port->class == DDB_PORT_LOOP) ++ /*ddbwritel(dev, 0x15, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 0x45, ++ TS_OUTPUT_CONTROL(output->nr));*/ ++ ddbwritel(dev, (1 << 13) | 0x15, ++ TS_OUTPUT_CONTROL(output->nr)); ++ else ++ ddbwritel(dev, 0x1d, TS_OUTPUT_CONTROL(output->nr)); ++ } ++ if (output->dma) { ++ output->dma->running = 1; ++ spin_unlock_irq(&output->dma->lock); ++ } ++} + +- ddbwritel((1 << 16) | +- (input->dma_buf_num << 11) | +- (input->dma_buf_size >> 7), +- DMA_BUFFER_SIZE(input->nr)); +- ddbwritel(0, DMA_BUFFER_ACK(input->nr)); ++static void ddb_output_stop(struct ddb_output *output) ++{ ++ struct ddb *dev = output->port->dev; + +- ddbwritel(1, DMA_BASE_WRITE); +- ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); +- ddbwritel(9, TS_INPUT_CONTROL(input->nr)); +- input->running = 1; +- spin_unlock_irq(&input->lock); ++ if (output->dma) ++ spin_lock_irq(&output->dma->lock); ++ if (output->port->class == DDB_PORT_MOD) ++ ddbridge_mod_output_stop(output); ++ else ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr)); ++ if (output->dma) { ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma->nr)); ++ output->dma->running = 0; ++ spin_unlock_irq(&output->dma->lock); ++ } + } + + static void ddb_input_stop(struct ddb_input *input) + { + struct ddb *dev = input->port->dev; + +- spin_lock_irq(&input->lock); +- ddbwritel(0, TS_INPUT_CONTROL(input->nr)); +- ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); +- input->running = 0; +- spin_unlock_irq(&input->lock); ++ if (input->dma) ++ spin_lock_irq(&input->dma->lock); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(input->nr)); ++ if (input->dma) { ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma->nr)); ++ input->dma->running = 0; ++ spin_unlock_irq(&input->dma->lock); ++ } ++ /*pr_info("input_stop %d.%d\n", dev->nr, input->nr);*/ + } + +-static void ddb_output_start(struct ddb_output *output) ++static void ddb_input_start(struct ddb_input *input) + { +- struct ddb *dev = output->port->dev; ++ struct ddb *dev = input->port->dev; + +- spin_lock_irq(&output->lock); +- output->cbuf = 0; +- output->coff = 0; +- ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(2, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel((1 << 16) | +- (output->dma_buf_num << 11) | +- (output->dma_buf_size >> 7), +- DMA_BUFFER_SIZE(output->nr + 8)); +- ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8)); +- +- ddbwritel(1, DMA_BASE_READ); +- ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8)); +- /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */ +- ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr)); +- output->running = 1; +- spin_unlock_irq(&output->lock); ++ if (input->dma) { ++ spin_lock_irq(&input->dma->lock); ++ input->dma->cbuf = 0; ++ input->dma->coff = 0; ++ input->dma->stat = 0; ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma->nr)); ++ } ++ ddbwritel(dev, 0, TS_INPUT_CONTROL2(input->nr)); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(input->nr)); ++ ddbwritel(dev, 2, TS_INPUT_CONTROL(input->nr)); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(input->nr)); ++ ++ if (input->dma) { ++ ddbwritel(dev, input->dma->bufreg, ++ DMA_BUFFER_SIZE(input->dma->nr)); ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma->nr)); ++ ddbwritel(dev, 1, DMA_BASE_WRITE); ++ ddbwritel(dev, 3, DMA_BUFFER_CONTROL(input->dma->nr)); ++ } ++ if (dev->info->type == DDB_OCTONET) ++ ddbwritel(dev, 0x01, TS_INPUT_CONTROL(input->nr)); ++ else ++ ddbwritel(dev, 0x09, TS_INPUT_CONTROL(input->nr)); ++ if (input->dma) { ++ input->dma->running = 1; ++ spin_unlock_irq(&input->dma->lock); ++ } ++ /*pr_info("input_start %d.%d\n", dev->nr, input->nr);*/ + } + +-static void ddb_output_stop(struct ddb_output *output) ++ ++static int ddb_dvb_input_start(struct ddb_input *input) + { +- struct ddb *dev = output->port->dev; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (!dvb->users) ++ ddb_input_start(input); ++ ++ return ++dvb->users; ++} ++ ++static int ddb_dvb_input_stop(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + +- spin_lock_irq(&output->lock); +- ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8)); +- output->running = 0; +- spin_unlock_irq(&output->lock); ++ if (--dvb->users) ++ return dvb->users; ++ ++ ddb_input_stop(input); ++ return 0; ++} ++ ++static void ddb_input_start_all(struct ddb_input *input) ++{ ++ struct ddb_input *i = input; ++ struct ddb_output *o; ++ ++ mutex_lock(&redirect_lock); ++ while (i && (o = i->redo)) { ++ ddb_output_start(o); ++ i = o->port->input[0]; ++ if (i) ++ ddb_input_start(i); ++ } ++ ddb_input_start(input); ++ mutex_unlock(&redirect_lock); ++} ++ ++static void ddb_input_stop_all(struct ddb_input *input) ++{ ++ struct ddb_input *i = input; ++ struct ddb_output *o; ++ ++ mutex_lock(&redirect_lock); ++ ddb_input_stop(input); ++ while (i && (o = i->redo)) { ++ ddb_output_stop(o); ++ i = o->port->input[0]; ++ if (i) ++ ddb_input_stop(i); ++ } ++ mutex_unlock(&redirect_lock); + } + + static u32 ddb_output_free(struct ddb_output *output) + { +- u32 idx, off, stat = output->stat; ++ u32 idx, off, stat = output->dma->stat; + s32 diff; + + idx = (stat >> 11) & 0x1f; + off = (stat & 0x7ff) << 7; + +- if (output->cbuf != idx) { +- if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && +- (output->dma_buf_size - output->coff <= 188)) ++ if (output->dma->cbuf != idx) { ++ if ((((output->dma->cbuf + 1) % output->dma->num) == idx) && ++ (output->dma->size - output->dma->coff <= 188)) + return 0; + return 188; + } +- diff = off - output->coff; ++ diff = off - output->dma->coff; + if (diff <= 0 || diff > 188) + return 188; + return 0; + } + ++#if 0 ++static u32 ddb_dma_free(struct ddb_dma *dma) ++{ ++ u32 idx, off, stat = dma->stat; ++ s32 p1, p2, diff; ++ ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ ++ p1 = idx * dma->size + off; ++ p2 = dma->cbuf * dma->size + dma->coff; ++ ++ diff = p1 - p2; ++ if (diff <= 0) ++ diff += dma->num * dma->size; ++ return diff; ++} ++#endif ++ + static ssize_t ddb_output_write(struct ddb_output *output, +- const __user u8 *buf, size_t count) ++ const u8 *buf, size_t count) + { + struct ddb *dev = output->port->dev; +- u32 idx, off, stat = output->stat; ++ u32 idx, off, stat = output->dma->stat; + u32 left = count, len; + + idx = (stat >> 11) & 0x1f; + off = (stat & 0x7ff) << 7; + + while (left) { +- len = output->dma_buf_size - output->coff; +- if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && ++ len = output->dma->size - output->dma->coff; ++ if ((((output->dma->cbuf + 1) % output->dma->num) == idx) && + (off == 0)) { + if (len <= 188) + break; + len -= 188; + } +- if (output->cbuf == idx) { +- if (off > output->coff) { +-#if 1 +- len = off - output->coff; ++ if (output->dma->cbuf == idx) { ++ if (off > output->dma->coff) { ++ len = off - output->dma->coff; + len -= (len % 188); + if (len <= 188) +- +-#endif + break; + len -= 188; + } + } + if (len > left) + len = left; +- if (copy_from_user(output->vbuf[output->cbuf] + output->coff, ++ if (copy_from_user(output->dma->vbuf[output->dma->cbuf] + ++ output->dma->coff, + buf, len)) + return -EIO; ++#ifdef DDB_ALT_DMA ++ dma_sync_single_for_device(dev->dev, ++ output->dma->pbuf[ ++ output->dma->cbuf], ++ output->dma->size, DMA_TO_DEVICE); ++#endif + left -= len; + buf += len; +- output->coff += len; +- if (output->coff == output->dma_buf_size) { +- output->coff = 0; +- output->cbuf = ((output->cbuf + 1) % output->dma_buf_num); ++ output->dma->coff += len; ++ if (output->dma->coff == output->dma->size) { ++ output->dma->coff = 0; ++ output->dma->cbuf = ((output->dma->cbuf + 1) % ++ output->dma->num); + } +- ddbwritel((output->cbuf << 11) | (output->coff >> 7), +- DMA_BUFFER_ACK(output->nr + 8)); ++ ddbwritel(dev, ++ (output->dma->cbuf << 11) | ++ (output->dma->coff >> 7), ++ DMA_BUFFER_ACK(output->dma->nr)); + } + return count - left; + } + ++#if 0 ++static u32 ddb_input_free_bytes(struct ddb_input *input) ++{ ++ struct ddb *dev = input->port->dev; ++ u32 idx, off, stat = input->dma->stat; ++ u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma->nr)); ++ ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ ++ if (ctrl & 4) ++ return 0; ++ if (input->dma->cbuf != idx) ++ return 1; ++ return 0; ++} ++ ++ ++ ++static s32 ddb_output_used_bufs(struct ddb_output *output) ++{ ++ u32 idx, off, stat, ctrl; ++ s32 diff; ++ ++ spin_lock_irq(&output->dma->lock); ++ stat = output->dma->stat; ++ ctrl = output->dma->ctrl; ++ spin_unlock_irq(&output->dma->lock); ++ ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ ++ if (ctrl & 4) ++ return 0; ++ diff = output->dma->cbuf - idx; ++ if (diff == 0 && off < output->dma->coff) ++ return 0; ++ if (diff <= 0) ++ diff += output->dma->num; ++ return diff; ++} ++ ++static s32 ddb_input_free_bufs(struct ddb_input *input) ++{ ++ u32 idx, off, stat, ctrl; ++ s32 free; ++ ++ spin_lock_irq(&input->dma->lock); ++ ctrl = input->dma->ctrl; ++ stat = input->dma->stat; ++ spin_unlock_irq(&input->dma->lock); ++ if (ctrl & 4) ++ return 0; ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ free = input->dma->cbuf - idx; ++ if (free == 0 && off < input->dma->coff) ++ return 0; ++ if (free <= 0) ++ free += input->dma->num; ++ return free - 1; ++} ++ ++static u32 ddb_output_ok(struct ddb_output *output) ++{ ++ struct ddb_input *input = output->port->input[0]; ++ s32 diff; ++ ++ diff = ddb_input_free_bufs(input) - ddb_output_used_bufs(output); ++ if (diff > 0) ++ return 1; ++ return 0; ++} ++#endif ++ + static u32 ddb_input_avail(struct ddb_input *input) + { + struct ddb *dev = input->port->dev; +- u32 idx, off, stat = input->stat; +- u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr)); ++ u32 idx, off, stat = input->dma->stat; ++ u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma->nr)); + + idx = (stat >> 11) & 0x1f; + off = (stat & 0x7ff) << 7; + + if (ctrl & 4) { +- printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl); +- ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr)); ++ pr_err("IA %d %d %08x\n", idx, off, ctrl); ++ ddbwritel(dev, stat, DMA_BUFFER_ACK(input->dma->nr)); + return 0; + } +- if (input->cbuf != idx) ++ if (input->dma->cbuf != idx) + return 188; + return 0; + } + +-static ssize_t ddb_input_read(struct ddb_input *input, __user u8 *buf, size_t count) ++static size_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) + { + struct ddb *dev = input->port->dev; + u32 left = count; +- u32 idx, free, stat = input->stat; ++ u32 idx, off, free, stat = input->dma->stat; + int ret; + + idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; + + while (left) { +- if (input->cbuf == idx) ++ if (input->dma->cbuf == idx) + return count - left; +- free = input->dma_buf_size - input->coff; ++ free = input->dma->size - input->dma->coff; + if (free > left) + free = left; +- ret = copy_to_user(buf, input->vbuf[input->cbuf] + +- input->coff, free); ++#ifdef DDB_ALT_DMA ++ dma_sync_single_for_cpu(dev->dev, ++ input->dma->pbuf[input->dma->cbuf], ++ input->dma->size, DMA_FROM_DEVICE); ++#endif ++ ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] + ++ input->dma->coff, free); + if (ret) + return -EFAULT; +- input->coff += free; +- if (input->coff == input->dma_buf_size) { +- input->coff = 0; +- input->cbuf = (input->cbuf+1) % input->dma_buf_num; ++ input->dma->coff += free; ++ if (input->dma->coff == input->dma->size) { ++ input->dma->coff = 0; ++ input->dma->cbuf = (input->dma->cbuf + 1) % ++ input->dma->num; + } + left -= free; +- ddbwritel((input->cbuf << 11) | (input->coff >> 7), +- DMA_BUFFER_ACK(input->nr)); ++ ddbwritel(dev, ++ (input->dma->cbuf << 11) | (input->dma->coff >> 7), ++ DMA_BUFFER_ACK(input->dma->nr)); + } + return count; + } + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + +-#if 0 +-static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) ++static ssize_t ts_write(struct file *file, const char *buf, ++ size_t count, loff_t *ppos) + { +- int i; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb *dev = output->port->dev; ++ size_t left = count; ++ int stat; + +- for (i = 0; i < dev->info->port_num * 2; i++) { +- if (dev->input[i].fe == fe) +- return &dev->input[i]; ++ if (!dev->has_dma) ++ return -EINVAL; ++ while (left) { ++ if (ddb_output_free(output) < 188) { ++ if (file->f_flags & O_NONBLOCK) ++ break; ++ if (wait_event_interruptible( ++ output->dma->wq, ++ ddb_output_free(output) >= 188) < 0) ++ break; ++ } ++ stat = ddb_output_write(output, buf, left); ++ if (stat < 0) ++ return stat; ++ buf += stat; ++ left -= stat; + } +- return NULL; ++ return (left == count) ? -EAGAIN : (count - left); + } +-#endif + +-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) ++static ssize_t ts_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) + { +- struct ddb_input *input = fe->sec_priv; +- struct ddb_port *port = input->port; +- int status; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; ++ struct ddb *dev = output->port->dev; ++ size_t left = count; ++ int stat; + +- if (enable) { +- mutex_lock(&port->i2c_gate_lock); +- status = input->gate_ctrl(fe, 1); +- } else { +- status = input->gate_ctrl(fe, 0); +- mutex_unlock(&port->i2c_gate_lock); ++ if (!dev->has_dma) ++ return -EINVAL; ++ while (left) { ++ if (ddb_input_avail(input) < 188) { ++ if (file->f_flags & O_NONBLOCK) ++ break; ++ if (wait_event_interruptible( ++ input->dma->wq, ++ ddb_input_avail(input) >= 188) < 0) ++ break; ++ } ++ stat = ddb_input_read(input, buf, left); ++ if (stat < 0) ++ return stat; ++ left -= stat; ++ buf += stat; + } +- return status; ++ return (count && (left == count)) ? -EAGAIN : (count - left); + } + +-static int demod_attach_drxk(struct ddb_input *input) ++static unsigned int ts_poll(struct file *file, poll_table *wait) + { +- struct i2c_adapter *i2c = &input->port->i2c->adap; +- struct dvb_frontend *fe; +- struct drxk_config config; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; + +- memset(&config, 0, sizeof(config)); +- config.microcode_name = "drxk_a3.mc"; +- config.qam_demod_parameter_count = 4; +- config.adr = 0x29 + (input->nr & 1); ++ unsigned int mask = 0; + +- fe = input->fe = dvb_attach(drxk_attach, &config, i2c); +- if (!input->fe) { +- printk(KERN_ERR "No DRXK found!\n"); +- return -ENODEV; +- } +- fe->sec_priv = input; +- input->gate_ctrl = fe->ops.i2c_gate_ctrl; +- fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; +- return 0; ++ poll_wait(file, &input->dma->wq, wait); ++ poll_wait(file, &output->dma->wq, wait); ++ if (ddb_input_avail(input) >= 188) ++ mask |= POLLIN | POLLRDNORM; ++ if (ddb_output_free(output) >= 188) ++ mask |= POLLOUT | POLLWRNORM; ++ return mask; + } + +-static int tuner_attach_tda18271(struct ddb_input *input) ++static int ts_release(struct inode *inode, struct file *file) + { +- struct i2c_adapter *i2c = &input->port->i2c->adap; +- struct dvb_frontend *fe; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; ++ ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) { ++ if (!input) ++ return -EINVAL; ++ ddb_input_stop(input); ++ } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ ddb_output_stop(output); ++ } ++ return dvb_generic_release(inode, file); ++} ++ ++static int ts_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; ++ ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) { ++ if (!input) ++ return -EINVAL; ++ if (input->redo || input->redi) ++ return -EBUSY; ++ } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ } ++ err = dvb_generic_open(inode, file); ++ if (err < 0) ++ return err; ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) ++ ddb_input_start(input); ++ else if ((file->f_flags & O_ACCMODE) == O_WRONLY) ++ ddb_output_start(output); ++ return err; ++} ++ ++static int mod_release(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ ++ if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ ddb_output_stop(output); ++ } ++ return dvb_generic_release(inode, file); ++} ++ ++static int mod_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ ++ if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ } ++ err = dvb_generic_open(inode, file); ++ if (err < 0) ++ return err; ++ if ((file->f_flags & O_ACCMODE) == O_WRONLY) ++ ddb_output_start(output); ++ return err; ++} ++static const struct file_operations ci_fops = { ++ .owner = THIS_MODULE, ++ .read = ts_read, ++ .write = ts_write, ++ .open = ts_open, ++ .release = ts_release, ++ .poll = ts_poll, ++ .mmap = 0, ++}; ++ ++static struct dvb_device dvbdev_ci = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 2, ++ .fops = &ci_fops, ++}; ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static long mod_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy(file, cmd, arg, ddbridge_mod_do_ioctl); ++} ++ ++static const struct file_operations mod_fops = { ++ .owner = THIS_MODULE, ++ .read = ts_read, ++ .write = ts_write, ++ .open = mod_open, ++ .release = mod_release, ++ .poll = ts_poll, ++ .mmap = 0, ++ .unlocked_ioctl = mod_ioctl, ++}; ++ ++static struct dvb_device dvbdev_mod = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 2, ++ .fops = &mod_fops, ++}; ++ ++ ++#if 0 ++static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) ++{ ++ int i; ++ ++ for (i = 0; i < dev->info->port_num * 2; i++) { ++ if (dev->input[i].fe == fe) ++ return &dev->input[i]; ++ } ++ return NULL; ++} ++#endif ++ ++static int locked_gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int status; ++ ++ if (enable) { ++ mutex_lock(&port->i2c_gate_lock); ++ status = dvb->i2c_gate_ctrl(fe, 1); ++ } else { ++ status = dvb->i2c_gate_ctrl(fe, 0); ++ mutex_unlock(&port->i2c_gate_lock); ++ } ++ return status; ++} ++ ++#if IS_ENABLED(CONFIG_DVB_DRXK) ++static int demod_attach_drxk(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ struct drxk_config config; ++ ++ memset(&config, 0, sizeof(config)); ++ config.adr = 0x29 + (input->nr & 1); ++ config.microcode_name = "drxk_a3.mc"; ++ ++ fe = dvb->fe = dvb_attach(drxk_attach, &config, i2c); ++ if (!fe) { ++ pr_err("No DRXK found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++#endif ++ ++#if 0 ++struct stv0367_config stv0367_0 = { ++ .demod_address = 0x1f, ++ .xtal = 27000000, ++ .if_khz = 5000, ++ .if_iq_mode = FE_TER_NORMAL_IF_TUNER, ++ .ts_mode = STV0367_SERIAL_PUNCT_CLOCK, ++ .clk_pol = STV0367_RISINGEDGE_CLOCK, ++}; ++ ++struct stv0367_config stv0367_1 = { ++ .demod_address = 0x1e, ++ .xtal = 27000000, ++ .if_khz = 5000, ++ .if_iq_mode = FE_TER_NORMAL_IF_TUNER, ++ .ts_mode = STV0367_SERIAL_PUNCT_CLOCK, ++ .clk_pol = STV0367_RISINGEDGE_CLOCK, ++}; ++ ++ ++static int demod_attach_stv0367(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ fe = dvb->fe = dvb_attach(stv0367ter_attach, ++ (input->nr & 1) ? &stv0367_1 : &stv0367_0, ++ i2c); ++ if (!dvb->fe) { ++ pr_err("No stv0367 found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++#endif ++ ++struct cxd2843_cfg cxd2843_0 = { ++ .adr = 0x6c, ++}; ++ ++struct cxd2843_cfg cxd2843_1 = { ++ .adr = 0x6d, ++}; ++ ++struct cxd2843_cfg cxd2843p_0 = { ++ .adr = 0x6c, ++ .parallel = 1, ++}; + +- if (input->fe->ops.i2c_gate_ctrl) +- input->fe->ops.i2c_gate_ctrl(input->fe, 1); +- fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); ++struct cxd2843_cfg cxd2843p_1 = { ++ .adr = 0x6d, ++ .parallel = 1, ++}; ++ ++static int demod_attach_cxd2843(struct ddb_input *input, int par) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ if (par) ++ fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, ++ (input->nr & 1) ? ++ &cxd2843p_1 : &cxd2843p_0); ++ else ++ fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, ++ (input->nr & 1) ? ++ &cxd2843_1 : &cxd2843_0); ++ if (!dvb->fe) { ++ pr_err("No cxd2837/38/43 found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++struct stv0367_cfg stv0367dd_0 = { ++ .adr = 0x1f, ++ .xtal = 27000000, ++}; ++ ++struct stv0367_cfg stv0367dd_1 = { ++ .adr = 0x1e, ++ .xtal = 27000000, ++}; ++ ++static int demod_attach_stv0367dd(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ fe = dvb->fe = dvb_attach(stv0367_attach, i2c, ++ (input->nr & 1) ? ++ &stv0367dd_1 : &stv0367dd_0, ++ &dvb->fe2); ++ if (!dvb->fe) { ++ pr_err("No stv0367 found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int tuner_attach_tda18271(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ if (dvb->fe->ops.i2c_gate_ctrl) ++ dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 1); ++ fe = dvb_attach(tda18271c2dd_attach, dvb->fe, i2c, 0x60); ++ if (dvb->fe->ops.i2c_gate_ctrl) ++ dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 0); + if (!fe) { +- printk(KERN_ERR "No TDA18271 found!\n"); ++ pr_err("No TDA18271 found!\n"); + return -ENODEV; + } +- if (input->fe->ops.i2c_gate_ctrl) +- input->fe->ops.i2c_gate_ctrl(input->fe, 0); + return 0; + } + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++static int tuner_attach_tda18212dd(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ fe = dvb_attach(tda18212dd_attach, dvb->fe, i2c, ++ (input->nr & 1) ? 0x63 : 0x60); ++ if (!fe) { ++ pr_err("No TDA18212 found!\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++#ifdef CONFIG_DVB_TDA18212 ++struct tda18212_config tda18212_0 = { ++ .i2c_address = 0x60, ++}; ++ ++struct tda18212_config tda18212_1 = { ++ .i2c_address = 0x63, ++}; ++ ++static int tuner_attach_tda18212(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ struct tda18212_config *cfg; ++ ++ cfg = (input->nr & 1) ? &tda18212_1 : &tda18212_0; ++ fe = dvb_attach(tda18212_attach, dvb->fe, i2c, cfg); ++ if (!fe) { ++ pr_err("No TDA18212 found!\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + + static struct stv090x_config stv0900 = { + .device = STV0900, +@@ -624,6 +1144,9 @@ static struct stv090x_config stv0900 = { + .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + ++ .ts1_tei = 1, ++ .ts2_tei = 1, ++ + .repeater_level = STV090x_RPTLEVEL_16, + + .adc1_range = STV090x_ADC_1Vpp, +@@ -643,6 +1166,9 @@ static struct stv090x_config stv0900_aa = { + .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + ++ .ts1_tei = 1, ++ .ts2_tei = 1, ++ + .repeater_level = STV090x_RPTLEVEL_16, + + .adc1_range = STV090x_ADC_1Vpp, +@@ -667,18 +1193,19 @@ static int demod_attach_stv0900(struct ddb_input *input, int type) + { + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + +- input->fe = dvb_attach(stv090x_attach, feconf, i2c, +- (input->nr & 1) ? STV090x_DEMODULATOR_1 +- : STV090x_DEMODULATOR_0); +- if (!input->fe) { +- printk(KERN_ERR "No STV0900 found!\n"); ++ dvb->fe = dvb_attach(stv090x_attach, feconf, i2c, ++ (input->nr & 1) ? STV090x_DEMODULATOR_1 ++ : STV090x_DEMODULATOR_0); ++ if (!dvb->fe) { ++ pr_err("No STV0900 found!\n"); + return -ENODEV; + } +- if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0, ++ if (!dvb_attach(lnbh24_attach, dvb->fe, i2c, 0, + 0, (input->nr & 1) ? + (0x09 - type) : (0x0b - type))) { +- printk(KERN_ERR "No LNBH24 found!\n"); ++ pr_err("No LNBH24 found!\n"); + return -ENODEV; + } + return 0; +@@ -687,18 +1214,19 @@ static int demod_attach_stv0900(struct ddb_input *input, int type) + static int tuner_attach_stv6110(struct ddb_input *input, int type) + { + struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; + struct stv6110x_config *tunerconf = (input->nr & 1) ? + &stv6110b : &stv6110a; + struct stv6110x_devctl *ctl; + +- ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c); ++ ctl = dvb_attach(stv6110x_attach, dvb->fe, tunerconf, i2c); + if (!ctl) { +- printk(KERN_ERR "No STV6110X found!\n"); ++ pr_err("No STV6110X found!\n"); + return -ENODEV; + } +- printk(KERN_INFO "attach tuner input %d adr %02x\n", +- input->nr, tunerconf->addr); ++ pr_info("attach tuner input %d adr %02x\n", ++ input->nr, tunerconf->addr); + + feconf->tuner_init = ctl->tuner_init; + feconf->tuner_sleep = ctl->tuner_sleep; +@@ -715,329 +1243,919 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) + return 0; + } + +-static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, +- int (*start_feed)(struct dvb_demux_feed *), +- int (*stop_feed)(struct dvb_demux_feed *), +- void *priv) ++static struct stv0910_cfg stv0910 = { ++ .adr = 0x68, ++ .parallel = 1, ++ .rptlvl = 4, ++ .clk = 30000000, ++}; ++ ++static int demod_attach_stv0910(struct ddb_input *input, int type) + { +- dvbdemux->priv = priv; ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + +- dvbdemux->filternum = 256; +- dvbdemux->feednum = 256; +- dvbdemux->start_feed = start_feed; +- dvbdemux->stop_feed = stop_feed; +- dvbdemux->write_to_decoder = NULL; +- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | +- DMX_SECTION_FILTERING | +- DMX_MEMORY_BASED_FILTERING); +- return dvb_dmx_init(dvbdemux); ++ dvb->fe = dvb_attach(stv0910_attach, i2c, &stv0910, (input->nr & 1)); ++ if (!dvb->fe) { ++ pr_err("No STV0910 found!\n"); ++ return -ENODEV; ++ } ++ if (!dvb_attach(lnbh25_attach, dvb->fe, i2c, ++ (input->nr & 1) ? 0x09 : 0x08)) { ++ pr_err("No LNBH25 found!\n"); ++ return -ENODEV; ++ } ++ return 0; + } + +-static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, +- struct dvb_demux *dvbdemux, +- struct dmx_frontend *hw_frontend, +- struct dmx_frontend *mem_frontend, +- struct dvb_adapter *dvb_adapter) ++static int tuner_attach_stv6111(struct ddb_input *input) + { +- int ret; +- +- dmxdev->filternum = 256; +- dmxdev->demux = &dvbdemux->dmx; +- dmxdev->capabilities = 0; +- ret = dvb_dmxdev_init(dmxdev, dvb_adapter); +- if (ret < 0) +- return ret; ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; + +- hw_frontend->source = DMX_FRONTEND_0; +- dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); +- mem_frontend->source = DMX_MEMORY_FE; +- dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); +- return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); ++ fe = dvb_attach(stv6111_attach, dvb->fe, i2c, ++ (input->nr & 1) ? 0x63 : 0x60); ++ if (!fe) { ++ pr_err("No STV6111 found!\n"); ++ return -ENODEV; ++ } ++ return 0; + } + +-static int start_feed(struct dvb_demux_feed *dvbdmxfeed) ++static int lnb_command(struct ddb *dev, u32 lnb, u32 cmd) + { +- struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +- struct ddb_input *input = dvbdmx->priv; ++ u32 c, v = 0; + +- if (!input->users) +- ddb_input_start(input); +- +- return ++input->users; ++ v = LNB_TONE & (dev->lnb_tone << (15 - lnb)); ++ pr_info("lnb_control[%u] = %08x\n", lnb, cmd | v); ++ ddbwritel(dev, cmd | v, LNB_CONTROL(lnb)); ++ for (c = 0; c < 10; c++) { ++ v = ddbreadl(dev, LNB_CONTROL(lnb)); ++ pr_info("ctrl = %08x\n", v); ++ if ((v & LNB_BUSY) == 0) ++ break; ++ msleep(20); ++ } ++ return 0; + } + +-static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++static int dd_send_master_cmd(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *cmd) + { +- struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +- struct ddb_input *input = dvbdmx->priv; +- +- if (--input->users) +- return input->users; ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int i; + +- ddb_input_stop(input); ++ mutex_lock(&dev->lnb_lock); ++ ddbwritel(dev, 0, LNB_BUF_LEVEL(dvb->input)); ++ for (i = 0; i < cmd->msg_len; i++) ++ ddbwritel(dev, cmd->msg[i], LNB_BUF_WRITE(dvb->input)); ++ lnb_command(dev, dvb->input, LNB_CMD_DISEQC); ++ mutex_unlock(&dev->lnb_lock); + return 0; + } + +- +-static void dvb_input_detach(struct ddb_input *input) ++static int dd_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) + { +- struct dvb_adapter *adap = &input->adap; +- struct dvb_demux *dvbdemux = &input->demux; +- +- switch (input->attached) { +- case 5: +- if (input->fe2) +- dvb_unregister_frontend(input->fe2); +- if (input->fe) { +- dvb_unregister_frontend(input->fe); +- dvb_frontend_detach(input->fe); +- input->fe = NULL; +- } +- case 4: +- dvb_net_release(&input->dvbnet); +- +- case 3: +- dvbdemux->dmx.close(&dvbdemux->dmx); +- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, +- &input->hw_frontend); +- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, +- &input->mem_frontend); +- dvb_dmxdev_release(&input->dmxdev); ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int s = 0; + +- case 2: +- dvb_dmx_release(&input->demux); ++ mutex_lock(&dev->lnb_lock); ++ switch (tone) { ++ case SEC_TONE_OFF: ++ dev->lnb_tone &= ~(1ULL << dvb->input); ++ break; ++ case SEC_TONE_ON: ++ dev->lnb_tone |= (1ULL << dvb->input); ++ break; ++ default: ++ s = -EINVAL; ++ break; ++ }; ++ if (!s) ++ s = lnb_command(dev, dvb->input, LNB_CMD_NOP); ++ mutex_unlock(&dev->lnb_lock); ++ return 0; ++} + +- case 1: +- dvb_unregister_adapter(adap); +- } +- input->attached = 0; ++static int dd_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) ++{ ++ ++ return 0; + } + +-static int dvb_input_attach(struct ddb_input *input) ++static int dd_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) + { +- int ret; ++ struct ddb_input *input = fe->sec_priv; + struct ddb_port *port = input->port; +- struct dvb_adapter *adap = &input->adap; +- struct dvb_demux *dvbdemux = &input->demux; +- +- ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, +- &input->port->dev->pdev->dev, +- adapter_nr); +- if (ret < 0) { +- printk(KERN_ERR "ddbridge: Could not register adapter." +- "Check if you enabled enough adapters in dvb-core!\n"); ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int s = 0; ++ ++ mutex_lock(&dev->lnb_lock); ++ switch (voltage) { ++ case SEC_VOLTAGE_OFF: ++ lnb_command(dev, dvb->input, LNB_CMD_OFF); ++ break; ++ case SEC_VOLTAGE_13: ++ lnb_command(dev, dvb->input, LNB_CMD_LOW); ++ break; ++ case SEC_VOLTAGE_18: ++ lnb_command(dev, dvb->input, LNB_CMD_HIGH); ++ break; ++ default: ++ s = -EINVAL; ++ break; ++ }; ++ mutex_unlock(&dev->lnb_lock); ++ return s; ++} ++ ++static int dd_set_input(struct dvb_frontend *fe) ++{ ++ ++ return 0; ++} ++ ++static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, ++ int (*start_feed)(struct dvb_demux_feed *), ++ int (*stop_feed)(struct dvb_demux_feed *), ++ void *priv) ++{ ++ dvbdemux->priv = priv; ++ ++ dvbdemux->filternum = 256; ++ dvbdemux->feednum = 256; ++ dvbdemux->start_feed = start_feed; ++ dvbdemux->stop_feed = stop_feed; ++ dvbdemux->write_to_decoder = NULL; ++ dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | ++ DMX_SECTION_FILTERING | ++ DMX_MEMORY_BASED_FILTERING); ++ return dvb_dmx_init(dvbdemux); ++} ++ ++static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, ++ struct dvb_demux *dvbdemux, ++ struct dmx_frontend *hw_frontend, ++ struct dmx_frontend *mem_frontend, ++ struct dvb_adapter *dvb_adapter) ++{ ++ int ret; ++ ++ dmxdev->filternum = 256; ++ dmxdev->demux = &dvbdemux->dmx; ++ dmxdev->capabilities = 0; ++ ret = dvb_dmxdev_init(dmxdev, dvb_adapter); ++ if (ret < 0) + return ret; ++ ++ hw_frontend->source = DMX_FRONTEND_0; ++ dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); ++ mem_frontend->source = DMX_MEMORY_FE; ++ dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); ++ return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); ++} ++ ++#if 0 ++static int start_input(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (!dvb->users) ++ ddb_input_start_all(input); ++ ++ return ++dvb->users; ++} ++ ++static int stop_input(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (--dvb->users) ++ return dvb->users; ++ ++ ddb_input_stop_all(input); ++ return 0; ++} ++#endif ++ ++static int start_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct ddb_input *input = dvbdmx->priv; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (!dvb->users) ++ ddb_input_start_all(input); ++ ++ return ++dvb->users; ++} ++ ++static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct ddb_input *input = dvbdmx->priv; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (--dvb->users) ++ return dvb->users; ++ ++ ddb_input_stop_all(input); ++ return 0; ++} ++ ++static void dvb_input_detach(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_demux *dvbdemux = &dvb->demux; ++ ++ switch (dvb->attached) { ++ case 0x31: ++ if (dvb->fe2) ++ dvb_unregister_frontend(dvb->fe2); ++ if (dvb->fe) ++ dvb_unregister_frontend(dvb->fe); ++ /* fallthrough */ ++ case 0x30: ++ dvb_frontend_detach(dvb->fe); ++ dvb->fe = dvb->fe2 = NULL; ++ /* fallthrough */ ++ case 0x21: ++ if (input->port->dev->ns_num) ++ dvb_netstream_release(&dvb->dvbns); ++ /* fallthrough */ ++ case 0x20: ++ dvb_net_release(&dvb->dvbnet); ++ /* fallthrough */ ++ case 0x11: ++ dvbdemux->dmx.close(&dvbdemux->dmx); ++ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, ++ &dvb->hw_frontend); ++ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, ++ &dvb->mem_frontend); ++ dvb_dmxdev_release(&dvb->dmxdev); ++ /* fallthrough */ ++ case 0x10: ++ dvb_dmx_release(&dvb->demux); ++ /* fallthrough */ ++ case 0x01: ++ break; ++ } ++ dvb->attached = 0x00; ++} ++ ++static int dvb_register_adapters(struct ddb *dev) ++{ ++ int i, ret = 0; ++ struct ddb_port *port; ++ struct dvb_adapter *adap; ++ ++ if (adapter_alloc == 3 || dev->info->type == DDB_MOD) { ++ port = &dev->port[0]; ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ for (i = 0; i < dev->info->port_num; i++) { ++ port = &dev->port[i]; ++ port->dvb[0].adap = adap; ++ port->dvb[1].adap = adap; ++ } ++ return 0; ++ } ++ ++ for (i = 0; i < dev->info->port_num; i++) { ++ port = &dev->port[i]; ++ switch (port->class) { ++ case DDB_PORT_TUNER: ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ ++ if (adapter_alloc > 0) { ++ port->dvb[1].adap = port->dvb[0].adap; ++ break; ++ } ++ adap = port->dvb[1].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[1].adap_registered = 1; ++ break; ++ ++ case DDB_PORT_CI: ++ case DDB_PORT_LOOP: ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ break; ++ default: ++ if (adapter_alloc < 2) ++ break; ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ break; ++ } ++ } ++ return ret; ++} ++ ++static void dvb_unregister_adapters(struct ddb *dev) ++{ ++ int i; ++ struct ddb_port *port; ++ struct ddb_dvb *dvb; ++ ++ for (i = 0; i < dev->info->port_num; i++) { ++ port = &dev->port[i]; ++ ++ dvb = &port->dvb[0]; ++ if (dvb->adap_registered) ++ dvb_unregister_adapter(dvb->adap); ++ dvb->adap_registered = 0; ++ ++ dvb = &port->dvb[1]; ++ if (dvb->adap_registered) ++ dvb_unregister_adapter(dvb->adap); ++ dvb->adap_registered = 0; + } +- input->attached = 1; ++} ++ ++static int dvb_input_attach(struct ddb_input *input) ++{ ++ int ret = 0; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct ddb_port *port = input->port; ++ struct dvb_adapter *adap = dvb->adap; ++ struct dvb_demux *dvbdemux = &dvb->demux; ++ ++ dvb->attached = 0x01; + + ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", + start_feed, + stop_feed, input); + if (ret < 0) + return ret; +- input->attached = 2; ++ dvb->attached = 0x10; + +- ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux, +- &input->hw_frontend, +- &input->mem_frontend, adap); ++ ret = my_dvb_dmxdev_ts_card_init(&dvb->dmxdev, ++ &dvb->demux, ++ &dvb->hw_frontend, ++ &dvb->mem_frontend, adap); + if (ret < 0) + return ret; +- input->attached = 3; ++ dvb->attached = 0x11; + +- ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux); ++ ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); + if (ret < 0) + return ret; +- input->attached = 4; ++ dvb->attached = 0x20; + +- input->fe = NULL; ++ if (input->port->dev->ns_num) { ++ ret = netstream_init(input); ++ if (ret < 0) ++ return ret; ++ dvb->attached = 0x21; ++ } ++ dvb->fe = dvb->fe2 = 0; + switch (port->type) { + case DDB_TUNER_DVBS_ST: + if (demod_attach_stv0900(input, 0) < 0) + return -ENODEV; + if (tuner_attach_stv6110(input, 0) < 0) + return -ENODEV; +- if (input->fe) { +- if (dvb_register_frontend(adap, input->fe) < 0) +- return -ENODEV; +- } ++ break; ++ case DDB_TUNER_DVBS_STV0910: ++ case DDB_TUNER_DVBS_STV0910_P: ++ if (demod_attach_stv0910(input, 0) < 0) ++ return -ENODEV; ++ if (tuner_attach_stv6111(input) < 0) ++ return -ENODEV; + break; + case DDB_TUNER_DVBS_ST_AA: + if (demod_attach_stv0900(input, 1) < 0) + return -ENODEV; + if (tuner_attach_stv6110(input, 1) < 0) + return -ENODEV; +- if (input->fe) { +- if (dvb_register_frontend(adap, input->fe) < 0) +- return -ENODEV; +- } + break; ++#if IS_ENABLED(CONFIG_DVB_DRXK) + case DDB_TUNER_DVBCT_TR: + if (demod_attach_drxk(input) < 0) + return -ENODEV; + if (tuner_attach_tda18271(input) < 0) + return -ENODEV; +- if (dvb_register_frontend(adap, input->fe) < 0) ++ break; ++#endif ++ case DDB_TUNER_DVBCT_ST: ++ if (demod_attach_stv0367dd(input) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) ++ return -ENODEV; ++ break; ++ case DDB_TUNER_DVBCT2_SONY: ++ case DDB_TUNER_DVBC2T2_SONY: ++ case DDB_TUNER_ISDBT_SONY: ++ if (demod_attach_cxd2843(input, 0) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) ++ return -ENODEV; ++ break; ++ case DDB_TUNER_DVBCT2_SONY_P: ++ case DDB_TUNER_DVBC2T2_SONY_P: ++ case DDB_TUNER_ISDBT_SONY_P: ++ if (demod_attach_cxd2843(input, 1) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) + return -ENODEV; +- if (input->fe2) { +- if (dvb_register_frontend(adap, input->fe2) < 0) +- return -ENODEV; +- input->fe2->tuner_priv = input->fe->tuner_priv; +- memcpy(&input->fe2->ops.tuner_ops, +- &input->fe->ops.tuner_ops, +- sizeof(struct dvb_tuner_ops)); +- } + break; ++ default: ++ return 0; + } +- input->attached = 5; ++ dvb->attached = 0x30; ++ if (dvb->fe) { ++ if (dvb_register_frontend(adap, dvb->fe) < 0) ++ return -ENODEV; ++ } ++ if (dvb->fe2) { ++ if (dvb_register_frontend(adap, dvb->fe2) < 0) ++ return -ENODEV; ++ dvb->fe2->tuner_priv = dvb->fe->tuner_priv; ++ memcpy(&dvb->fe2->ops.tuner_ops, ++ &dvb->fe->ops.tuner_ops, ++ sizeof(struct dvb_tuner_ops)); ++ } ++ dvb->attached = 0x31; + return 0; + } + +-/****************************************************************************/ +-/****************************************************************************/ + +-static ssize_t ts_write(struct file *file, const __user char *buf, +- size_t count, loff_t *ppos) ++static int port_has_encti(struct ddb_port *port) + { +- struct dvb_device *dvbdev = file->private_data; +- struct ddb_output *output = dvbdev->priv; +- size_t left = count; +- int stat; ++ u8 val; ++ int ret = i2c_read_reg(&port->i2c->adap, 0x20, 0, &val); + +- while (left) { +- if (ddb_output_free(output) < 188) { +- if (file->f_flags & O_NONBLOCK) +- break; +- if (wait_event_interruptible( +- output->wq, ddb_output_free(output) >= 188) < 0) +- break; +- } +- stat = ddb_output_write(output, buf, left); +- if (stat < 0) +- break; +- buf += stat; +- left -= stat; +- } +- return (left == count) ? -EAGAIN : (count - left); ++ if (!ret) ++ pr_info("[0x20]=0x%02x\n", val); ++ return ret ? 0 : 1; + } + +-static ssize_t ts_read(struct file *file, __user char *buf, +- size_t count, loff_t *ppos) ++static int port_has_cxd(struct ddb_port *port, u8 *type) + { +- struct dvb_device *dvbdev = file->private_data; +- struct ddb_output *output = dvbdev->priv; +- struct ddb_input *input = output->port->input[0]; +- int left, read; ++ u8 val; ++ u8 probe[4] = { 0xe0, 0x00, 0x00, 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = 0x40, .flags = 0, ++ .buf = probe, .len = 4 }, ++ { .addr = 0x40, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++ val = i2c_transfer(&port->i2c->adap, msgs, 2); ++ if (val != 2) ++ return 0; + +- count -= count % 188; +- left = count; +- while (left) { +- if (ddb_input_avail(input) < 188) { +- if (file->f_flags & O_NONBLOCK) +- break; +- if (wait_event_interruptible( +- input->wq, ddb_input_avail(input) >= 188) < 0) +- break; +- } +- read = ddb_input_read(input, buf, left); +- if (read < 0) +- return read; +- left -= read; +- buf += read; +- } +- return (left == count) ? -EAGAIN : (count - left); ++ if (data[0] == 0x02 && data[1] == 0x2b && data[3] == 0x43) ++ *type = 2; ++ else ++ *type = 1; ++ return 1; + } + +-static unsigned int ts_poll(struct file *file, poll_table *wait) ++static int port_has_xo2(struct ddb_port *port, u8 *id) + { +- /* +- struct dvb_device *dvbdev = file->private_data; +- struct ddb_output *output = dvbdev->priv; +- struct ddb_input *input = output->port->input[0]; +- */ +- unsigned int mask = 0; ++ u8 val; ++ u8 probe[1] = { 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = 0x10, .flags = 0, ++ .buf = probe, .len = 1 }, ++ { .addr = 0x10, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++ val = i2c_transfer(&port->i2c->adap, msgs, 2); ++ if (val != 2) ++ return 0; ++ ++ if (data[0] != 'D' || data[1] != 'F') ++ return 0; ++ ++ *id = data[2]; ++ return 1; ++} ++ ++static int port_has_stv0900(struct ddb_port *port) ++{ ++ u8 val; ++ if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) ++ return 0; ++ return 1; ++} ++ ++static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) ++{ ++ if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) ++ return 0; ++ return 1; ++} ++ ++static int port_has_drxks(struct ddb_port *port) ++{ ++ u8 val; ++ if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) ++ return 0; ++ if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) ++ return 0; ++ return 1; ++} ++ ++static int port_has_stv0367(struct ddb_port *port) ++{ ++ u8 val; ++ ++ if (i2c_read_reg16(&port->i2c->adap, 0x1e, 0xf000, &val) < 0) ++ return 0; ++ if (val != 0x60) ++ return 0; ++ if (i2c_read_reg16(&port->i2c->adap, 0x1f, 0xf000, &val) < 0) ++ return 0; ++ if (val != 0x60) ++ return 0; ++ return 1; ++} + + #if 0 +- if (data_avail_to_read) +- mask |= POLLIN | POLLRDNORM; +- if (data_avail_to_write) +- mask |= POLLOUT | POLLWRNORM; ++static int init_xo2_old(struct ddb_port *port) ++{ ++ struct i2c_adapter *i2c = &port->i2c->adap; ++ u8 val; ++ int res; ++ ++ res = i2c_read_reg(i2c, 0x10, 0x04, &val); ++ if (res < 0) ++ return res; ++ ++ if (val != 0x02) { ++ pr_info("Port %d: invalid XO2\n", port->nr); ++ return -1; ++ } ++ i2c_write_reg(i2c, 0x10, 0xc0, 0x00); /* Disable XO2 I2C master */ ++ ++ i2c_read_reg(i2c, 0x10, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, 0x10, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x87); + +- poll_wait(file, &read_queue, wait); +- poll_wait(file, &write_queue, wait); ++ return 0; ++} + #endif +- return mask; ++ ++static int init_xo2(struct ddb_port *port) ++{ ++ struct i2c_adapter *i2c = &port->i2c->adap; ++ u8 val, data[2]; ++ int res; ++ ++ res = i2c_read_regs(i2c, 0x10, 0x04, data, 2); ++ if (res < 0) ++ return res; ++ ++ if (data[0] != 0x01) { ++ pr_info("Port %d: invalid XO2\n", port->nr); ++ return -1; ++ } ++ ++ i2c_read_reg(i2c, 0x10, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, 0x10, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x87); ++ ++ return 0; + } + +-static const struct file_operations ci_fops = { +- .owner = THIS_MODULE, +- .read = ts_read, +- .write = ts_write, +- .open = dvb_generic_open, +- .release = dvb_generic_release, +- .poll = ts_poll, ++static int port_has_cxd28xx(struct ddb_port *port, u8 *id) ++{ ++ struct i2c_adapter *i2c = &port->i2c->adap; ++ int status; ++ ++ status = i2c_write_reg(&port->i2c->adap, 0x6e, 0, 0); ++ if (status) ++ return 0; ++ status = i2c_read_reg(i2c, 0x6e, 0xfd, id); ++ if (status) ++ return 0; ++ return 1; ++} ++ ++static char *xo2names[] = { ++ "DUAL DVB-S2", "DUAL DVB-C/T/T2", ++ "DUAL DVB-ISDBT", "DUAL DVB-C/C2/T/T2", ++ "DUAL ATSC", "DUAL DVB-C/C2/T/T2", ++ "", "" + }; + +-static struct dvb_device dvbdev_ci = { +- .readers = -1, +- .writers = -1, +- .users = -1, +- .fops = &ci_fops, +-}; ++static void ddb_port_probe(struct ddb_port *port) ++{ ++ struct ddb *dev = port->dev; ++ u8 id; ++ ++ port->name = "NO MODULE"; ++ port->class = DDB_PORT_NONE; ++ ++ if (dev->info->type == DDB_MOD) { ++ port->name = "MOD"; ++ port->class = DDB_PORT_MOD; ++ return; ++ } ++ ++ if (dev->info->type == DDB_OCTOPUS_MAX) { ++ port->name = "DUAL DVB-S2 MX"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_MXL5XX; ++ if (port->i2c) ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ return; ++ } ++ ++ if (port->nr > 1 && dev->info->type == DDB_OCTOPUS_CI) { ++ port->name = "CI internal"; ++ port->class = DDB_PORT_CI; ++ port->type = DDB_CI_INTERNAL; ++ } else if (port_has_cxd(port, &id)) { ++ if (id == 1) { ++ port->name = "CI"; ++ port->class = DDB_PORT_CI; ++ port->type = DDB_CI_EXTERNAL_SONY; ++ ddbwritel(dev, I2C_SPEED_400, ++ port->i2c->regs + I2C_TIMING); ++ } else { ++ pr_info(KERN_INFO "Port %d: Uninitialized DuoFlex\n", ++ port->nr); ++ return; ++ } ++ } else if (port_has_xo2(port, &id)) { ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ id >>= 2; ++ if (id > 5) { ++ port->name = "unknown XO2 DuoFlex"; ++ } else { ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_XO2 + id; ++ port->name = xo2names[id]; ++ init_xo2(port); ++ } ++ } else if (port_has_cxd28xx(port, &id)) { ++ switch (id) { ++ case 0xa4: ++ port->name = "DUAL DVB-CT2 CXD2843"; ++ port->type = DDB_TUNER_DVBC2T2_SONY_P; ++ break; ++ case 0xb1: ++ port->name = "DUAL DVB-CT2 CXD2837"; ++ port->type = DDB_TUNER_DVBCT2_SONY_P; ++ break; ++ case 0xb0: ++ port->name = "DUAL ISDB-T CXD2838"; ++ port->type = DDB_TUNER_ISDBT_SONY_P; ++ break; ++ default: ++ return; ++ } ++ port->class = DDB_PORT_TUNER; ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_stv0900(port)) { ++ port->name = "DUAL DVB-S2"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBS_ST; ++ ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_stv0900_aa(port, &id)) { ++ port->name = "DUAL DVB-S2"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBS_ST_AA; ++ if (id == 0x51) ++ port->type = DDB_TUNER_DVBS_STV0910_P; ++ else ++ port->type = DDB_TUNER_DVBS_ST_AA; ++ ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_drxks(port)) { ++ port->name = "DUAL DVB-C/T"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBCT_TR; ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_stv0367(port)) { ++ port->name = "DUAL DVB-C/T"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBCT_ST; ++ ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_encti(port)) { ++ port->name = "ENCTI"; ++ port->class = DDB_PORT_LOOP; ++ } else if (port->nr == ts_loop) { ++ port->name = "TS LOOP"; ++ port->class = DDB_PORT_LOOP; ++ } ++} ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static int wait_ci_ready(struct ddb_ci *ci) ++{ ++ u32 count = 10; ++ ++ ndelay(500); ++ do { ++ if (ddbreadl(ci->port->dev, ++ CI_CONTROL(ci->nr)) & CI_READY) ++ break; ++ usleep_range(1, 2); ++ if ((--count) == 0) ++ return -1; ++ } while (1); ++ return 0; ++} ++ ++static int read_attribute_mem(struct dvb_ca_en50221 *ca, ++ int slot, int address) ++{ ++ struct ddb_ci *ci = ca->data; ++ u32 val, off = (address >> 1) & (CI_BUFFER_SIZE-1); ++ ++ if (address > CI_BUFFER_SIZE) ++ return -1; ++ ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address, ++ CI_DO_READ_ATTRIBUTES(ci->nr)); ++ wait_ci_ready(ci); ++ val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off); ++ return val; ++} ++ ++static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, ++ int address, u8 value) ++{ ++ struct ddb_ci *ci = ca->data; ++ ++ ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address, ++ CI_DO_ATTRIBUTE_RW(ci->nr)); ++ wait_ci_ready(ci); ++ return 0; ++} ++ ++static int read_cam_control(struct dvb_ca_en50221 *ca, ++ int slot, u8 address) ++{ ++ u32 count = 100; ++ struct ddb_ci *ci = ca->data; ++ u32 res; ++ ++ ddbwritel(ci->port->dev, CI_READ_CMD | address, ++ CI_DO_IO_RW(ci->nr)); ++ ndelay(500); ++ do { ++ res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr)); ++ if (res & CI_READY) ++ break; ++ usleep_range(1, 2); ++ if ((--count) == 0) ++ return -1; ++ } while (1); ++ return 0xff & res; ++} ++ ++static int write_cam_control(struct dvb_ca_en50221 *ca, int slot, ++ u8 address, u8 value) ++{ ++ struct ddb_ci *ci = ca->data; ++ ++ ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address, ++ CI_DO_IO_RW(ci->nr)); ++ wait_ci_ready(ci); ++ return 0; ++} ++ ++static int slot_reset(struct dvb_ca_en50221 *ca, int slot) ++{ ++ struct ddb_ci *ci = ca->data; ++ ++ ddbwritel(ci->port->dev, CI_POWER_ON, ++ CI_CONTROL(ci->nr)); ++ msleep(100); ++ ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM, ++ CI_CONTROL(ci->nr)); ++ ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM, ++ CI_CONTROL(ci->nr)); ++ udelay(20); ++ ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON, ++ CI_CONTROL(ci->nr)); ++ return 0; ++} + +-/****************************************************************************/ +-/****************************************************************************/ +-/****************************************************************************/ ++static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot) ++{ ++ struct ddb_ci *ci = ca->data; + +-static void input_tasklet(unsigned long data) ++ ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr)); ++ msleep(300); ++ return 0; ++} ++ ++static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) + { +- struct ddb_input *input = (struct ddb_input *) data; +- struct ddb *dev = input->port->dev; ++ struct ddb_ci *ci = ca->data; ++ u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr)); + +- spin_lock(&input->lock); +- if (!input->running) { +- spin_unlock(&input->lock); +- return; +- } +- input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); ++ ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE, ++ CI_CONTROL(ci->nr)); ++ return 0; ++} + +- if (input->port->class == DDB_PORT_TUNER) { +- if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) +- printk(KERN_ERR "Overflow input %d\n", input->nr); +- while (input->cbuf != ((input->stat >> 11) & 0x1f) +- || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) { +- dvb_dmx_swfilter_packets(&input->demux, +- input->vbuf[input->cbuf], +- input->dma_buf_size / 188); ++static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) ++{ ++ struct ddb_ci *ci = ca->data; ++ u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr)); ++ int stat = 0; + +- input->cbuf = (input->cbuf + 1) % input->dma_buf_num; +- ddbwritel((input->cbuf << 11), +- DMA_BUFFER_ACK(input->nr)); +- input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); +- } +- } +- if (input->port->class == DDB_PORT_CI) +- wake_up(&input->wq); +- spin_unlock(&input->lock); ++ if (val & CI_CAM_DETECT) ++ stat |= DVB_CA_EN50221_POLL_CAM_PRESENT; ++ if (val & CI_CAM_READY) ++ stat |= DVB_CA_EN50221_POLL_CAM_READY; ++ return stat; + } + +-static void output_tasklet(unsigned long data) ++static struct dvb_ca_en50221 en_templ = { ++ .read_attribute_mem = read_attribute_mem, ++ .write_attribute_mem = write_attribute_mem, ++ .read_cam_control = read_cam_control, ++ .write_cam_control = write_cam_control, ++ .slot_reset = slot_reset, ++ .slot_shutdown = slot_shutdown, ++ .slot_ts_enable = slot_ts_enable, ++ .poll_slot_status = poll_slot_status, ++}; ++ ++static void ci_attach(struct ddb_port *port) + { +- struct ddb_output *output = (struct ddb_output *) data; +- struct ddb *dev = output->port->dev; ++ struct ddb_ci *ci = 0; + +- spin_lock(&output->lock); +- if (!output->running) { +- spin_unlock(&output->lock); ++ ci = kzalloc(sizeof(*ci), GFP_KERNEL); ++ if (!ci) + return; +- } +- output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); +- wake_up(&output->wq); +- spin_unlock(&output->lock); ++ memcpy(&ci->en, &en_templ, sizeof(en_templ)); ++ ci->en.data = ci; ++ port->en = &ci->en; ++ ci->port = port; ++ ci->nr = port->nr - 2; + } + ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ + +-static struct cxd2099_cfg cxd_cfg = { +- .bitrate = 62000, ++struct cxd2099_cfg cxd_cfg = { ++ .bitrate = 72000, + .adr = 0x40, + .polarity = 1, + .clock_mode = 1, +@@ -1045,28 +2163,21 @@ static struct cxd2099_cfg cxd_cfg = { + + static int ddb_ci_attach(struct ddb_port *port) + { +- int ret; +- +- ret = dvb_register_adapter(&port->output->adap, +- "DDBridge", +- THIS_MODULE, +- &port->dev->pdev->dev, +- adapter_nr); +- if (ret < 0) +- return ret; +- port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); +- if (!port->en) { +- dvb_unregister_adapter(&port->output->adap); +- return -ENODEV; ++ if (port->type == DDB_CI_EXTERNAL_SONY) { ++ cxd_cfg.bitrate = ci_bitrate; ++ port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); ++ if (!port->en) ++ return -ENODEV; ++ dvb_ca_en50221_init(port->dvb[0].adap, ++ port->en, 0, 1); + } +- ddb_input_start(port->input[0]); +- ddb_output_start(port->output); +- dvb_ca_en50221_init(&port->output->adap, +- port->en, 0, 1); +- ret = dvb_register_device(&port->output->adap, &port->output->dev, +- &dvbdev_ci, (void *) port->output, +- DVB_DEVICE_SEC); +- return ret; ++ if (port->type == DDB_CI_INTERNAL) { ++ ci_attach(port); ++ if (!port->en) ++ return -ENODEV; ++ dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); ++ } ++ return 0; + } + + static int ddb_port_attach(struct ddb_port *port) +@@ -1079,15 +2190,32 @@ static int ddb_port_attach(struct ddb_port *port) + if (ret < 0) + break; + ret = dvb_input_attach(port->input[1]); ++ if (ret < 0) ++ break; ++ port->input[0]->redi = port->input[0]; ++ port->input[1]->redi = port->input[1]; + break; + case DDB_PORT_CI: + ret = ddb_ci_attach(port); ++ if (ret < 0) ++ break; ++ case DDB_PORT_LOOP: ++ ret = dvb_register_device(port->dvb[0].adap, ++ &port->dvb[0].dev, ++ &dvbdev_ci, (void *) port->output, ++ DVB_DEVICE_CI); ++ break; ++ case DDB_PORT_MOD: ++ ret = dvb_register_device(port->dvb[0].adap, ++ &port->dvb[0].dev, ++ &dvbdev_mod, (void *) port->output, ++ DVB_DEVICE_MOD); + break; + default: + break; + } + if (ret < 0) +- printk(KERN_ERR "port_attach on port %d failed\n", port->nr); ++ pr_err("port_attach on port %d failed\n", port->nr); + return ret; + } + +@@ -1096,6 +2224,21 @@ static int ddb_ports_attach(struct ddb *dev) + int i, ret = 0; + struct ddb_port *port; + ++ if (dev->ids.devid == 0x0301dd01) ++ dev->ns_num = 15; ++ else ++ dev->ns_num = dev->info->ns_num; ++ for (i = 0; i < dev->ns_num; i++) ++ dev->ns[i].nr = i; ++ pr_info("%d netstream channels\n", dev->ns_num); ++ ++ if (dev->info->port_num) { ++ ret = dvb_register_adapters(dev); ++ if (ret < 0) { ++ pr_err("Registering adapters failed. Check DVB_MAX_ADAPTERS in config.\n"); ++ return ret; ++ } ++ } + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + ret = ddb_port_attach(port); +@@ -1112,124 +2255,259 @@ static void ddb_ports_detach(struct ddb *dev) + + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; ++ + switch (port->class) { + case DDB_PORT_TUNER: + dvb_input_detach(port->input[0]); + dvb_input_detach(port->input[1]); + break; + case DDB_PORT_CI: +- dvb_unregister_device(port->output->dev); ++ case DDB_PORT_LOOP: ++ if (port->dvb[0].dev) ++ dvb_unregister_device(port->dvb[0].dev); + if (port->en) { +- ddb_input_stop(port->input[0]); +- ddb_output_stop(port->output); + dvb_ca_en50221_release(port->en); + kfree(port->en); +- port->en = NULL; +- dvb_unregister_adapter(&port->output->adap); ++ port->en = 0; + } + break; ++ case DDB_PORT_MOD: ++ if (port->dvb[0].dev) ++ dvb_unregister_device(port->dvb[0].dev); ++ break; + } + } ++ dvb_unregister_adapters(dev); + } + +-/****************************************************************************/ +-/****************************************************************************/ + +-static int port_has_ci(struct ddb_port *port) ++/* Copy input DMA pointers to output DMA and ACK. */ ++ ++static void input_write_output(struct ddb_input *input, ++ struct ddb_output *output) + { +- u8 val; +- return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; ++ ddbwritel(output->port->dev, ++ input->dma->stat, DMA_BUFFER_ACK(output->dma->nr)); ++ output->dma->cbuf = (input->dma->stat >> 11) & 0x1f; ++ output->dma->coff = (input->dma->stat & 0x7ff) << 7; + } + +-static int port_has_stv0900(struct ddb_port *port) ++static void output_ack_input(struct ddb_output *output, ++ struct ddb_input *input) + { +- u8 val; +- if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) +- return 0; +- return 1; ++ ddbwritel(input->port->dev, ++ output->dma->stat, DMA_BUFFER_ACK(input->dma->nr)); + } + +-static int port_has_stv0900_aa(struct ddb_port *port) ++static void input_write_dvb(struct ddb_input *input, ++ struct ddb_input *input2) + { +- u8 val; +- if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) +- return 0; +- return 1; ++ struct ddb_dvb *dvb = &input2->port->dvb[input2->nr & 1]; ++ struct ddb_dma *dma, *dma2; ++ struct ddb *dev = input->port->dev; ++ int noack = 0; ++ ++ dma = dma2 = input->dma; ++ /* if there also is an output connected, do not ACK. ++ input_write_output will ACK. */ ++ if (input->redo) { ++ dma2 = input->redo->dma; ++ noack = 1; ++ } ++ while (dma->cbuf != ((dma->stat >> 11) & 0x1f) ++ || (4 & dma->ctrl)) { ++ if (4 & dma->ctrl) { ++ /*pr_err("Overflow dma %d\n", dma->nr);*/ ++ if (noack) ++ noack = 0; ++ } ++#ifdef DDB_ALT_DMA ++ dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf], ++ dma2->size, DMA_FROM_DEVICE); ++#endif ++ dvb_dmx_swfilter_packets(&dvb->demux, ++ dma2->vbuf[dma->cbuf], ++ dma2->size / 188); ++ dma->cbuf = (dma->cbuf + 1) % dma2->num; ++ if (!noack) ++ ddbwritel(dev, (dma->cbuf << 11), ++ DMA_BUFFER_ACK(dma->nr)); ++ dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr)); ++ dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr)); ++ } + } + +-static int port_has_drxks(struct ddb_port *port) ++#ifdef DDB_USE_WORK ++static void input_work(struct work_struct *work) + { +- u8 val; +- if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) +- return 0; +- if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) +- return 0; +- return 1; ++ struct ddb_dma *dma = container_of(work, struct ddb_dma, work); ++ struct ddb_input *input = (struct ddb_input *) dma->io; ++#else ++static void input_tasklet(unsigned long data) ++{ ++ struct ddb_input *input = (struct ddb_input *) data; ++ struct ddb_dma *dma = input->dma; ++#endif ++ struct ddb *dev = input->port->dev; ++ ++ spin_lock(&dma->lock); ++ if (!dma->running) { ++ spin_unlock(&dma->lock); ++ return; ++ } ++ dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr)); ++ dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr)); ++ ++#if 0 ++ if (4 & dma->ctrl) ++ pr_err("Overflow dma %d\n", dma->nr); ++#endif ++ if (input->redi) ++ input_write_dvb(input, input->redi); ++ if (input->redo) ++ input_write_output(input, input->redo); ++ wake_up(&dma->wq); ++ spin_unlock(&dma->lock); + } + +-static void ddb_port_probe(struct ddb_port *port) ++static void input_handler(unsigned long data) + { +- struct ddb *dev = port->dev; +- char *modname = "NO MODULE"; ++ struct ddb_input *input = (struct ddb_input *) data; ++ struct ddb_dma *dma = input->dma; + +- port->class = DDB_PORT_NONE; + +- if (port_has_ci(port)) { +- modname = "CI"; +- port->class = DDB_PORT_CI; +- ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); +- } else if (port_has_stv0900(port)) { +- modname = "DUAL DVB-S2"; +- port->class = DDB_PORT_TUNER; +- port->type = DDB_TUNER_DVBS_ST; +- ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); +- } else if (port_has_stv0900_aa(port)) { +- modname = "DUAL DVB-S2"; +- port->class = DDB_PORT_TUNER; +- port->type = DDB_TUNER_DVBS_ST_AA; +- ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); +- } else if (port_has_drxks(port)) { +- modname = "DUAL DVB-C/T"; +- port->class = DDB_PORT_TUNER; +- port->type = DDB_TUNER_DVBCT_TR; +- ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ /* If there is no input connected, input_tasklet() will ++ just copy pointers and ACK. So, there is no need to go ++ through the tasklet scheduler. */ ++#ifdef DDB_USE_WORK ++ if (input->redi) ++ queue_work(ddb_wq, &dma->work); ++ else ++ input_work(&dma->work); ++#else ++ if (input->redi) ++ tasklet_schedule(&dma->tasklet); ++ else ++ input_tasklet(data); ++#endif ++} ++ ++/* hmm, don't really need this anymore. ++ The output IRQ just copies some pointers, acks and wakes. */ ++ ++#ifdef DDB_USE_WORK ++static void output_work(struct work_struct *work) ++{ ++} ++#else ++static void output_tasklet(unsigned long data) ++{ ++} ++#endif ++ ++static void output_handler(unsigned long data) ++{ ++ struct ddb_output *output = (struct ddb_output *) data; ++ struct ddb_dma *dma = output->dma; ++ struct ddb *dev = output->port->dev; ++ ++ spin_lock(&dma->lock); ++ if (!dma->running) { ++ spin_unlock(&dma->lock); ++ return; ++ } ++ dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr)); ++ dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr)); ++ if (output->redi) ++ output_ack_input(output, output->redi); ++ wake_up(&dma->wq); ++ spin_unlock(&dma->lock); ++} ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++ ++static void ddb_dma_init(struct ddb_dma *dma, int nr, void *io, int out) ++{ ++#ifndef DDB_USE_WORK ++ unsigned long priv = (unsigned long) io; ++#endif ++ ++ dma->io = io; ++ dma->nr = nr; ++ spin_lock_init(&dma->lock); ++ init_waitqueue_head(&dma->wq); ++ if (out) { ++#ifdef DDB_USE_WORK ++ INIT_WORK(&dma->work, output_work); ++#else ++ tasklet_init(&dma->tasklet, output_tasklet, priv); ++#endif ++ dma->num = OUTPUT_DMA_BUFS; ++ dma->size = OUTPUT_DMA_SIZE; ++ dma->div = OUTPUT_DMA_IRQ_DIV; ++ } else { ++#ifdef DDB_USE_WORK ++ INIT_WORK(&dma->work, input_work); ++#else ++ tasklet_init(&dma->tasklet, input_tasklet, priv); ++#endif ++ dma->num = INPUT_DMA_BUFS; ++ dma->size = INPUT_DMA_SIZE; ++ dma->div = INPUT_DMA_IRQ_DIV; + } +- printk(KERN_INFO "Port %d (TAB %d): %s\n", +- port->nr, port->nr+1, modname); + } + +-static void ddb_input_init(struct ddb_port *port, int nr) ++static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int dma_nr) + { + struct ddb *dev = port->dev; + struct ddb_input *input = &dev->input[nr]; + ++ if (dev->has_dma) { ++ dev->handler[dma_nr + 8] = input_handler; ++ dev->handler_data[dma_nr + 8] = (unsigned long) input; ++ } ++ port->input[pnr] = input; + input->nr = nr; + input->port = port; +- input->dma_buf_num = INPUT_DMA_BUFS; +- input->dma_buf_size = INPUT_DMA_SIZE; +- ddbwritel(0, TS_INPUT_CONTROL(nr)); +- ddbwritel(2, TS_INPUT_CONTROL(nr)); +- ddbwritel(0, TS_INPUT_CONTROL(nr)); +- ddbwritel(0, DMA_BUFFER_ACK(nr)); +- tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input); +- spin_lock_init(&input->lock); +- init_waitqueue_head(&input->wq); ++ if (dev->has_dma) { ++ input->dma = &dev->dma[dma_nr]; ++ ddb_dma_init(input->dma, dma_nr, (void *) input, 0); ++ } ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(nr)); ++ ddbwritel(dev, 2, TS_INPUT_CONTROL(nr)); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(nr)); ++ if (dev->has_dma) ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma->nr)); + } + +-static void ddb_output_init(struct ddb_port *port, int nr) ++static void ddb_output_init(struct ddb_port *port, int nr, int dma_nr) + { + struct ddb *dev = port->dev; + struct ddb_output *output = &dev->output[nr]; ++ ++ if (dev->has_dma) { ++ dev->handler[dma_nr + 8] = output_handler; ++ dev->handler_data[dma_nr + 8] = (unsigned long) output; ++ } ++ port->output = output; + output->nr = nr; + output->port = port; +- output->dma_buf_num = OUTPUT_DMA_BUFS; +- output->dma_buf_size = OUTPUT_DMA_SIZE; +- +- ddbwritel(0, TS_OUTPUT_CONTROL(nr)); +- ddbwritel(2, TS_OUTPUT_CONTROL(nr)); +- ddbwritel(0, TS_OUTPUT_CONTROL(nr)); +- tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output); +- init_waitqueue_head(&output->wq); ++ if (dev->has_dma) { ++ output->dma = &dev->dma[dma_nr]; ++ ddb_dma_init(output->dma, dma_nr, (void *) output, 1); ++ } ++ if (output->port->class == DDB_PORT_MOD) { ++ /*ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));*/ ++ } else { ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(nr)); ++ ddbwritel(dev, 2, TS_OUTPUT_CONTROL(nr)); ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(nr)); ++ } ++ if (dev->has_dma) ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma->nr)); + } + + static void ddb_ports_init(struct ddb *dev) +@@ -1237,20 +2515,53 @@ static void ddb_ports_init(struct ddb *dev) + int i; + struct ddb_port *port; + ++ if (dev->info->board_control) { ++ ddbwritel(dev, 0, BOARD_CONTROL); ++ msleep(100); ++ ddbwritel(dev, 4, BOARD_CONTROL); ++ usleep_range(2000, 3000); ++ ddbwritel(dev, 4 | dev->info->board_control, BOARD_CONTROL); ++ usleep_range(2000, 3000); ++ } ++ + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + port->dev = dev; + port->nr = i; +- port->i2c = &dev->i2c[i]; +- port->input[0] = &dev->input[2 * i]; +- port->input[1] = &dev->input[2 * i + 1]; +- port->output = &dev->output[i]; +- ++ if (dev->info->i2c_num > i) ++ port->i2c = &dev->i2c[i]; ++ port->gap = 4; ++ port->obr = ci_bitrate; + mutex_init(&port->i2c_gate_lock); + ddb_port_probe(port); +- ddb_input_init(port, 2 * i); +- ddb_input_init(port, 2 * i + 1); +- ddb_output_init(port, i); ++ pr_info("Port %d (TAB %d): %s\n", ++ port->nr, port->nr + 1, port->name); ++ ++ port->dvb[0].adap = &dev->adap[2 * i]; ++ port->dvb[1].adap = &dev->adap[2 * i + 1]; ++ ++ if ((dev->info->type == DDB_OCTOPUS_CI) || ++ (dev->info->type == DDB_OCTONET) || ++ (dev->info->type == DDB_OCTOPUS)) { ++ if (i >= 2 && dev->info->type == DDB_OCTOPUS_CI) { ++ ddb_input_init(port, 2 + i, 0, 2 + i); ++ ddb_input_init(port, 4 + i, 1, 4 + i); ++ } else { ++ ddb_input_init(port, 2 * i, 0, 2 * i); ++ ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); ++ } ++ ddb_output_init(port, i, i + 8); ++ } ++ if (dev->info->type == DDB_OCTOPUS_MAX) { ++ ddb_input_init(port, 2 * i, 0, 2 * i); ++ ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); ++ } ++ if (dev->info->type == DDB_MOD) { ++ ddb_output_init(port, i, i); ++ dev->handler[i + 18] = ddbridge_mod_rate_handler; ++ dev->handler_data[i + 18] = ++ (unsigned long) &dev->output[i]; ++ } + } + } + +@@ -1259,12 +2570,25 @@ static void ddb_ports_release(struct ddb *dev) + int i; + struct ddb_port *port; + ++ if (!dev->has_dma) ++ return; + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; +- port->dev = dev; +- tasklet_kill(&port->input[0]->tasklet); +- tasklet_kill(&port->input[1]->tasklet); +- tasklet_kill(&port->output->tasklet); ++#ifdef DDB_USE_WORK ++ if (port->input[0]) ++ cancel_work_sync(&port->input[0]->dma->work); ++ if (port->input[1]) ++ cancel_work_sync(&port->input[1]->dma->work); ++ if (port->output) ++ cancel_work_sync(&port->output->dma->work); ++#else ++ if (port->input[0]) ++ tasklet_kill(&port->input[0]->dma->tasklet); ++ if (port->input[1]) ++ tasklet_kill(&port->input[1]->dma->tasklet); ++ if (port->output) ++ tasklet_kill(&port->output->dma->tasklet); ++#endif + } + } + +@@ -1272,90 +2596,306 @@ static void ddb_ports_release(struct ddb *dev) + /****************************************************************************/ + /****************************************************************************/ + +-static void irq_handle_i2c(struct ddb *dev, int n) ++#define IRQ_HANDLE(_nr) \ ++ do { if ((s & (1UL << _nr)) && dev->handler[_nr]) \ ++ dev->handler[_nr](dev->handler_data[_nr]); } \ ++ while (0) ++ ++static void irq_handle_msg(struct ddb *dev, u32 s) ++{ ++ dev->i2c_irq++; ++ IRQ_HANDLE(0); ++ IRQ_HANDLE(1); ++ IRQ_HANDLE(2); ++ IRQ_HANDLE(3); ++} ++ ++static void irq_handle_io(struct ddb *dev, u32 s) ++{ ++ dev->ts_irq++; ++ IRQ_HANDLE(8); ++ IRQ_HANDLE(9); ++ IRQ_HANDLE(10); ++ IRQ_HANDLE(11); ++ IRQ_HANDLE(12); ++ IRQ_HANDLE(13); ++ IRQ_HANDLE(14); ++ IRQ_HANDLE(15); ++ IRQ_HANDLE(16); ++ IRQ_HANDLE(17); ++ IRQ_HANDLE(18); ++ IRQ_HANDLE(19); ++ if (dev->info->type != DDB_MOD) ++ return; ++ IRQ_HANDLE(20); ++ IRQ_HANDLE(21); ++ IRQ_HANDLE(22); ++ IRQ_HANDLE(23); ++ IRQ_HANDLE(24); ++ IRQ_HANDLE(25); ++ IRQ_HANDLE(26); ++ IRQ_HANDLE(27); ++} ++ ++static irqreturn_t irq_handler0(int irq, void *dev_id) + { +- struct ddb_i2c *i2c = &dev->i2c[n]; ++ struct ddb *dev = (struct ddb *) dev_id; ++ u32 s = ddbreadl(dev, INTERRUPT_STATUS); ++ ++ do { ++ if (s & 0x80000000) ++ return IRQ_NONE; ++ if (!(s & 0xfff00)) ++ return IRQ_NONE; ++ ddbwritel(dev, s, INTERRUPT_ACK); ++ irq_handle_io(dev, s); ++ } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t irq_handler1(int irq, void *dev_id) ++{ ++ struct ddb *dev = (struct ddb *) dev_id; ++ u32 s = ddbreadl(dev, INTERRUPT_STATUS); ++ ++ do { ++ if (s & 0x80000000) ++ return IRQ_NONE; ++ if (!(s & 0x0000f)) ++ return IRQ_NONE; ++ ddbwritel(dev, s, INTERRUPT_ACK); ++ irq_handle_msg(dev, s); ++ } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); + +- i2c->done = 1; +- wake_up(&i2c->wq); ++ return IRQ_HANDLED; + } + + static irqreturn_t irq_handler(int irq, void *dev_id) + { + struct ddb *dev = (struct ddb *) dev_id; +- u32 s = ddbreadl(INTERRUPT_STATUS); ++ u32 s = ddbreadl(dev, INTERRUPT_STATUS); ++ int ret = IRQ_HANDLED; + + if (!s) + return IRQ_NONE; +- + do { +- ddbwritel(s, INTERRUPT_ACK); +- +- if (s & 0x00000001) +- irq_handle_i2c(dev, 0); +- if (s & 0x00000002) +- irq_handle_i2c(dev, 1); +- if (s & 0x00000004) +- irq_handle_i2c(dev, 2); +- if (s & 0x00000008) +- irq_handle_i2c(dev, 3); +- +- if (s & 0x00000100) +- tasklet_schedule(&dev->input[0].tasklet); +- if (s & 0x00000200) +- tasklet_schedule(&dev->input[1].tasklet); +- if (s & 0x00000400) +- tasklet_schedule(&dev->input[2].tasklet); +- if (s & 0x00000800) +- tasklet_schedule(&dev->input[3].tasklet); +- if (s & 0x00001000) +- tasklet_schedule(&dev->input[4].tasklet); +- if (s & 0x00002000) +- tasklet_schedule(&dev->input[5].tasklet); +- if (s & 0x00004000) +- tasklet_schedule(&dev->input[6].tasklet); +- if (s & 0x00008000) +- tasklet_schedule(&dev->input[7].tasklet); +- +- if (s & 0x00010000) +- tasklet_schedule(&dev->output[0].tasklet); +- if (s & 0x00020000) +- tasklet_schedule(&dev->output[1].tasklet); +- if (s & 0x00040000) +- tasklet_schedule(&dev->output[2].tasklet); +- if (s & 0x00080000) +- tasklet_schedule(&dev->output[3].tasklet); +- +- /* if (s & 0x000f0000) printk(KERN_DEBUG "%08x\n", istat); */ +- } while ((s = ddbreadl(INTERRUPT_STATUS))); ++ if (s & 0x80000000) ++ return IRQ_NONE; ++ ddbwritel(dev, s, INTERRUPT_ACK); ++ ++ if (s & 0x0000000f) ++ irq_handle_msg(dev, s); ++ if (s & 0x0fffff00) { ++ irq_handle_io(dev, s); ++#ifdef DDB_TEST_THREADED ++ ret = IRQ_WAKE_THREAD; ++#endif ++ } ++ } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); ++ ++ return ret; ++} ++ ++#ifdef DDB_TEST_THREADED ++static irqreturn_t irq_thread(int irq, void *dev_id) ++{ ++ /* struct ddb *dev = (struct ddb *) dev_id; */ ++ ++ /*pr_info("%s\n", __func__);*/ + + return IRQ_HANDLED; + } ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++#ifdef DVB_NSD ++ ++static ssize_t nsd_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ return 0; ++} + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++static unsigned int nsd_poll(struct file *file, poll_table *wait) ++{ ++ return 0; ++} ++ ++static int nsd_release(struct inode *inode, struct file *file) ++{ ++ return dvb_generic_release(inode, file); ++} ++ ++static int nsd_open(struct inode *inode, struct file *file) ++{ ++ return dvb_generic_open(inode, file); ++} ++ ++static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb *dev = dvbdev->priv; ++ ++ /* unsigned long arg = (unsigned long) parg; */ ++ int ret = 0; ++ ++ switch (cmd) { ++ case NSD_START_GET_TS: ++ { ++ struct dvb_nsd_ts *ts = parg; ++ u32 ctrl = ((ts->input & 7) << 8) | ++ ((ts->filter_mask & 3) << 2); ++ u32 to; ++ ++ if (ddbreadl(dev, TS_CAPTURE_CONTROL) & 1) { ++ pr_info("ts capture busy\n"); ++ return -EBUSY; ++ } ++ ddb_dvb_input_start(&dev->input[ts->input & 7]); ++ ++ ddbwritel(dev, ctrl, TS_CAPTURE_CONTROL); ++ ddbwritel(dev, ts->pid, TS_CAPTURE_PID); ++ ddbwritel(dev, (ts->section_id << 16) | ++ (ts->table << 8) | ts->section, ++ TS_CAPTURE_TABLESECTION); ++ /* 1024 ms default timeout if timeout set to 0 */ ++ if (ts->timeout) ++ to = ts->timeout; ++ else ++ to = 1024; ++ /* 21 packets default if num set to 0 */ ++ if (ts->num) ++ to |= ((u32) ts->num << 16); ++ else ++ to |= (21 << 16); ++ ddbwritel(dev, to, TS_CAPTURE_TIMEOUT); ++ if (ts->mode) ++ ctrl |= 2; ++ ddbwritel(dev, ctrl | 1, TS_CAPTURE_CONTROL); ++ break; ++ } ++ case NSD_POLL_GET_TS: ++ { ++ struct dvb_nsd_ts *ts = parg; ++ u32 ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); ++ ++ if (ctrl & 1) ++ return -EBUSY; ++ if (ctrl & (1 << 14)) { ++ /*pr_info("ts capture timeout\n");*/ ++ return -EAGAIN; ++ } ++ ddbcpyfrom(dev, dev->tsbuf, TS_CAPTURE_MEMORY, ++ TS_CAPTURE_LEN); ++ ts->len = ddbreadl(dev, TS_CAPTURE_RECEIVED) & 0x1fff; ++ if (copy_to_user(ts->ts, dev->tsbuf, ts->len)) ++ return -EIO; ++ break; ++ } ++ case NSD_CANCEL_GET_TS: ++ { ++ u32 ctrl = 0; ++ pr_info("cancel ts capture: 0x%x\n", ctrl); ++ ddbwritel(dev, ctrl, TS_CAPTURE_CONTROL); ++ ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); ++ /*pr_info("control register is 0x%x\n", ctrl);*/ ++ break; ++ } ++ case NSD_STOP_GET_TS: ++ { ++ struct dvb_nsd_ts *ts = parg; ++ u32 ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); ++ ++ if (ctrl & 1) { ++ pr_info("cannot stop ts capture, while it was neither finished not canceled\n"); ++ return -EBUSY; ++ } ++ /*pr_info("ts capture stopped\n");*/ ++ ddb_dvb_input_stop(&dev->input[ts->input & 7]); ++ break; ++ } ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static long nsd_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy(file, cmd, arg, nsd_do_ioctl); ++} ++ ++static const struct file_operations nsd_fops = { ++ .owner = THIS_MODULE, ++ .read = nsd_read, ++ .open = nsd_open, ++ .release = nsd_release, ++ .poll = nsd_poll, ++ .unlocked_ioctl = nsd_ioctl, ++}; ++ ++static struct dvb_device dvbdev_nsd = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 1, ++ .fops = &nsd_fops, ++}; ++ ++static int ddb_nsd_attach(struct ddb *dev) ++{ ++ int ret; ++ ++ ret = dvb_register_device(&dev->adap[0], ++ &dev->nsd_dev, ++ &dvbdev_nsd, (void *) dev, ++ DVB_DEVICE_NSD); ++ return ret; ++} ++ ++static void ddb_nsd_detach(struct ddb *dev) ++{ ++ if (dev->nsd_dev->users > 2) { ++ wait_event(dev->nsd_dev->wait_queue, ++ dev->nsd_dev->users == 2); ++ } ++ dvb_unregister_device(dev->nsd_dev); ++} ++ ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + + static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) + { + u32 data, shift; + + if (wlen > 4) +- ddbwritel(1, SPI_CONTROL); ++ ddbwritel(dev, 1, SPI_CONTROL); + while (wlen > 4) { + /* FIXME: check for big-endian */ + data = swab32(*(u32 *)wbuf); + wbuf += 4; + wlen -= 4; +- ddbwritel(data, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, data, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; + } + + if (rlen) +- ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); ++ ddbwritel(dev, 0x0001 | ((wlen << (8 + 3)) & 0x1f00), ++ SPI_CONTROL); + else +- ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); ++ ddbwritel(dev, 0x0003 | ((wlen << (8 + 3)) & 0x1f00), ++ SPI_CONTROL); + + data = 0; + shift = ((4 - wlen) * 8); +@@ -1367,33 +2907,33 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) + } + if (shift) + data <<= shift; +- ddbwritel(data, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, data, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; + + if (!rlen) { +- ddbwritel(0, SPI_CONTROL); ++ ddbwritel(dev, 0, SPI_CONTROL); + return 0; + } + if (rlen > 4) +- ddbwritel(1, SPI_CONTROL); ++ ddbwritel(dev, 1, SPI_CONTROL); + + while (rlen > 4) { +- ddbwritel(0xffffffff, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, 0xffffffff, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; +- data = ddbreadl(SPI_DATA); ++ data = ddbreadl(dev, SPI_DATA); + *(u32 *) rbuf = swab32(data); + rbuf += 4; + rlen -= 4; + } +- ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); +- ddbwritel(0xffffffff, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); ++ ddbwritel(dev, 0xffffffff, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; + +- data = ddbreadl(SPI_DATA); +- ddbwritel(0, SPI_CONTROL); ++ data = ddbreadl(dev, SPI_DATA); ++ ddbwritel(dev, 0, SPI_CONTROL); + + if (rlen < 4) + data <<= ((4 - rlen) * 8); +@@ -1407,28 +2947,107 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) + return 0; + } + ++int ddbridge_flashread(struct ddb *dev, u8 *buf, u32 addr, u32 len) ++{ ++ u8 cmd[4] = {0x03, (addr >> 16) & 0xff, ++ (addr >> 8) & 0xff, addr & 0xff}; ++ ++ return flashio(dev, cmd, 4, buf, len); ++} ++ ++static int mdio_write(struct ddb *dev, u8 adr, u8 reg, u16 val) ++{ ++ ddbwritel(dev, adr, MDIO_ADR); ++ ddbwritel(dev, reg, MDIO_REG); ++ ddbwritel(dev, val, MDIO_VAL); ++ ddbwritel(dev, 0x03, MDIO_CTRL); ++ while (ddbreadl(dev, MDIO_CTRL) & 0x02) ++ ndelay(500); ++ return 0; ++} ++ ++static u16 mdio_read(struct ddb *dev, u8 adr, u8 reg) ++{ ++ ddbwritel(dev, adr, MDIO_ADR); ++ ddbwritel(dev, reg, MDIO_REG); ++ ddbwritel(dev, 0x07, MDIO_CTRL); ++ while (ddbreadl(dev, MDIO_CTRL) & 0x02) ++ ndelay(500); ++ return ddbreadl(dev, MDIO_VAL); ++} ++ + #define DDB_MAGIC 'd' + + struct ddb_flashio { +- __user __u8 *write_buf; ++ __u8 *write_buf; + __u32 write_len; +- __user __u8 *read_buf; ++ __u8 *read_buf; + __u32 read_len; + }; + +-#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) ++struct ddb_gpio { ++ __u32 mask; ++ __u32 data; ++}; ++ ++struct ddb_id { ++ __u16 vendor; ++ __u16 device; ++ __u16 subvendor; ++ __u16 subdevice; ++ __u32 hw; ++ __u32 regmap; ++}; ++ ++struct ddb_reg { ++ __u32 reg; ++ __u32 val; ++}; ++ ++struct ddb_mem { ++ __u32 off; ++ __u8 *buf; ++ __u32 len; ++}; ++ ++struct ddb_mdio { ++ __u8 adr; ++ __u8 reg; ++ __u16 val; ++}; ++ ++#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) ++#define IOCTL_DDB_GPIO_IN _IOWR(DDB_MAGIC, 0x01, struct ddb_gpio) ++#define IOCTL_DDB_GPIO_OUT _IOWR(DDB_MAGIC, 0x02, struct ddb_gpio) ++#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id) ++#define IOCTL_DDB_READ_REG _IOWR(DDB_MAGIC, 0x04, struct ddb_reg) ++#define IOCTL_DDB_WRITE_REG _IOW(DDB_MAGIC, 0x05, struct ddb_reg) ++#define IOCTL_DDB_READ_MEM _IOWR(DDB_MAGIC, 0x06, struct ddb_mem) ++#define IOCTL_DDB_WRITE_MEM _IOR(DDB_MAGIC, 0x07, struct ddb_mem) ++#define IOCTL_DDB_READ_MDIO _IOWR(DDB_MAGIC, 0x08, struct ddb_mdio) ++#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio) + + #define DDB_NAME "ddbridge" + + static u32 ddb_num; +-static struct ddb *ddbs[32]; +-static struct class *ddb_class; + static int ddb_major; ++static DEFINE_MUTEX(ddb_mutex); ++ ++static int ddb_release(struct inode *inode, struct file *file) ++{ ++ struct ddb *dev = file->private_data; ++ ++ dev->ddb_dev_users--; ++ return 0; ++} + + static int ddb_open(struct inode *inode, struct file *file) + { + struct ddb *dev = ddbs[iminor(inode)]; + ++ if (dev->ddb_dev_users) ++ return -EBUSY; ++ dev->ddb_dev_users++; + file->private_data = dev; + return 0; + } +@@ -1436,7 +3055,7 @@ static int ddb_open(struct inode *inode, struct file *file) + static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + { + struct ddb *dev = file->private_data; +- __user void *parg = (__user void *)arg; ++ void *parg = (void *)arg; + int res; + + switch (cmd) { +@@ -1447,7 +3066,6 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + + if (copy_from_user(&fio, parg, sizeof(fio))) + return -EFAULT; +- + if (fio.write_len > 1028 || fio.read_len > 1028) + return -EINVAL; + if (fio.write_len + fio.read_len > 1028) +@@ -1465,6 +3083,107 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + return -EFAULT; + break; + } ++ case IOCTL_DDB_GPIO_OUT: ++ { ++ struct ddb_gpio gpio; ++ if (copy_from_user(&gpio, parg, sizeof(gpio))) ++ return -EFAULT; ++ ddbwritel(dev, gpio.mask, GPIO_DIRECTION); ++ ddbwritel(dev, gpio.data, GPIO_OUTPUT); ++ break; ++ } ++ case IOCTL_DDB_ID: ++ { ++ struct ddb_id ddbid; ++ ++ ddbid.vendor = dev->ids.vendor; ++ ddbid.device = dev->ids.device; ++ ddbid.subvendor = dev->ids.subvendor; ++ ddbid.subdevice = dev->ids.subdevice; ++ ddbid.hw = ddbreadl(dev, 0); ++ ddbid.regmap = ddbreadl(dev, 4); ++ if (copy_to_user(parg, &ddbid, sizeof(ddbid))) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_READ_REG: ++ { ++ struct ddb_reg reg; ++ ++ if (copy_from_user(®, parg, sizeof(reg))) ++ return -EFAULT; ++ if (reg.reg >= dev->regs_len) ++ return -EINVAL; ++ reg.val = ddbreadl(dev, reg.reg); ++ if (copy_to_user(parg, ®, sizeof(reg))) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_WRITE_REG: ++ { ++ struct ddb_reg reg; ++ ++ if (copy_from_user(®, parg, sizeof(reg))) ++ return -EFAULT; ++ if (reg.reg >= dev->regs_len) ++ return -EINVAL; ++ ddbwritel(dev, reg.val, reg.reg); ++ break; ++ } ++ case IOCTL_DDB_READ_MDIO: ++ { ++ struct ddb_mdio mdio; ++ ++ if (!dev->info->mdio_num) ++ return -EIO; ++ if (copy_from_user(&mdio, parg, sizeof(mdio))) ++ return -EFAULT; ++ mdio.val = mdio_read(dev, mdio.adr, mdio.reg); ++ if (copy_to_user(parg, &mdio, sizeof(mdio))) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_WRITE_MDIO: ++ { ++ struct ddb_mdio mdio; ++ ++ if (!dev->info->mdio_num) ++ return -EIO; ++ if (copy_from_user(&mdio, parg, sizeof(mdio))) ++ return -EFAULT; ++ mdio_write(dev, mdio.adr, mdio.reg, mdio.val); ++ break; ++ } ++ case IOCTL_DDB_READ_MEM: ++ { ++ struct ddb_mem mem; ++ u8 *buf = &dev->iobuf[0]; ++ ++ if (copy_from_user(&mem, parg, sizeof(mem))) ++ return -EFAULT; ++ if ((mem.len + mem.off > dev->regs_len) || ++ mem.len > 1024) ++ return -EINVAL; ++ ddbcpyfrom(dev, buf, mem.off, mem.len); ++ if (copy_to_user(mem.buf, buf, mem.len)) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_WRITE_MEM: ++ { ++ struct ddb_mem mem; ++ u8 *buf = &dev->iobuf[0]; ++ ++ if (copy_from_user(&mem, parg, sizeof(mem))) ++ return -EFAULT; ++ if ((mem.len + mem.off > dev->regs_len) || ++ mem.len > 1024) ++ return -EINVAL; ++ if (copy_from_user(buf, mem.buf, mem.len)) ++ return -EFAULT; ++ ddbcpyto(dev, mem.off, buf, mem.len); ++ break; ++ } + default: + return -ENOTTY; + } +@@ -1474,284 +3193,508 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + static const struct file_operations ddb_fops = { + .unlocked_ioctl = ddb_ioctl, + .open = ddb_open, ++ .release = ddb_release, + }; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) ++static char *ddb_devnode(struct device *device, mode_t *mode) ++#else + static char *ddb_devnode(struct device *device, umode_t *mode) ++#endif + { + struct ddb *dev = dev_get_drvdata(device); + + return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); + } + +-static int ddb_class_create(void) +-{ +- ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); +- if (ddb_major < 0) +- return ddb_major; ++#define __ATTR_MRO(_name, _show) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = _show, \ ++} + +- ddb_class = class_create(THIS_MODULE, DDB_NAME); +- if (IS_ERR(ddb_class)) { +- unregister_chrdev(ddb_major, DDB_NAME); +- return PTR_ERR(ddb_class); +- } +- ddb_class->devnode = ddb_devnode; +- return 0; ++#define __ATTR_MWO(_name, _store) { \ ++ .attr = { .name = __stringify(_name), .mode = 0222 }, \ ++ .store = _store, \ + } + +-static void ddb_class_destroy(void) ++static ssize_t ports_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- class_destroy(ddb_class); +- unregister_chrdev(ddb_major, DDB_NAME); ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "%d\n", dev->info->port_num); + } + +-static int ddb_device_create(struct ddb *dev) ++static ssize_t ts_irq_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- dev->nr = ddb_num++; +- dev->ddb_dev = device_create(ddb_class, NULL, +- MKDEV(ddb_major, dev->nr), +- dev, "ddbridge%d", dev->nr); +- ddbs[dev->nr] = dev; +- if (IS_ERR(dev->ddb_dev)) +- return -1; +- return 0; ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "%d\n", dev->ts_irq); + } + +-static void ddb_device_destroy(struct ddb *dev) ++static ssize_t i2c_irq_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- ddb_num--; +- if (IS_ERR(dev->ddb_dev)) +- return; +- device_destroy(ddb_class, MKDEV(ddb_major, 0)); ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "%d\n", dev->i2c_irq); + } + ++static char *class_name[] = { ++ "NONE", "CI", "TUNER", "LOOP" ++}; + +-/****************************************************************************/ +-/****************************************************************************/ +-/****************************************************************************/ ++static char *type_name[] = { ++ "NONE", "DVBS_ST", "DVBS_ST_AA", "DVBCT_TR", ++ "DVBCT_ST", "INTERNAL", "CXD2099", "TYPE07", ++ "TYPE08", "TYPE09", "TYPE0A", "TYPE0B", ++ "TYPE0C", "TYPE0D", "TYPE0E", "TYPE0F", ++ "DVBS", "DVBCT2_SONY", "ISDBT_SONY", "DVBC2T2_SONY", ++ "ATSC_ST", "DVBC2T2_ST" ++}; + +-static void ddb_unmap(struct ddb *dev) ++static ssize_t fan_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- if (dev->regs) +- iounmap(dev->regs); +- vfree(dev); ++ struct ddb *dev = dev_get_drvdata(device); ++ u32 val; ++ ++ val = ddbreadl(dev, GPIO_OUTPUT) & 1; ++ return sprintf(buf, "%d\n", val); + } + ++static ssize_t fan_store(struct device *device, struct device_attribute *d, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ unsigned val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ ddbwritel(dev, 1, GPIO_DIRECTION); ++ ddbwritel(dev, val & 1, GPIO_OUTPUT); ++ return count; ++} + +-static void ddb_remove(struct pci_dev *pdev) ++static ssize_t temp_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- struct ddb *dev = pci_get_drvdata(pdev); ++ struct ddb *dev = dev_get_drvdata(device); ++ struct i2c_adapter *adap; ++ int temp, temp2, temp3, i; ++ u8 tmp[2]; + +- ddb_ports_detach(dev); +- ddb_i2c_release(dev); ++ if (dev->info->type == DDB_MOD) { ++ ddbwritel(dev, 1, TEMPMON_CONTROL); ++ for (i = 0; i < 10; i++) { ++ if (0 == (1 & ddbreadl(dev, TEMPMON_CONTROL))) ++ break; ++ usleep_range(1000, 2000); ++ } ++ temp = ddbreadl(dev, TEMPMON_SENSOR1); ++ temp2 = ddbreadl(dev, TEMPMON_SENSOR2); ++ temp = (temp * 1000) >> 8; ++ temp2 = (temp2 * 1000) >> 8; ++ if (ddbreadl(dev, TEMPMON_CONTROL) & 0x8000) { ++ temp3 = ddbreadl(dev, TEMPMON_CORE); ++ temp3 = (temp3 * 1000) >> 8; ++ return sprintf(buf, "%d %d %d\n", temp, temp2, temp3); ++ } ++ return sprintf(buf, "%d %d\n", temp, temp2); ++ } ++ if (!dev->info->temp_num) ++ return sprintf(buf, "no sensor\n"); ++ adap = &dev->i2c[dev->info->temp_bus].adap; ++ if (i2c_read_regs(adap, 0x48, 0, tmp, 2) < 0) ++ return sprintf(buf, "read_error\n"); ++ temp = (tmp[0] << 3) | (tmp[1] >> 5); ++ temp *= 125; ++ if (dev->info->temp_num == 2) { ++ if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0) ++ return sprintf(buf, "read_error\n"); ++ temp2 = (tmp[0] << 3) | (tmp[1] >> 5); ++ temp2 *= 125; ++ return sprintf(buf, "%d %d\n", temp, temp2); ++ } ++ return sprintf(buf, "%d\n", temp); ++} + +- ddbwritel(0, INTERRUPT_ENABLE); +- free_irq(dev->pdev->irq, dev); +-#ifdef CONFIG_PCI_MSI +- if (dev->msi) +- pci_disable_msi(dev->pdev); +-#endif +- ddb_ports_release(dev); +- ddb_buffers_free(dev); +- ddb_device_destroy(dev); ++#if 0 ++static ssize_t qam_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ struct i2c_adapter *adap; ++ u8 tmp[4]; ++ s16 i, q; + +- ddb_unmap(dev); +- pci_set_drvdata(pdev, NULL); +- pci_disable_device(pdev); ++ adap = &dev->i2c[1].adap; ++ if (i2c_read_regs16(adap, 0x1f, 0xf480, tmp, 4) < 0) ++ return sprintf(buf, "read_error\n"); ++ i = (s16) (((u16) tmp[1]) << 14) | (((u16) tmp[0]) << 6); ++ q = (s16) (((u16) tmp[3]) << 14) | (((u16) tmp[2]) << 6); ++ ++ return sprintf(buf, "%d %d\n", i, q); + } ++#endif ++ ++static ssize_t mod_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; + ++ return sprintf(buf, "%s:%s\n", ++ class_name[dev->port[num].class], ++ type_name[dev->port[num].type]); ++} + +-static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id) ++static ssize_t led_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- struct ddb *dev; +- int stat = 0; +- int irq_flag = IRQF_SHARED; ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; + +- if (pci_enable_device(pdev) < 0) +- return -ENODEV; ++ return sprintf(buf, "%d\n", dev->leds & (1 << num) ? 1 : 0); ++} + +- dev = vmalloc(sizeof(struct ddb)); +- if (dev == NULL) +- return -ENOMEM; +- memset(dev, 0, sizeof(struct ddb)); + +- dev->pdev = pdev; +- pci_set_drvdata(pdev, dev); +- dev->info = (struct ddb_info *) id->driver_data; +- printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name); ++static void ddb_set_led(struct ddb *dev, int num, int val) ++{ ++ if (!dev->info->led_num) ++ return; ++ switch (dev->port[num].class) { ++ case DDB_PORT_TUNER: ++ switch (dev->port[num].type) { ++ case DDB_TUNER_DVBS_ST: ++ i2c_write_reg16(&dev->i2c[num].adap, ++ 0x69, 0xf14c, val ? 2 : 0); ++ break; ++ case DDB_TUNER_DVBCT_ST: ++ i2c_write_reg16(&dev->i2c[num].adap, ++ 0x1f, 0xf00e, 0); ++ i2c_write_reg16(&dev->i2c[num].adap, ++ 0x1f, 0xf00f, val ? 1 : 0); ++ break; ++ case DDB_TUNER_XO2 ... DDB_TUNER_DVBC2T2_ST: ++ { ++ u8 v; + +- dev->regs = ioremap(pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0)); +- if (!dev->regs) { +- stat = -ENOMEM; +- goto fail; ++ i2c_read_reg(&dev->i2c[num].adap, 0x10, 0x08, &v); ++ v = (v & ~0x10) | (val ? 0x10 : 0); ++ i2c_write_reg(&dev->i2c[num].adap, 0x10, 0x08, v); ++ break; ++ } ++ default: ++ break; ++ } ++ break; + } +- printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); ++} ++ ++static ssize_t led_store(struct device *device, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; ++ unsigned val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ if (val) ++ dev->leds |= (1 << num); ++ else ++ dev->leds &= ~(1 << num); ++ ddb_set_led(dev, num, val); ++ return count; ++} ++ ++static ssize_t snr_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ char snr[32]; ++ int num = attr->attr.name[3] - 0x30; + +-#ifdef CONFIG_PCI_MSI +- if (pci_msi_enabled()) +- stat = pci_enable_msi(dev->pdev); +- if (stat) { +- printk(KERN_INFO ": MSI not available.\n"); ++ if (dev->port[num].type >= DDB_TUNER_XO2) { ++ if (i2c_read_regs(&dev->i2c[num].adap, 0x10, 0x10, snr, 16) < 0) ++ return sprintf(buf, "NO SNR\n"); ++ snr[16] = 0; + } else { +- irq_flag = 0; +- dev->msi = 1; ++ /* serial number at 0x100-0x11f */ ++ if (i2c_read_regs16(&dev->i2c[num].adap, ++ 0x50, 0x100, snr, 32) < 0) ++ if (i2c_read_regs16(&dev->i2c[num].adap, ++ 0x57, 0x100, snr, 32) < 0) ++ return sprintf(buf, "NO SNR\n"); ++ snr[31] = 0; /* in case it is not terminated on EEPROM */ + } +-#endif +- stat = request_irq(dev->pdev->irq, irq_handler, +- irq_flag, "DDBridge", (void *) dev); +- if (stat < 0) +- goto fail1; +- ddbwritel(0, DMA_BASE_WRITE); +- ddbwritel(0, DMA_BASE_READ); +- ddbwritel(0xffffffff, INTERRUPT_ACK); +- ddbwritel(0xfff0f, INTERRUPT_ENABLE); +- ddbwritel(0, MSI1_ENABLE); +- +- if (ddb_i2c_init(dev) < 0) +- goto fail1; +- ddb_ports_init(dev); +- if (ddb_buffers_alloc(dev) < 0) { +- printk(KERN_INFO ": Could not allocate buffer memory\n"); +- goto fail2; +- } +- if (ddb_ports_attach(dev) < 0) +- goto fail3; +- ddb_device_create(dev); ++ return sprintf(buf, "%s\n", snr); ++} ++ ++ ++static ssize_t snr_store(struct device *device, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; ++ u8 snr[34] = { 0x01, 0x00 }; ++ ++ if (count > 31) ++ return -EINVAL; ++ if (dev->port[num].type >= DDB_TUNER_XO2) ++ return -EINVAL; ++ memcpy(snr + 2, buf, count); ++ i2c_write(&dev->i2c[num].adap, 0x57, snr, 34); ++ i2c_write(&dev->i2c[num].adap, 0x50, snr, 34); ++ return count; ++} ++ ++static ssize_t bsnr_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ char snr[16]; ++ ++ ddbridge_flashread(dev, snr, 0x10, 15); ++ snr[15] = 0; /* in case it is not terminated on EEPROM */ ++ return sprintf(buf, "%s\n", snr); ++} ++ ++static ssize_t redirect_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ + return 0; ++} + +-fail3: +- ddb_ports_detach(dev); +- printk(KERN_ERR "fail3\n"); +- ddb_ports_release(dev); +-fail2: +- printk(KERN_ERR "fail2\n"); +- ddb_buffers_free(dev); +-fail1: +- printk(KERN_ERR "fail1\n"); +- if (dev->msi) +- pci_disable_msi(dev->pdev); +- free_irq(dev->pdev->irq, dev); +-fail: +- printk(KERN_ERR "fail\n"); +- ddb_unmap(dev); +- pci_set_drvdata(pdev, NULL); +- pci_disable_device(pdev); +- return -1; ++static ssize_t redirect_store(struct device *device, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned int i, p; ++ int res; ++ ++ if (sscanf(buf, "%x %x\n", &i, &p) != 2) ++ return -EINVAL; ++ res = ddb_redirect(i, p); ++ if (res < 0) ++ return res; ++ pr_info("redirect: %02x, %02x\n", i, p); ++ return count; + } + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++static ssize_t gap_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; + +-static struct ddb_info ddb_none = { +- .type = DDB_NONE, +- .name = "Digital Devices PCIe bridge", +-}; ++ return sprintf(buf, "%d\n", dev->port[num].gap); + +-static struct ddb_info ddb_octopus = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus DVB adapter", +- .port_num = 4, +-}; ++} ++static ssize_t gap_store(struct device *device, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; ++ unsigned int val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ if (val > 20) ++ return -EINVAL; ++ dev->port[num].gap = val; ++ return count; ++} + +-static struct ddb_info ddb_octopus_le = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus LE DVB adapter", +- .port_num = 2, +-}; ++static ssize_t version_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); + +-static struct ddb_info ddb_octopus_mini = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus Mini", +- .port_num = 4, +-}; ++ return sprintf(buf, "%08x %08x\n", ++ ddbreadl(dev, 0), ddbreadl(dev, 4)); ++} + +-static struct ddb_info ddb_v6 = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Cine S2 V6 DVB adapter", +- .port_num = 3, +-}; +-static struct ddb_info ddb_v6_5 = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Cine S2 V6.5 DVB adapter", +- .port_num = 4, ++static ssize_t hwid_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "0x%08X\n", dev->ids.hwid); ++} ++ ++static ssize_t regmap_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "0x%08X\n", dev->ids.regmapid); ++} ++ ++static struct device_attribute ddb_attrs[] = { ++ __ATTR_RO(version), ++ __ATTR_RO(ports), ++ __ATTR_RO(ts_irq), ++ __ATTR_RO(i2c_irq), ++ __ATTR(gap0, 0664, gap_show, gap_store), ++ __ATTR(gap1, 0664, gap_show, gap_store), ++ __ATTR(gap2, 0664, gap_show, gap_store), ++ __ATTR(gap3, 0664, gap_show, gap_store), ++ __ATTR_RO(hwid), ++ __ATTR_RO(regmap), ++#if 0 ++ __ATTR_RO(qam), ++#endif ++ __ATTR(redirect, 0664, redirect_show, redirect_store), ++ __ATTR_MRO(snr, bsnr_show), ++ __ATTR_NULL, + }; + +-static struct ddb_info ddb_dvbct = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices DVBCT V6.1 DVB adapter", +- .port_num = 3, ++static struct device_attribute ddb_attrs_temp[] = { ++ __ATTR_RO(temp), + }; + +-static struct ddb_info ddb_satixS2v3 = { +- .type = DDB_OCTOPUS, +- .name = "Mystique SaTiX-S2 V3 DVB adapter", +- .port_num = 3, ++static struct device_attribute ddb_attrs_mod[] = { ++ __ATTR_MRO(mod0, mod_show), ++ __ATTR_MRO(mod1, mod_show), ++ __ATTR_MRO(mod2, mod_show), ++ __ATTR_MRO(mod3, mod_show), ++ __ATTR_MRO(mod4, mod_show), ++ __ATTR_MRO(mod5, mod_show), ++ __ATTR_MRO(mod6, mod_show), ++ __ATTR_MRO(mod7, mod_show), ++ __ATTR_MRO(mod8, mod_show), ++ __ATTR_MRO(mod9, mod_show), + }; + +-static struct ddb_info ddb_octopusv3 = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus V3 DVB adapter", +- .port_num = 4, ++static struct device_attribute ddb_attrs_fan[] = { ++ __ATTR(fan, 0664, fan_show, fan_store), + }; + +-#define DDVID 0xdd01 /* Digital Devices Vendor ID */ +- +-#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ +- .vendor = _vend, .device = _dev, \ +- .subvendor = _subvend, .subdevice = _subdev, \ +- .driver_data = (unsigned long)&_driverdata } +- +-static const struct pci_device_id ddb_id_tbl[] = { +- DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), +- DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), +- DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), +- /* in case sub-ids got deleted in flash */ +- DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), +- {0} ++static struct device_attribute ddb_attrs_snr[] = { ++ __ATTR(snr0, 0664, snr_show, snr_store), ++ __ATTR(snr1, 0664, snr_show, snr_store), ++ __ATTR(snr2, 0664, snr_show, snr_store), ++ __ATTR(snr3, 0664, snr_show, snr_store), + }; +-MODULE_DEVICE_TABLE(pci, ddb_id_tbl); + ++static struct device_attribute ddb_attrs_led[] = { ++ __ATTR(led0, 0664, led_show, led_store), ++ __ATTR(led1, 0664, led_show, led_store), ++ __ATTR(led2, 0664, led_show, led_store), ++ __ATTR(led3, 0664, led_show, led_store), ++}; + +-static struct pci_driver ddb_pci_driver = { +- .name = "DDBridge", +- .id_table = ddb_id_tbl, +- .probe = ddb_probe, +- .remove = ddb_remove, ++static struct class ddb_class = { ++ .name = "ddbridge", ++ .owner = THIS_MODULE, ++#if 0 ++ .dev_attrs = ddb_attrs, ++#endif ++ .devnode = ddb_devnode, + }; + +-static __init int module_init_ddbridge(void) ++static int ddb_class_create(void) + { +- int ret; ++ ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); ++ if (ddb_major < 0) ++ return ddb_major; ++ if (class_register(&ddb_class) < 0) ++ return -1; ++ return 0; ++} ++ ++static void ddb_class_destroy(void) ++{ ++ class_unregister(&ddb_class); ++ unregister_chrdev(ddb_major, DDB_NAME); ++} + +- printk(KERN_INFO "Digital Devices PCIE bridge driver, " +- "Copyright (C) 2010-11 Digital Devices GmbH\n"); ++static void ddb_device_attrs_del(struct ddb *dev) ++{ ++ int i; + +- ret = ddb_class_create(); +- if (ret < 0) +- return ret; +- ret = pci_register_driver(&ddb_pci_driver); +- if (ret < 0) +- ddb_class_destroy(); +- return ret; ++ for (i = 0; i < dev->info->temp_num; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]); ++ for (i = 0; i < dev->info->port_num; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_mod[i]); ++ for (i = 0; i < dev->info->fan_num; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_fan[i]); ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ if (dev->info->led_num) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_led[i]); ++ device_remove_file(dev->ddb_dev, &ddb_attrs_snr[i]); ++ } ++ for (i = 0; ddb_attrs[i].attr.name; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs[i]); + } + +-static __exit void module_exit_ddbridge(void) ++static int ddb_device_attrs_add(struct ddb *dev) + { +- pci_unregister_driver(&ddb_pci_driver); +- ddb_class_destroy(); ++ int i; ++ ++ for (i = 0; ddb_attrs[i].attr.name; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs[i])) ++ goto fail; ++ for (i = 0; i < dev->info->temp_num; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_temp[i])) ++ goto fail; ++ for (i = 0; i < dev->info->port_num; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_mod[i])) ++ goto fail; ++ for (i = 0; i < dev->info->fan_num; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_fan[i])) ++ goto fail; ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_snr[i])) ++ goto fail; ++ if (dev->info->led_num) ++ if (device_create_file(dev->ddb_dev, ++ &ddb_attrs_led[i])) ++ goto fail; ++ } ++ return 0; ++fail: ++ return -1; + } + +-module_init(module_init_ddbridge); +-module_exit(module_exit_ddbridge); ++static int ddb_device_create(struct ddb *dev) ++{ ++ int res = 0; ++ ++ if (ddb_num == DDB_MAX_ADAPTER) ++ return -ENOMEM; ++ mutex_lock(&ddb_mutex); ++ dev->nr = ddb_num; ++ ddbs[dev->nr] = dev; ++ dev->ddb_dev = device_create(&ddb_class, dev->dev, ++ MKDEV(ddb_major, dev->nr), ++ dev, "ddbridge%d", dev->nr); ++ if (IS_ERR(dev->ddb_dev)) { ++ res = PTR_ERR(dev->ddb_dev); ++ pr_info("Could not create ddbridge%d\n", dev->nr); ++ goto fail; ++ } ++ res = ddb_device_attrs_add(dev); ++ if (res) { ++ ddb_device_attrs_del(dev); ++ device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); ++ ddbs[dev->nr] = 0; ++ dev->ddb_dev = ERR_PTR(-ENODEV); ++ } else ++ ddb_num++; ++fail: ++ mutex_unlock(&ddb_mutex); ++ return res; ++} + +-MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); +-MODULE_AUTHOR("Ralph Metzler"); +-MODULE_LICENSE("GPL"); +-MODULE_VERSION("0.5"); ++static void ddb_device_destroy(struct ddb *dev) ++{ ++ if (IS_ERR(dev->ddb_dev)) ++ return; ++ ddb_device_attrs_del(dev); ++ device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); ++} +diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c +new file mode 100644 +index 0000000..bd0d9b1 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c +@@ -0,0 +1,257 @@ ++/* ++ * ddbridge-i2c.c: Digital Devices bridge i2c driver ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) ++{ ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_regs16(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 *val, u8 len) ++{ ++ u8 reg16[2] = { reg >> 8, reg }; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = reg16, .len = 2 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, ++ u16 reg, u8 val) ++{ ++ u8 msg[3] = {reg >> 8, reg & 0xff, val}; ++ ++ return i2c_write(adap, adr, msg, 3); ++} ++ ++static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ ++ return i2c_write(adap, adr, msg, 2); ++} ++ ++static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) ++{ ++ struct ddb *dev = i2c->dev; ++ int stat; ++ u32 val; ++ ++ ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND); ++ stat = wait_for_completion_timeout(&i2c->completion, HZ); ++ if (stat <= 0) { ++ pr_err("DDBridge I2C timeout, card %d, port %d\n", ++ dev->nr, i2c->nr); ++#ifdef CONFIG_PCI_MSI ++ { /* MSI debugging*/ ++ u32 istat = ddbreadl(dev, INTERRUPT_STATUS); ++ dev_err(dev->dev, "DDBridge IRS %08x\n", istat); ++ ddbwritel(dev, istat, INTERRUPT_ACK); ++ } ++#endif ++ return -EIO; ++ } ++ val = ddbreadl(dev, i2c->regs + I2C_COMMAND); ++ if (val & 0x70000) ++ return -EIO; ++ return 0; ++} ++ ++static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msg[], int num) ++{ ++ struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter); ++ struct ddb *dev = i2c->dev; ++ u8 addr = 0; ++ ++ if (num) ++ addr = msg[0].addr; ++ if (num == 2 && msg[1].flags & I2C_M_RD && ++ !(msg[0].flags & I2C_M_RD)) { ++ memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, ++ msg[0].buf, msg[0].len); ++ ddbwritel(dev, msg[0].len|(msg[1].len << 16), ++ i2c->regs + I2C_TASKLENGTH); ++ if (!ddb_i2c_cmd(i2c, addr, 1)) { ++ memcpy_fromio(msg[1].buf, ++ dev->regs + I2C_TASKMEM_BASE + ++ i2c->rbuf, ++ msg[1].len); ++ return num; ++ } ++ } ++ if (num == 1 && !(msg[0].flags & I2C_M_RD)) { ++ ddbcpyto(dev, I2C_TASKMEM_BASE + i2c->wbuf, ++ msg[0].buf, msg[0].len); ++ ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); ++ if (!ddb_i2c_cmd(i2c, addr, 2)) ++ return num; ++ } ++ if (num == 1 && (msg[0].flags & I2C_M_RD)) { ++ ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); ++ if (!ddb_i2c_cmd(i2c, addr, 3)) { ++ ddbcpyfrom(dev, msg[0].buf, ++ I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); ++ return num; ++ } ++ } ++ return -EIO; ++} ++ ++#if 0 ++static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msg[], int num) ++{ ++ struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter); ++ struct ddb *dev = i2c->dev; ++ int ret; ++ ++ if (dev->info->type != DDB_OCTONET || i2c->nr == 0 || i2c->nr == 3) ++ return ddb_i2c_master_xfer_locked(adapter, msg, num); ++ ++ mutex_lock(&dev->octonet_i2c_lock); ++ ret = ddb_i2c_master_xfer_locked(adapter, msg, num); ++ mutex_unlock(&dev->octonet_i2c_lock); ++ return ret; ++} ++#endif ++ ++static u32 ddb_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_SMBUS_EMUL; ++} ++ ++struct i2c_algorithm ddb_i2c_algo = { ++ .master_xfer = ddb_i2c_master_xfer, ++ .functionality = ddb_i2c_functionality, ++}; ++ ++static void ddb_i2c_release(struct ddb *dev) ++{ ++ int i; ++ struct ddb_i2c *i2c; ++ struct i2c_adapter *adap; ++ ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ i2c = &dev->i2c[i]; ++ adap = &i2c->adap; ++ i2c_del_adapter(adap); ++ } ++} ++ ++static void i2c_handler(unsigned long priv) ++{ ++ struct ddb_i2c *i2c = (struct ddb_i2c *) priv; ++ ++ complete(&i2c->completion); ++} ++ ++static int ddb_i2c_init(struct ddb *dev) ++{ ++ int i, j, stat = 0; ++ struct ddb_i2c *i2c; ++ struct i2c_adapter *adap; ++ ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ i2c = &dev->i2c[i]; ++ dev->handler[i] = i2c_handler; ++ dev->handler_data[i] = (unsigned long) i2c; ++ i2c->dev = dev; ++ i2c->nr = i; ++ i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); ++ i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); ++ i2c->regs = 0x80 + i * 0x20; ++ ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING); ++ ddbwritel(dev, (i2c->rbuf << 16) | i2c->wbuf, ++ i2c->regs + I2C_TASKADDRESS); ++ init_completion(&i2c->completion); ++ ++ adap = &i2c->adap; ++ i2c_set_adapdata(adap, i2c); ++#ifdef I2C_ADAP_CLASS_TV_DIGITAL ++ adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; ++#else ++#ifdef I2C_CLASS_TV_ANALOG ++ adap->class = I2C_CLASS_TV_ANALOG; ++#endif ++#endif ++ strcpy(adap->name, "ddbridge"); ++ adap->algo = &ddb_i2c_algo; ++ adap->algo_data = (void *)i2c; ++ adap->dev.parent = dev->dev; ++ stat = i2c_add_adapter(adap); ++ if (stat) ++ break; ++ } ++ if (stat) ++ for (j = 0; j < i; j++) { ++ i2c = &dev->i2c[j]; ++ adap = &i2c->adap; ++ i2c_del_adapter(adap); ++ } ++ return stat; ++} ++ +diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.h b/drivers/media/pci/ddbridge/ddbridge-i2c.h +new file mode 100644 +index 0000000..4a9bc26 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-i2c.h +@@ -0,0 +1,105 @@ ++/* ++ * ddbridge-i2c.h: Digital Devices bridge i2c driver ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#ifndef _DDBRIDGE_I2C_H_ ++#define _DDBRIDGE_I2C_H_ ++ ++#include ++#include ++ ++static inline int i2c_write(struct i2c_adapter *adap, u8 adr, ++ u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; ++} ++ ++static inline int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) ++{ ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ ++static inline int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_read_regs16(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 *val, u8 len) ++{ ++ u8 reg16[2] = { reg >> 8, reg }; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = reg16, .len = 2 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, ++ u16 reg, u8 val) ++{ ++ u8 msg[3] = {reg >> 8, reg & 0xff, val}; ++ ++ return i2c_write(adap, adr, msg, 3); ++} ++ ++static inline int i2c_write_reg(struct i2c_adapter *adap, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ ++ return i2c_write(adap, adr, msg, 2); ++} ++ ++#endif +diff --git a/drivers/media/pci/ddbridge/ddbridge-mod.c b/drivers/media/pci/ddbridge/ddbridge-mod.c +new file mode 100644 +index 0000000..5a9c866 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-mod.c +@@ -0,0 +1,1148 @@ ++/* ++ * ddbridge.c: Digital Devices PCIe bridge driver ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * Marcus Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include "ddbridge.h" ++#include "ddbridge-regs.h" ++ ++#include ++ ++inline s64 ConvertPCR(s64 a) ++{ ++ s32 ext; ++ s64 b; ++ ++ b = div_s64_rem(a, 300 << 22, &ext); ++ ++ return (b << 31) | ext; ++ ++} ++ ++inline s64 NegConvertPCR(s64 a) ++{ ++ s32 ext; ++ s64 b; ++ ++ b = -div_s64_rem(a, 300 << 22, &ext); ++ ++ if (ext != 0) { ++ ext = (300 << 22) - ext; ++ b -= 1; ++ } ++ return (b << 31) | ext; ++} ++ ++inline s64 RoundPCR(s64 a) ++{ ++ s64 b = a + (HW_LSB_MASK>>1); ++ return b & ~(HW_LSB_MASK - 1); ++} ++ ++inline s64 RoundPCRUp(s64 a) ++{ ++ s64 b = a + (HW_LSB_MASK - 1); ++ return b & ~(HW_LSB_MASK - 1); ++} ++ ++inline s64 RoundPCRDown(s64 a) ++{ ++ return a & ~(HW_LSB_MASK - 1); ++} ++ ++static int mod_busy(struct ddb *dev, int chan) ++{ ++ u32 creg; ++ ++ while (1) { ++ creg = ddbreadl(dev, CHANNEL_CONTROL(chan)); ++ if (creg == 0xffffffff) ++ return -EFAULT; ++ if ((creg & CHANNEL_CONTROL_BUSY) == 0) ++ break; ++ } ++ return 0; ++} ++ ++void ddbridge_mod_output_stop(struct ddb_output *output) ++{ ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ mod->State = CM_IDLE; ++ mod->Control = 0; ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++#if 0 ++ udelay(10); ++ ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr)); ++ udelay(10); ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++#endif ++ mod_busy(dev, output->nr); ++ pr_info("mod_output_stop %d.%d\n", dev->nr, output->nr); ++} ++ ++static void mod_set_incs(struct ddb_output *output) ++{ ++ s64 pcr; ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ pcr = ConvertPCR(mod->PCRIncrement); ++ ddbwritel(dev, pcr & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTL(output->nr)); ++ ddbwritel(dev, (pcr >> 32) & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTH(output->nr)); ++ mod_busy(dev, output->nr); ++ ++ pcr = NegConvertPCR(mod->PCRDecrement); ++ ddbwritel(dev, pcr & 0xffffffff, ++ CHANNEL_PCR_ADJUST_INL(output->nr)); ++ ddbwritel(dev, (pcr >> 32) & 0xffffffff, ++ CHANNEL_PCR_ADJUST_INH(output->nr)); ++ mod_busy(dev, output->nr); ++ ++} ++ ++static void mod_set_rateinc(struct ddb *dev, u32 chan) ++{ ++ ddbwritel(dev, dev->mod[chan].rate_inc, CHANNEL_RATE_INCR(chan)); ++ mod_busy(dev, chan); ++} ++ ++static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 }; ++ ++void ddbridge_mod_output_start(struct ddb_output *output) ++{ ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ /*PCRIncrement = RoundPCR(PCRIncrement);*/ ++ /*PCRDecrement = RoundPCR(PCRDecrement);*/ ++ ++ mod->LastInPacketCount = 0; ++ mod->LastOutPacketCount = 0; ++ mod->InOverflowPacketCount = 0; ++ mod->OutOverflowPacketCount = 0; ++ mod->LastInPackets = 0; ++ mod->LastOutPackets = 0; ++ mod->LastPCRAdjust = 0; ++ mod->PCRRunningCorr = 0; ++ /* we interrupt every 0x80000=524288 packets */ ++ mod->MinInputPackets = 524288 / 2; ++ mod->PCRIncrement = 0; ++ mod->PCRDecrement = 0; ++ ++ mod->State = CM_STARTUP; ++ mod->StateCounter = CM_STARTUP_DELAY; ++ ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++ udelay(10); ++ ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr)); ++ udelay(10); ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++ ++ /* QAM: 600 601 602 903 604 = 16 32 64 128 256 */ ++ /* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */ ++ ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr)); ++ ++ mod_set_rateinc(dev, output->nr); ++ mod_set_incs(output); ++ ++ mod->Control = (CHANNEL_CONTROL_ENABLE_IQ | ++ CHANNEL_CONTROL_ENABLE_DVB | ++ CHANNEL_CONTROL_ENABLE_SOURCE); ++ ++ ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr)); ++ pr_info("mod_output_start %d.%d\n", dev->nr, output->nr); ++} ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void mod_write_dac_register(struct ddb *dev, u8 Index, u8 Value) ++{ ++ u32 RegValue = 0; ++ ++ ddbwritel(dev, Value, DAC_WRITE_DATA); ++ ddbwritel(dev, DAC_CONTROL_STARTIO | Index, DAC_CONTROL); ++ do { ++ RegValue = ddbreadl(dev, DAC_CONTROL); ++ } while ((RegValue & DAC_CONTROL_STARTIO) != 0); ++} ++ ++static void mod_write_dac_register2(struct ddb *dev, u8 Index, u16 Value) ++{ ++ u32 RegValue = 0; ++ ++ ddbwritel(dev, Value, DAC_WRITE_DATA); ++ ddbwritel(dev, DAC_CONTROL_STARTIO | 0x20 | Index, DAC_CONTROL); ++ do { ++ RegValue = ddbreadl(dev, DAC_CONTROL); ++ } while ((RegValue & DAC_CONTROL_STARTIO) != 0); ++} ++ ++static int mod_read_dac_register(struct ddb *dev, u8 Index, u8 *pValue) ++{ ++ u32 RegValue = 0; ++ ++ ddbwritel(dev, DAC_CONTROL_STARTIO | 0x80 | Index, DAC_CONTROL); ++ do { ++ RegValue = ddbreadl(dev, DAC_CONTROL); ++ } while ((RegValue & DAC_CONTROL_STARTIO) != 0); ++ ++ RegValue = ddbreadl(dev, DAC_READ_DATA); ++ *pValue = (u8) RegValue; ++ return 0; ++} ++ ++static void mod_set_up_converter_vco1(struct ddb *dev, u32 Value) ++{ ++ u32 RegValue = 0; ++ ++ /* Extra delay before writing N divider */ ++ if ((Value & 0x03) == 0x02) ++ msleep(50); ++ do { ++ RegValue = ddbreadl(dev, VCO1_CONTROL); ++ } while ((RegValue & VCO1_CONTROL_WRITE) != 0); ++ ++ if ((RegValue & VCO1_CONTROL_CE) == 0) { ++ RegValue |= VCO1_CONTROL_CE; ++ ddbwritel(dev, RegValue, VCO1_CONTROL); ++ msleep(20); ++ } ++ ++ ddbwritel(dev, Value, VCO1_DATA); ++ ddbwritel(dev, RegValue | VCO1_CONTROL_WRITE, VCO1_CONTROL); ++} ++ ++static void mod_set_up_converter_vco2(struct ddb *dev, u32 Value) ++{ ++ u32 RegValue = 0; ++ ++ /* Extra delay before writing N divider */ ++ if ((Value & 0x03) == 0x02) ++ msleep(50); ++ do { ++ RegValue = ddbreadl(dev, VCO2_CONTROL); ++ } while ((RegValue & VCO2_CONTROL_WRITE) != 0); ++ ++ if ((RegValue & VCO2_CONTROL_CE) == 0) { ++ RegValue |= VCO2_CONTROL_CE; ++ ddbwritel(dev, RegValue, VCO2_CONTROL); ++ msleep(20); ++ } ++ ++ ddbwritel(dev, Value, VCO2_DATA); ++ ddbwritel(dev, RegValue | VCO2_CONTROL_WRITE, VCO2_CONTROL); ++} ++ ++static void mod_set_down_converter_vco(struct ddb *dev, u32 Value) ++{ ++ u32 RegValue = 0; ++ ++ do { ++ RegValue = ddbreadl(dev, VCO3_CONTROL); ++ } while ((RegValue & VCO3_CONTROL_WRITE) != 0); ++ ++ if ((RegValue & VCO3_CONTROL_CE) == 0) { ++ RegValue |= VCO3_CONTROL_CE; ++ ddbwritel(dev, RegValue, VCO3_CONTROL); ++ msleep(20); ++ } ++ ddbwritel(dev, Value, VCO3_DATA); ++ ddbwritel(dev, RegValue | VCO3_CONTROL_WRITE, VCO3_CONTROL); ++} ++ ++static int mod_set_attenuator(struct ddb *dev, u32 Value) ++{ ++ if (Value > 31) ++ return -EINVAL; ++ ddbwritel(dev, Value, RF_ATTENUATOR); ++ return 0; ++} ++ ++static void mod_si598_readreg(struct ddb *dev, u8 index, u8 *val) ++{ ++ ddbwritel(dev, index, CLOCKGEN_INDEX); ++ ddbwritel(dev, 1, CLOCKGEN_CONTROL); ++ usleep_range(5000, 6000); ++ *val = ddbreadl(dev, CLOCKGEN_READDATA); ++} ++ ++static void mod_si598_writereg(struct ddb *dev, u8 index, u8 val) ++{ ++ ddbwritel(dev, index, CLOCKGEN_INDEX); ++ ddbwritel(dev, val, CLOCKGEN_WRITEDATA); ++ ddbwritel(dev, 3, CLOCKGEN_CONTROL); ++ usleep_range(5000, 6000); ++} ++ ++static int mod_set_si598(struct ddb *dev, u32 freq) ++{ ++ u8 Data[6]; ++ u64 fDCO = 0; ++ u64 RFreq = 0; ++ u32 fOut = 10000000; ++ u64 m_fXtal = 0; ++ u32 N = 0; ++ u64 HSDiv = 0; ++ ++ u32 fxtal; ++ u64 MinDiv, MaxDiv, Div; ++ u64 RF; ++ ++ if (freq < 10000000 || freq > 525000000) ++ return -EINVAL; ++ mod_si598_writereg(dev, 137, 0x10); ++ ++ if (m_fXtal == 0) { ++ mod_si598_writereg(dev, 135, 0x01); ++ mod_si598_readreg(dev, 7, &Data[0]); ++ mod_si598_readreg(dev, 8, &Data[1]); ++ mod_si598_readreg(dev, 9, &Data[2]); ++ mod_si598_readreg(dev, 10, &Data[3]); ++ mod_si598_readreg(dev, 11, &Data[4]); ++ mod_si598_readreg(dev, 12, &Data[5]); ++ ++ pr_info(" Data = %02x %02x %02x %02x %02x %02x\n", ++ Data[0], Data[1], Data[2], Data[3], Data[4], Data[5]); ++ RFreq = (((u64)Data[1] & 0x3F) << 32) | ((u64)Data[2] << 24) | ++ ((u64)Data[3] << 16) | ((u64)Data[4] << 8) | ++ ((u64)Data[5]); ++ if (RFreq == 0) ++ return -EINVAL; ++ HSDiv = ((Data[0] & 0xE0) >> 5) + 4; ++ if (HSDiv == 8 || HSDiv == 10) ++ return -EINVAL; ++ N = (((u32)(Data[0] & 0x1F) << 2) | ++ ((u32)(Data[1] & 0xE0) >> 6)) + 1; ++ fDCO = fOut * (u64)(HSDiv * N); ++ m_fXtal = fDCO << 28; ++ pr_info("fxtal %016llx rfreq %016llx\n", m_fXtal, RFreq); ++ ++ m_fXtal += RFreq >> 1; ++ m_fXtal = div64_u64(m_fXtal, RFreq); ++ ++ pr_info("fOut = %d fXtal = %d fDCO = %d HDIV = %2d, N = %3d\n", ++ (u32) fOut, (u32) m_fXtal, (u32) fDCO, (u32) HSDiv, N); ++ } ++ ++ fOut = freq; ++ MinDiv = 4850000000ULL; do_div(MinDiv, freq); MinDiv += 1; ++ MaxDiv = 5670000000ULL; do_div(MaxDiv, freq); ++ Div = 5260000000ULL; do_div(Div, freq); ++ ++ if (Div < MinDiv) ++ Div = Div + 1; ++ pr_info(" fOut = %u MinDiv = %llu MaxDiv = %llu StartDiv = %llu\n", ++ fOut, MinDiv, MaxDiv, Div); ++ ++ if (Div <= 11) { ++ N = 1; ++ HSDiv = Div; ++ } else { ++ int retry = 100; ++ while (retry > 0) { ++ N = 0; ++ HSDiv = Div; ++ while ((HSDiv > 11) /*|| ((HSDiv * N) != Div)*/) { ++ N = N + 2; ++ HSDiv = Div; ++ do_div(HSDiv, N); ++ if (N > 128) ++ break; ++ } ++ pr_info(" %3d: %llu %llu %llu %u\n", ++ retry, Div, HSDiv * N, HSDiv, N); ++ if (HSDiv * N < MinDiv) ++ Div = Div + 2; ++ else if (HSDiv * N > MaxDiv) ++ Div = Div - 2; ++ else ++ break; ++ retry = retry - 1; ++ } ++ if (retry == 0) { ++ pr_err(" FAIL\n"); ++ return -EINVAL; ++ } ++ } ++ ++ if (HSDiv == 8 || HSDiv == 10) { ++ HSDiv = HSDiv >> 1; ++ N = N * 2; ++ } ++ ++ if (HSDiv < 4) ++ return -EINVAL; ++ ++ ++ fDCO = (u64)fOut * (u64)N * (u64)HSDiv; ++ pr_info("fdco %16llx\n", fDCO); ++ RFreq = fDCO<<28; ++ pr_info("%16llx %16llx\n", fDCO, RFreq); ++ ++ fxtal = m_fXtal; ++ do_div(RFreq, fxtal); ++ pr_info("%16llx %d\n", RFreq, fxtal); ++ RF = RFreq; ++ ++ pr_info("fOut = %u fXtal = %llu fDCO = %llu HSDIV = %llu, N = %u, RFreq = %llu\n", ++ fOut, m_fXtal, fDCO, HSDiv, N, RFreq); ++ ++ Data[0] = (u8)(((HSDiv - 4) << 5) | ((N - 1) >> 2)); ++ Data[1] = (u8)((((N - 1) & 0x03) << 6) | ((RF >> 32) & 0x3F)); ++ Data[2] = (u8)((RF >> 24) & 0xFF); ++ Data[3] = (u8)((RF >> 16) & 0xFF); ++ Data[4] = (u8)((RF >> 8) & 0xFF); ++ Data[5] = (u8)((RF) & 0xFF); ++ ++ pr_info(" Data = %02x %02x %02x %02x %02x %02x\n", ++ Data[0], Data[1], Data[2], Data[3], Data[4], Data[5]); ++ mod_si598_writereg(dev, 7, Data[0]); ++ mod_si598_writereg(dev, 8, Data[1]); ++ mod_si598_writereg(dev, 9, Data[2]); ++ mod_si598_writereg(dev, 10, Data[3]); ++ mod_si598_writereg(dev, 11, Data[4]); ++ mod_si598_writereg(dev, 12, Data[5]); ++ ++ mod_si598_writereg(dev, 137, 0x00); ++ mod_si598_writereg(dev, 135, 0x40); ++ return 0; ++} ++ ++ ++static void mod_bypass_equalizer(struct ddb *dev, int bypass) ++{ ++ u32 RegValue; ++ ++ RegValue = ddbreadl(dev, IQOUTPUT_CONTROL); ++ RegValue &= ~IQOUTPUT_CONTROL_BYPASS_EQUALIZER; ++ RegValue |= (bypass ? IQOUTPUT_CONTROL_BYPASS_EQUALIZER : 0x00); ++ ddbwritel(dev, RegValue, IQOUTPUT_CONTROL); ++} ++ ++static int mod_set_equalizer(struct ddb *dev, u32 Num, s16 *cTable) ++{ ++ u32 i, adr = IQOUTPUT_EQUALIZER_0; ++ ++ if (Num > 11) ++ return -EINVAL; ++ ++ for (i = 0; i < 11 - Num; i += 1) { ++ ddbwritel(dev, 0, adr); ++ adr += 4; ++ } ++ for (i = 0; i < Num; i += 1) { ++ ddbwritel(dev, (u32) cTable[i], adr); ++ adr += 4; ++ } ++ return 0; ++} ++ ++#if 0 ++static void mod_peak(struct ddb *dev, u32 Time, s16 *pIPeak, s16 *pQPeak) ++{ ++ u32 val; ++ ++ val = ddbreadl(dev, IQOUTPUT_CONTROL); ++ val &= ~(IQOUTPUT_CONTROL_ENABLE_PEAK | IQOUTPUT_CONTROL_RESET_PEAK); ++ ddbwritel(dev, val, IQOUTPUT_CONTROL); ++ ddbwritel(dev, val | IQOUTPUT_CONTROL_RESET_PEAK, IQOUTPUT_CONTROL); ++ msleep(20); ++ ddbwritel(dev, val, IQOUTPUT_CONTROL); ++ ddbwritel(dev, val | IQOUTPUT_CONTROL_ENABLE_PEAK, IQOUTPUT_CONTROL); ++ msleep(Time); ++ ddbwritel(dev, val, IQOUTPUT_CONTROL); ++ val = ddbreadl(dev, IQOUTPUT_PEAK_DETECTOR); ++ ++ *pIPeak = val & 0xffff; ++ *pQPeak = (val >> 16) & 0xffff; ++} ++#endif ++ ++static int mod_init_dac_input(struct ddb *dev) ++{ ++ u8 Set = 0; ++ u8 Hld = 0; ++ u8 Sample = 0; ++ ++ u8 Seek = 0; ++ u8 ReadSeek = 0; ++ ++ u8 SetTable[32]; ++ u8 HldTable[32]; ++ u8 SeekTable[32]; ++ ++ u8 Sample1 = 0xFF; ++ u8 Sample2 = 0xFF; ++ ++ u8 SelectSample = 0xFF; ++ u8 DiffMin = 0xFF; ++ ++ for (Sample = 0; Sample < 32; Sample++) { ++ Set = 0; ++ Hld = 0; ++ ++ mod_write_dac_register(dev, 0x04, Set << 4 | Hld); ++ mod_write_dac_register(dev, 0x05, Sample); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ Seek = ReadSeek & 0x01; ++ SeekTable[Sample] = Seek; ++ ++ HldTable[Sample] = 15; ++ ++ for (Hld = 1; Hld < 16; Hld += 1) { ++ mod_write_dac_register(dev, 0x04, Set << 4 | Hld); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ ++ if ((ReadSeek & 0x01) != Seek) { ++ HldTable[Sample] = Hld; ++ break; ++ } ++ } ++ ++ Hld = 0; ++ SetTable[Sample] = 15; ++ for (Set = 1; Set < 16; Set += 1) { ++ mod_write_dac_register(dev, 0x04, Set << 4 | Hld); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ ++ if ((ReadSeek & 0x01) != Seek) { ++ SetTable[Sample] = Set; ++ break; ++ } ++ } ++ } ++ ++ Seek = 1; ++ for (Sample = 0; Sample < 32; Sample += 1) { ++ /* printk(" %2d: %d %2d %2d\n", ++ Sample, SeekTable[Sample], SetTable[Sample], ++ HldTable[Sample]); ++ */ ++ ++ if (Sample1 == 0xFF && SeekTable[Sample] == 1 && Seek == 0) ++ Sample1 = Sample; ++ if (Sample1 != 0xFF && Sample2 == 0xFF && ++ SeekTable[Sample] == 0 && Seek == 1) ++ Sample2 = Sample; ++ Seek = SeekTable[Sample]; ++ } ++ ++ if (Sample1 == 0xFF || Sample2 == 0xFF) { ++ pr_err(" No valid window found\n"); ++ return -EINVAL; ++ } ++ ++ pr_err(" Window = %d - %d\n", Sample1, Sample2); ++ ++ for (Sample = Sample1; Sample < Sample2; Sample += 1) { ++ if (SetTable[Sample] < HldTable[Sample]) { ++ if (HldTable[Sample] - SetTable[Sample] < DiffMin) { ++ DiffMin = HldTable[Sample] - SetTable[Sample]; ++ SelectSample = Sample; ++ } ++ } ++ } ++ ++ pr_info("Select Sample %d\n", SelectSample); ++ ++ if (SelectSample == 0xFF) { ++ pr_err("No valid sample found\n"); ++ return -EINVAL; ++ } ++ ++ if (HldTable[SelectSample] + SetTable[SelectSample] < 8) { ++ pr_err("Too high jitter\n"); ++ return -EINVAL; ++ } ++ ++ mod_write_dac_register(dev, 0x04, 0x00); ++ mod_write_dac_register(dev, 0x05, (SelectSample - 1) & 0x1F); ++ mod_read_dac_register(dev, 0x06, &Seek); ++ mod_write_dac_register(dev, 0x05, (SelectSample + 1) & 0x1F); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ Seek &= ReadSeek; ++ ++ mod_write_dac_register(dev, 0x05, SelectSample); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ Seek &= ReadSeek; ++ if ((Seek & 0x01) == 0) { ++ pr_err("Insufficient timing margin\n"); ++ return -EINVAL; ++ } ++ pr_info("Done\n"); ++ return 0; ++} ++ ++static void mod_set_up1(struct ddb *dev, u32 Frequency, u32 Ref, u32 Ext) ++{ ++ u32 RDiv = Ext / Ref; ++ ++ Frequency = Frequency / Ref; ++ mod_set_up_converter_vco1(dev, 0x360001 | (RDiv << 2)); ++ mod_set_up_converter_vco1(dev, 0x0ff128); ++ mod_set_up_converter_vco1(dev, 0x02 | (Frequency << 8)); ++} ++ ++static void mod_set_up2(struct ddb *dev, u32 Frequency, u32 Ref, u32 Ext) ++{ ++ u32 Rdiv = Ext / Ref; ++ u32 PreScale = 8; ++ ++ Frequency = Frequency / Ref; ++ mod_set_up_converter_vco2(dev, 0x360001 | (Rdiv << 2)); ++ mod_set_up_converter_vco2(dev, 0x0fc128 | ++ (((PreScale - 8) / 8) << 22)); ++ mod_set_up_converter_vco2(dev, 0x02 | ((Frequency / PreScale) << 8) ++ | (Frequency & (PreScale - 1)) << 2); ++} ++ ++static int mod_set_down(struct ddb *dev, u32 Frequency, u32 Ref, u32 Ext) ++{ ++ u32 BandSelect = Ref * 8; ++ u32 RefMul = 1; ++ u32 RefDiv2 = 1; ++ u32 RefDiv = Ext * RefMul / (Ref * RefDiv2); ++ ++ if (Frequency < 2200 || Frequency > 4000) ++ return -EINVAL; ++ ++ Frequency = Frequency / Ref; ++ ++ mod_set_down_converter_vco(dev, 0x0080003C | ++ ((BandSelect & 0xFF) << 12)); ++ mod_set_down_converter_vco(dev, 0x00000003); ++ mod_set_down_converter_vco(dev, 0x18001E42 | ((RefMul-1) << 25) | ++ ((RefDiv2-1) << 24) | (RefDiv << 14)); ++ mod_set_down_converter_vco(dev, 0x08008021); ++ mod_set_down_converter_vco(dev, Frequency << 15); ++ return 0; ++} ++ ++static int mod_set_dac_clock(struct ddb *dev, u32 Frequency) ++{ ++ int hr, i; ++ ++ if (Frequency) { ++ ddbwritel(dev, DAC_CONTROL_RESET, DAC_CONTROL); ++ msleep(20); ++ if (mod_set_si598(dev, Frequency)) { ++ pr_err("mod_set_si598 failed\n"); ++ return -1; ++ } ++ msleep(50); ++ ddbwritel(dev, 0x000, DAC_CONTROL); ++ msleep(20); ++ mod_write_dac_register(dev, 0, 0x02); ++ } ++ ++ for (i = 0; i < 10; i++) { ++ hr = mod_init_dac_input(dev); ++ if (hr == 0) ++ break; ++ msleep(100); ++ } ++ pr_info("mod_set_dac_clock OK\n"); ++ return hr; ++} ++ ++static void mod_set_dac_current(struct ddb *dev, u32 Current1, u32 Current2) ++{ ++ mod_write_dac_register2(dev, 0x0b, Current1 & 0x3ff); ++ mod_write_dac_register2(dev, 0x0f, Current2 & 0x3ff); ++} ++ ++static void mod_output_enable(struct ddb *dev, int enable) ++{ ++ ++ u32 RegValue; ++ ++ RegValue = ddbreadl(dev, IQOUTPUT_CONTROL); ++ RegValue &= ~(IQOUTPUT_CONTROL_ENABLE | IQOUTPUT_CONTROL_RESET); ++ ddbwritel(dev, RegValue, IQOUTPUT_CONTROL); ++ ++ if (enable) { ++ ddbwritel(dev, RegValue | IQOUTPUT_CONTROL_RESET, ++ IQOUTPUT_CONTROL); ++ msleep(20); ++ ddbwritel(dev, RegValue, IQOUTPUT_CONTROL); ++ ddbwritel(dev, RegValue | IQOUTPUT_CONTROL_ENABLE, ++ IQOUTPUT_CONTROL); ++ } ++} ++ ++static int mod_set_iq(struct ddb *dev, u32 steps, u32 chan, u32 freq) ++{ ++ u32 i, j, k, fac = 8; ++ u32 s1 = 22, s2 = 33; ++ u64 amp = (1ULL << 17) - 1ULL; ++ u64 s = 0, c = (amp << s1), ss; ++ u64 frq = 0xC90FDAA22168C234ULL; ++ u32 *iqtab; ++ u32 iqtabadr; ++ u32 regval; ++ ++ iqtab = kmalloc((steps + 1) * 4, GFP_KERNEL); ++ if (!iqtab) ++ return -ENOMEM; ++ frq = div64_u64(frq, steps * fac) >> (61 - s2); ++ ++ /* create sine table */ ++ for (i = 0; i <= steps * fac / 4; i++) { ++ if (!(i & (fac - 1))) { ++ j = i / fac; ++ ss = s >> s1; ++ /*round? ss = ((s >> (s1 - 1)) + 1) >> 1; */ ++ ++ iqtab[j] = iqtab[steps / 2 - j] = ss; ++ iqtab[steps / 2 + j] = iqtab[steps - j] = -ss; ++ } ++ c -= ((s * frq) >> s2); ++ s += ((c * frq) >> s2); ++ } ++ iqtabadr = chan << 16; ++ ddbwritel(dev, chan & 0x0f, MODULATOR_IQTABLE_INDEX); ++ for (i = j = 0, k = steps / 4; i < steps; i++) { ++ ddbwritel(dev, (iqtabadr + i) | MODULATOR_IQTABLE_INDEX_SEL_I, ++ MODULATOR_IQTABLE_INDEX); ++ ddbwritel(dev, iqtab[j], MODULATOR_IQTABLE_DATA); ++ regval = ddbreadl(dev, MODULATOR_CONTROL); ++ ddbwritel(dev, (iqtabadr + i) | MODULATOR_IQTABLE_INDEX_SEL_Q, ++ MODULATOR_IQTABLE_INDEX); ++ ddbwritel(dev, iqtab[k], MODULATOR_IQTABLE_DATA); ++ regval = ddbreadl(dev, MODULATOR_CONTROL); ++ j += freq; ++ j %= steps; ++ k += freq; ++ k %= steps; ++ } ++ ddbwritel(dev, steps - 1, MODULATOR_IQTABLE_END); ++ kfree(iqtab); ++ return 0; ++} ++ ++u32 eqtab[] = { ++ 0x0000FFDB, 0x00000121, 0x0000FF0A, 0x000003D7, ++ 0x000001C4, 0x000005A5, 0x000009CC, 0x0000F50D, ++ 0x00001B23, 0x0000EEB7, 0x00006A28 ++}; ++ ++static int mod_set_modulation(struct ddb *dev, int chan, enum fe_modulation mod) ++{ ++ if (mod > QAM_256 || mod < QAM_16) ++ return -EINVAL; ++ dev->mod[chan].modulation = mod; ++ dev->mod[chan].obitrate = 0x0061072787900000 * (mod + 3); ++ dev->mod[chan].ibitrate = dev->mod[chan].obitrate; ++ ddbwritel(dev, qamtab[mod], CHANNEL_SETTINGS(chan)); ++ return 0; ++} ++ ++static void mod_set_channelsumshift(struct ddb *dev, u32 shift) ++{ ++ ddbwritel(dev, (shift & 3) << 2, MODULATOR_CONTROL); ++} ++ ++static void mod_pre_eq_gain(struct ddb *dev, u16 gain) ++{ ++ ddbwritel(dev, gain, IQOUTPUT_PRESCALER); ++} ++ ++static void mod_post_eq_gain(struct ddb *dev, u16 igain, u16 qgain) ++{ ++ ddbwritel(dev, ((u32)qgain << 16) | igain, IQOUTPUT_POSTSCALER); ++} ++ ++static int set_base_frequency(struct ddb *dev, u32 freq) ++{ ++ u32 Ext = 40; ++ u32 UP1Frequency = 290; ++ u32 UP2Frequency = 1896; ++ u32 down, freq10; ++ ++ pr_info("set base to %u\n", freq); ++ dev->mod_base.frequency = freq; ++ freq /= 1000000; ++ freq10 = dev->mod_base.flat_start + 4; ++ down = freq + 9 * 8 + freq10 + UP1Frequency + UP2Frequency; ++ ++ if ((freq10 + 9 * 8) > (dev->mod_base.flat_end - 4)) { ++ pr_err("Frequency out of range %d\n", freq10); ++ return -EINVAL; ++ } ++ if (down % 8) { ++ pr_err(" Invalid Frequency %d\n", down); ++ return -EINVAL; ++ } ++ return mod_set_down(dev, down, 8, Ext); ++} ++ ++static int mod_init(struct ddb *dev, u32 Frequency) ++{ ++ int stat = 0; ++ u8 *buffer; ++ struct DDMOD_FLASH *flash; ++ u32 Ext = 40; ++ u32 UP1Frequency = 290; ++ u32 UP2Frequency = 1896; ++ u32 DownFrequency; ++ u32 FrequencyCH10; ++ u32 iqfreq, iqsteps, i; ++ ++ buffer = kmalloc(4096, GFP_KERNEL); ++ if (!buffer) ++ return -ENOMEM; ++ flash = (struct DDMOD_FLASH *) buffer; ++ ++ ddbridge_flashread(dev, buffer, DDMOD_FLASH_START, 4096); ++ ++ if (flash->Magic != DDMOD_FLASH_MAGIC && flash->Magic != 1) { ++ stat = -EINVAL; ++ goto fail; ++ } ++ pr_info("srate = %d\n", flash->DataSet[0].Symbolrate * 1000); ++ ++ mod_output_enable(dev, 0); ++ stat = mod_set_dac_clock(dev, flash->DataSet[0].DACFrequency * 1000); ++ if (stat < 0) { ++ pr_err("setting DAC clock failed\n"); ++ goto fail; ++ } ++ mod_set_dac_current(dev, 512, 512); ++ ++ ddbwritel(dev, flash->DataSet[0].Control2, IQOUTPUT_CONTROL2); ++ ++ mod_set_up1(dev, UP1Frequency, 5, Ext); ++ mod_set_up2(dev, UP2Frequency, 8, Ext); ++ ++ dev->mod_base.flat_start = flash->DataSet[0].FlatStart; ++ dev->mod_base.flat_end = flash->DataSet[0].FlatEnd; ++ ++ Frequency /= 1000000; ++ FrequencyCH10 = flash->DataSet[0].FlatStart + 4; ++ DownFrequency = Frequency + 9 * 8 + FrequencyCH10 + ++ UP1Frequency + UP2Frequency; ++ pr_info("CH10 = %d, Down = %d\n", FrequencyCH10, DownFrequency); ++ ++ if ((FrequencyCH10 + 9 * 8) > (flash->DataSet[0].FlatEnd - 4)) { ++ pr_err("Frequency out of range %d\n", FrequencyCH10); ++ stat = -EINVAL; ++ goto fail; ++ } ++ ++ if (DownFrequency % 8 != 0) { ++ pr_err(" Invalid Frequency %d\n", DownFrequency); ++ stat = -EINVAL; ++ goto fail; ++ } ++ ++ mod_set_down(dev, DownFrequency, 8, Ext); ++ ++ for (i = 0; i < 10; i++) { ++ ddbwritel(dev, 0, CHANNEL_CONTROL(i)); ++ ++ iqfreq = flash->DataSet[0].FrequencyFactor * ++ (FrequencyCH10 + (9 - i) * 8); ++ iqsteps = flash->DataSet[0].IQTableLength; ++ mod_set_iq(dev, iqsteps, i, iqfreq); ++ mod_set_modulation(dev, i, QAM_256); ++ } ++ ++ mod_bypass_equalizer(dev, 1); ++ mod_set_equalizer(dev, 11, flash->DataSet[0].EQTap); ++ mod_bypass_equalizer(dev, 0); ++ mod_post_eq_gain(dev, flash->DataSet[0].PostScaleI, ++ flash->DataSet[0].PostScaleQ); ++ mod_pre_eq_gain(dev, flash->DataSet[0].PreScale); ++ /*mod_pre_eq_gain(dev, 0x0680);*/ ++ pr_info("prescaler %04x\n", flash->DataSet[0].PreScale); ++ mod_set_channelsumshift(dev, 2); ++ mod_output_enable(dev, 1); ++ ++ /*mod_set_attenuator(dev, 10);*/ ++fail: ++ kfree(buffer); ++ return stat; ++} ++ ++#define PACKET_CLOCKS (27000000ULL*1504) ++#define FACTOR (1ULL << 22) ++ ++/* ++ double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate); ++ double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate); ++ ++ 27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1 ++*/ ++ ++void ddbridge_mod_rate_handler(unsigned long data) ++{ ++ struct ddb_output *output = (struct ddb_output *) data; ++ struct ddb_dma *dma = output->dma; ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ u32 chan = output->nr; ++ u32 OutPacketCount; ++ u32 InPacketCount; ++ u64 OutPackets, InPackets; ++ s64 PCRAdjust; ++ u32 PCRAdjustExt, PCRAdjustExtFrac, InPacketDiff, OutPacketDiff; ++ s32 PCRCorr; ++ ++ s64 pcr; ++ s64 PCRIncrementDiff; ++ s64 PCRIncrement; ++ u64 mul; ++ ++ if (!mod->pcr_correction) ++ return; ++ spin_lock(&dma->lock); ++ ddbwritel(dev, mod->Control | CHANNEL_CONTROL_FREEZE_STATUS, ++ CHANNEL_CONTROL(output->nr)); ++ ++ OutPacketCount = ddbreadl(dev, CHANNEL_PKT_COUNT_OUT(chan)); ++ if (OutPacketCount < mod->LastOutPacketCount) ++ mod->OutOverflowPacketCount += 1; ++ mod->LastOutPacketCount = OutPacketCount; ++ ++ InPacketCount = ddbreadl(dev, CHANNEL_PKT_COUNT_IN(chan)); ++ if (InPacketCount < mod->LastInPacketCount) ++ mod->InOverflowPacketCount += 1; ++ mod->LastInPacketCount = InPacketCount; ++ ++ OutPackets = ((u64) (mod->OutOverflowPacketCount) << 20) | ++ OutPacketCount; ++ InPackets = ((u64) (mod->InOverflowPacketCount) << 20) | ++ InPacketCount; ++ ++ PCRAdjust = (s64) ((u64) ddbreadl(dev, ++ CHANNEL_PCR_ADJUST_ACCUL(chan)) | ++ (((u64) ddbreadl(dev, ++ CHANNEL_PCR_ADJUST_ACCUH(chan)) ++ << 32))); ++ PCRAdjustExt = (u32)((PCRAdjust & 0x7FFFFFFF) >> 22); ++ PCRAdjustExtFrac = (u32)((PCRAdjust & 0x003FFFFF) >> 12); ++ PCRAdjust >>= 31; ++ InPacketDiff = (u32) (InPackets - mod->LastInPackets); ++ OutPacketDiff = (u32) (OutPackets - mod->LastOutPackets); ++ PCRCorr = 0; ++ ++ switch (mod->State) { ++ case CM_STARTUP: ++ if (mod->StateCounter) { ++ if (mod->StateCounter == 1) { ++ if (mod->ibitrate == 0) { ++ mul = (0x1000000 * (u64) (OutPacketDiff - ++ InPacketDiff - ++ InPacketDiff/1000)); ++ if (OutPacketDiff) ++ mod->rate_inc = ++ div_u64(mul, OutPacketDiff); ++ else ++ mod->rate_inc = 0; ++ mod_set_rateinc(dev, output->nr); ++ mod->PCRIncrement = ++ div_u64(26785190066ULL, ++ mod->modulation + 3); ++ if (InPacketDiff) ++ mod->PCRDecrement = ++ div_u64(mod->PCRIncrement * ++ (u64) OutPacketDiff, ++ InPacketDiff); ++ else ++ mod->PCRDecrement = 0; ++ mod_set_incs(output); ++ } else { ++ mod->PCRIncrement = ++ div_u64(26785190066ULL, ++ mod->modulation + 3); ++ mod->PCRDecrement = ++ div_u64(FACTOR*PACKET_CLOCKS, ++ mod->ibitrate >> 32); ++ mod_set_incs(output); ++ } ++ } ++ mod->StateCounter--; ++ break; ++ } else if (InPacketDiff >= mod->MinInputPackets) { ++ mod->State = CM_ADJUST; ++ mod->Control |= CHANNEL_CONTROL_ENABLE_PCRADJUST; ++ mod->InPacketsSum = 0; ++ mod->OutPacketsSum = 0; ++ mod->PCRAdjustSum = 0; ++ mod->StateCounter = CM_AVERAGE; ++ } ++ break; ++ ++ case CM_ADJUST: ++ if (InPacketDiff < mod->MinInputPackets) { ++ pr_info("PCR Adjust reset IN: %u Min: %u\n", ++ InPacketDiff, mod->MinInputPackets); ++ mod->InPacketsSum = 0; ++ mod->OutPacketsSum = 0; ++ mod->PCRAdjustSum = 0; ++ mod->StateCounter = CM_AVERAGE; ++ ddbwritel(dev, ++ (mod->Control | ++ CHANNEL_CONTROL_FREEZE_STATUS) & ++ ~CHANNEL_CONTROL_ENABLE_PCRADJUST, ++ CHANNEL_CONTROL(chan)); ++ break; ++ } ++ ++ mod->PCRAdjustSum += (s32) PCRAdjust; ++ mod->InPacketsSum += InPacketDiff; ++ mod->OutPacketsSum += OutPacketDiff; ++ if (mod->StateCounter--) ++ break; ++ ++ if (mod->OutPacketsSum) ++ PCRIncrement = div_s64((s64)mod->InPacketsSum * ++ (s64)mod->PCRDecrement + ++ (s64)(mod->OutPacketsSum >> 1), ++ mod->OutPacketsSum); ++ else ++ PCRIncrement = 0; ++ ++ if (mod->PCRAdjustSum > 0) ++ PCRIncrement = RoundPCRDown(PCRIncrement); ++ else ++ PCRIncrement = RoundPCRUp(PCRIncrement); ++ ++ PCRIncrementDiff = PCRIncrement - mod->PCRIncrement; ++ if (PCRIncrementDiff > HW_LSB_MASK) ++ PCRIncrementDiff = HW_LSB_MASK; ++ if (PCRIncrementDiff < -HW_LSB_MASK) ++ PCRIncrementDiff = -HW_LSB_MASK; ++ ++ mod->PCRIncrement += PCRIncrementDiff; ++ pcr = ConvertPCR(mod->PCRIncrement); ++ pr_info("outl %016llx\n", pcr); ++ ddbwritel(dev, pcr & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTL(output->nr)); ++ ddbwritel(dev, (pcr >> 32) & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTH(output->nr)); ++ mod_busy(dev, chan); ++ ++ PCRCorr = (s32) (PCRIncrementDiff >> HW_LSB_SHIFT); ++ mod->PCRRunningCorr += PCRCorr; ++ ++ mod->InPacketsSum = 0; ++ mod->OutPacketsSum = 0; ++ mod->PCRAdjustSum = 0; ++ mod->StateCounter = CM_AVERAGE; ++ break; ++ ++ default: ++ break; ++ } ++ ddbwritel(dev, mod->Control, CHANNEL_CONTROL(chan)); ++ ++ mod->LastInPackets = InPackets; ++ mod->LastOutPackets = OutPackets; ++ mod->LastPCRAdjust = (s32) PCRAdjust; ++ ++ spin_unlock(&dma->lock); ++ ++ pr_info("chan %d out %016llx in %016llx indiff %08x\n", ++ chan, OutPackets, InPackets, InPacketDiff); ++ pr_info("cnt %d pcra %016llx pcraext %08x pcraextfrac %08x pcrcorr %08x pcri %016llx\n", ++ mod->StateCounter, PCRAdjust, PCRAdjustExt, ++ PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement); ++} ++ ++int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb *dev = output->port->dev; ++ ++ /* unsigned long arg = (unsigned long) parg; */ ++ int ret = 0; ++ ++ switch (cmd) { ++ case DVB_MOD_SET: ++ { ++ struct dvb_mod_params *mp = parg; ++ ++ pr_info("set base freq\n"); ++ if (mp->base_frequency != dev->mod_base.frequency) ++ if (set_base_frequency(dev, mp->base_frequency)) ++ return -EINVAL; ++ pr_info("set attenuator\n"); ++ mod_set_attenuator(dev, mp->attenuator); ++ break; ++ } ++ case DVB_MOD_CHANNEL_SET: ++ { ++ struct dvb_mod_channel_params *cp = parg; ++ int res; ++ u32 ri; ++ ++ pr_info("set modulation\n"); ++ res = mod_set_modulation(dev, output->nr, cp->modulation); ++ if (res) ++ return res; ++ ++ if (cp->input_bitrate > dev->mod[output->nr].obitrate) ++ return -EINVAL; ++ dev->mod[output->nr].ibitrate = cp->input_bitrate; ++ dev->mod[output->nr].pcr_correction = cp->pcr_correction; ++ ++ pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate); ++ pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate); ++ if (cp->input_bitrate != 0) { ++ u64 d = dev->mod[output->nr].obitrate - ++ dev->mod[output->nr].ibitrate; ++ ++ d = div64_u64(d, dev->mod[output->nr].obitrate >> 24); ++ if (d > 0xfffffe) ++ ri = 0xfffffe; ++ else ++ ri = d; ++ } else ++ ri = 0; ++ dev->mod[output->nr].rate_inc = ri; ++ pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n", ++ dev->mod[output->nr].ibitrate >> 32, ++ dev->mod[output->nr].obitrate >> 32, ++ ri); ++ break; ++ } ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++int ddbridge_mod_init(struct ddb *dev) ++{ ++ return mod_init(dev, 722000000); ++} +diff --git a/drivers/media/pci/ddbridge/ddbridge-ns.c b/drivers/media/pci/ddbridge/ddbridge-ns.c +new file mode 100644 +index 0000000..9d86cba +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-ns.c +@@ -0,0 +1,489 @@ ++/* ++ * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++static int ddb_dvb_input_start(struct ddb_input *input); ++static int ddb_dvb_input_stop(struct ddb_input *input); ++ ++static u16 calc_pcs(struct dvb_ns_params *p) ++{ ++ u32 sum = 0; ++ u16 pcs; ++ ++ sum += (p->sip[0] << 8) | p->sip[1]; ++ sum += (p->sip[2] << 8) | p->sip[3]; ++ sum += (p->dip[0] << 8) | p->dip[1]; ++ sum += (p->dip[2] << 8) | p->dip[3]; ++ sum += 0x11; /* UDP proto */ ++ sum = (sum >> 16) + (sum & 0xffff); ++ pcs = sum; ++ return pcs; ++} ++ ++static u16 calc_pcs16(struct dvb_ns_params *p, int ipv) ++{ ++ u32 sum = 0, i; ++ u16 pcs; ++ ++ for (i = 0; i < ipv ? 16 : 4; i += 2) { ++ sum += (p->sip[i] << 8) | p->sip[i + 1]; ++ sum += (p->dip[i] << 8) | p->dip[i + 1]; ++ } ++ sum += 0x11; /* UDP proto */ ++ sum = (sum >> 16) + (sum & 0xffff); ++ pcs = sum; ++ return pcs; ++} ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void ns_free(struct dvbnss *nss) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ ++ mutex_lock(&dev->mutex); ++ dns->input = 0; ++ mutex_unlock(&dev->mutex); ++} ++ ++static int ns_alloc(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ int i, ret = -EBUSY; ++ ++ mutex_lock(&dev->mutex); ++ for (i = 0; i < dev->ns_num; i++) { ++ if (dev->ns[i].input) ++ continue; ++ dev->ns[i].input = input; ++ dev->ns[i].fe = input->nr; ++ nss->priv = &dev->ns[i]; ++ ret = 0; ++ /*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */ ++ break; ++ } ++ ddbwritel(dev, 0x03, RTP_MASTER_CONTROL); ++ mutex_unlock(&dev->mutex); ++ return ret; ++} ++ ++static int ns_set_pids(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ ++ if (dev->ids.devid == 0x0301dd01) { ++ u32 sys = 0; ++ int pid, j = 1; ++ ++ sys |= nss->pids[0] & 3; ++ sys |= (nss->pids[2] & 0x1f) << 4; ++ ddbwritel(dev, sys, PID_FILTER_SYSTEM_PIDS(dns->nr)); ++ for (pid = 20; j < 5 && pid < 8192; pid++) ++ if (nss->pids[pid >> 3] & (1 << (pid & 7))) { ++ ddbwritel(dev, 0x8000 | pid, ++ PID_FILTER_PID(dns->nr, j)); ++ j++; ++ } ++ /* disable unused pids */ ++ for (; j < 5; j++) ++ ddbwritel(dev, 0, PID_FILTER_PID(dns->nr, j)); ++ } else ++ ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400); ++ return 0; ++} ++ ++static int ns_set_pid(struct dvbnss *nss, u16 pid) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ u16 byte = (pid & 0x1fff) >> 3; ++ u8 bit = 1 << (pid & 7); ++ u32 off = STREAM_PIDS(dns->nr); ++ ++#if 1 ++ if (dev->ids.devid == 0x0301dd01) { ++ if (pid & 0x2000) { ++ if (pid & 0x8000) ++ memset(nss->pids, 0xff, 0x400); ++ else ++ memset(nss->pids, 0x00, 0x400); ++ } else { ++ if (pid & 0x8000) ++ nss->pids[byte] |= bit; ++ else ++ nss->pids[byte] &= ~bit; ++ } ++ ns_set_pids(nss); ++ } else { ++ if (pid & 0x2000) { ++ if (pid & 0x8000) ++ ddbmemset(dev, off, 0xff, 0x400); ++ else ++ ddbmemset(dev, off, 0x00, 0x400); ++ } else { ++ u8 val = ddbreadb(dev, off + byte); ++ if (pid & 0x8000) ++ ddbwriteb(dev, val | bit, off + byte); ++ else ++ ddbwriteb(dev, val & ~bit, off + byte); ++ } ++ } ++#else ++ ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400); ++#endif ++ return 0; ++} ++ ++static int citoport(struct ddb *dev, u8 ci) ++{ ++ int i, j; ++ ++ for (i = j = 0; i < dev->info->port_num; i++) { ++ if (dev->port[i].class == DDB_PORT_CI) { ++ if (j == ci) ++ return i; ++ j++; ++ } ++ } ++ return -1; ++} ++ ++static int ns_set_ci(struct dvbnss *nss, u8 ci) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ int ciport; ++ ++ if (ci == 255) { ++ dns->fe = input->nr; ++ return 0; ++ } ++ ciport = citoport(dev, ci); ++ if (ciport < 0) ++ return -EINVAL; ++ pr_info("input %d to ci %d at port %d\n", input->nr, ci, ciport); ++ ddbwritel(dev, (input->nr << 16) | 0x1c, TS_OUTPUT_CONTROL(ciport)); ++ usleep_range(1, 5); ++ ddbwritel(dev, (input->nr << 16) | 0x1d, TS_OUTPUT_CONTROL(ciport)); ++ dns->fe = ciport * 2; ++ return 0; ++} ++ ++static u8 rtp_head[] = { ++ 0x80, 0x21, ++ 0x00, 0x00, /* seq number */ ++ 0x00, 0x00, 0x00, 0x00, /* time stamp*/ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++}; ++ ++static u8 rtcp_head[] = { ++ /* SR off 42:8 len 28*/ ++ 0x80, 0xc8, /* SR type */ ++ 0x00, 0x06, /* len */ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* NTP */ ++ 0x73, 0x64, 0x00, 0x00, /* RTP TS */ ++ 0x00, 0x00, 0x00, 0x00, /* packet count */ ++ 0x00, 0x00, 0x00, 0x00, /* octet count */ ++ /* SDES off 70:36 len 20 */ ++ 0x81, 0xca, /* SDES */ ++ 0x00, 0x03, /* len */ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++ 0x01, 0x05, /* CNAME item */ ++ 0x53, 0x41, 0x54, 0x49, 0x50, /* "SATIP" */ ++ 0x00, /* item type 0 */ ++ /* APP off 86:52 len 16+string length */ ++ 0x80, 0xcc, /* APP */ ++ 0x00, 0x04, /* len */ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++ 0x53, 0x45, 0x53, 0x31, /* "SES1" */ ++ 0x00, 0x00, /* identifier */ ++ 0x00, 0x00, /* string length */ ++ /* string off 102:68 */ ++}; ++ ++static int ns_set_rtcp_msg(struct dvbnss *nss, u8 *msg, u32 len) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ u32 off = STREAM_PACKET_ADR(dns->nr); ++ u32 coff = 96; ++ u16 wlen; ++ ++ if (!len) { ++ ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) & ++ ~0x10, ++ STREAM_CONTROL(dns->nr)); ++ return 0; ++ } ++ if (copy_from_user(dns->p + coff + dns->rtcp_len, msg, len)) ++ return -EFAULT; ++ dns->p[coff + dns->rtcp_len - 2] = (len >> 8); ++ dns->p[coff + dns->rtcp_len - 1] = (len & 0xff); ++ if (len & 3) { ++ u32 pad = 4 - (len & 3); ++ memset(dns->p + coff + dns->rtcp_len + len, 0, pad); ++ len += pad; ++ } ++ wlen = len / 4; ++ wlen += 3; ++ dns->p[coff + dns->rtcp_len - 14] = (wlen >> 8); ++ dns->p[coff + dns->rtcp_len - 13] = (wlen & 0xff); ++ ddbcpyto(dev, off, dns->p, sizeof(dns->p)); ++ ddbwritel(dev, (dns->rtcp_udplen + len) | ++ ((STREAM_PACKET_OFF(dns->nr) + coff) << 16), ++ STREAM_RTCP_PACKET(dns->nr)); ++ ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) | 0x10, ++ STREAM_CONTROL(dns->nr)); ++ return 0; ++} ++ ++static u32 set_nsbuf(struct dvb_ns_params *p, u8 *buf, u32 *udplen, int rtcp) ++{ ++ u32 c = 0; ++ u16 pcs; ++ u16 sport, dport; ++ ++ sport = rtcp ? p->sport2 : p->sport; ++ dport = rtcp ? p->dport2 : p->dport; ++ ++ /* MAC header */ ++ memcpy(buf + c, p->dmac, 6); ++ memcpy(buf + c + 6, p->smac, 6); ++ c += 12; ++ if (vlan) { ++ buf[c + 0] = 0x81; ++ buf[c + 1] = 0x00; ++ buf[c + 2] = ((p->qos & 7) << 5) | ((p->vlan & 0xf00) >> 8); ++ buf[c + 3] = p->vlan & 0xff; ++ c += 4; ++ } ++ buf[c + 0] = 0x08; ++ buf[c + 1] = 0x00; ++ c += 2; ++ ++ /* IP header */ ++ if (p->flags & DVB_NS_IPV6) { ++ u8 ip6head[8] = { 0x65, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x11, 0x00, }; ++ memcpy(buf + c, ip6head, sizeof(ip6head)); ++ buf[c + 7] = p->ttl; ++ memcpy(buf + c + 8, p->sip, 16); ++ memcpy(buf + c + 24, p->dip, 16); ++ c += 40; ++ ++ /* UDP */ ++ buf[c + 0] = sport >> 8; ++ buf[c + 1] = sport & 0xff; ++ buf[c + 2] = dport >> 8; ++ buf[c + 3] = dport & 0xff; ++ buf[c + 4] = 0; /* length */ ++ buf[c + 5] = 0; ++ pcs = calc_pcs16(p, p->flags & DVB_NS_IPV6); ++ buf[c + 6] = pcs >> 8; ++ buf[c + 7] = pcs & 0xff; ++ c += 8; ++ *udplen = 8; ++ ++ } else { ++ u8 ip4head[12] = { 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x40, 0x11, 0x00, 0x00 }; ++ ++ memcpy(buf + c, ip4head, sizeof(ip4head)); ++ buf[c + 8] = p->ttl; ++ memcpy(buf + c + 12, p->sip, 4); ++ memcpy(buf + c + 16, p->dip, 4); ++ c += 20; ++ ++ /* UDP */ ++ buf[c + 0] = sport >> 8; ++ buf[c + 1] = sport & 0xff; ++ buf[c + 2] = dport >> 8; ++ buf[c + 3] = dport & 0xff; ++ buf[c + 4] = 0; /* length */ ++ buf[c + 5] = 0; ++ pcs = calc_pcs(p); ++ buf[c + 6] = pcs >> 8; ++ buf[c + 7] = pcs & 0xff; ++ c += 8; ++ *udplen = 8; ++ } ++ ++ if (rtcp) { ++ memcpy(buf + c, rtcp_head, sizeof(rtcp_head)); ++ memcpy(buf + c + 4, p->ssrc, 4); ++ memcpy(buf + c + 32, p->ssrc, 4); ++ memcpy(buf + c + 48, p->ssrc, 4); ++ c += sizeof(rtcp_head); ++ *udplen += sizeof(rtcp_head); ++ } else if (p->flags & DVB_NS_RTP) { ++ memcpy(buf + c, rtp_head, sizeof(rtp_head)); ++ memcpy(buf + c + 8, p->ssrc, 4); ++ c += sizeof(rtp_head); ++ *udplen += sizeof(rtp_head); ++ } ++ return c; ++} ++ ++static int ns_set_ts_packets(struct dvbnss *nss, u8 *buf, u32 len) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ u32 off = STREAM_PACKET_ADR(dns->nr); ++ ++ if (nss->params.flags & DVB_NS_RTCP) ++ return -EINVAL; ++ ++ if (copy_from_user(dns->p + dns->ts_offset, buf, len)) ++ return -EFAULT; ++ ddbcpyto(dev, off, dns->p, sizeof(dns->p)); ++ return 0; ++} ++ ++static int ns_insert_ts_packets(struct dvbnss *nss, u8 count) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ u32 value = count; ++ ++ if (nss->params.flags & DVB_NS_RTCP) ++ return -EINVAL; ++ ++ if (count < 1 || count > 2) ++ return -EINVAL; ++ ++ ddbwritel(dev, value, STREAM_INSERT_PACKET(dns->nr)); ++ return 0; ++} ++ ++static int ns_set_net(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct dvb_ns_params *p = &nss->params; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ u32 off = STREAM_PACKET_ADR(dns->nr); ++ u32 coff = 96; ++ ++ dns->ts_offset = set_nsbuf(p, dns->p, &dns->udplen, 0); ++ if (nss->params.flags & DVB_NS_RTCP) ++ dns->rtcp_len = set_nsbuf(p, dns->p + coff, ++ &dns->rtcp_udplen, 1); ++ ddbcpyto(dev, off, dns->p, sizeof(dns->p)); ++ ddbwritel(dev, dns->udplen | (STREAM_PACKET_OFF(dns->nr) << 16), ++ STREAM_RTP_PACKET(dns->nr)); ++ ddbwritel(dev, dns->rtcp_udplen | ++ ((STREAM_PACKET_OFF(dns->nr) + coff) << 16), ++ STREAM_RTCP_PACKET(dns->nr)); ++ return 0; ++} ++ ++static int ns_start(struct dvbnss *nss) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ u32 reg = 0x8003; ++ ++ ++ if (nss->params.flags & DVB_NS_RTCP) ++ reg |= 0x10; ++ if (nss->params.flags & DVB_NS_RTP_TO) ++ reg |= 0x20; ++ if (nss->params.flags & DVB_NS_RTP) ++ reg |= 0x40; ++ if (nss->params.flags & DVB_NS_IPV6) ++ reg |= 0x80; ++ if (dns->fe != input->nr) ++ ddb_dvb_input_start(&dev->input[dns->fe]); ++ ddb_dvb_input_start(input); ++ ddbwritel(dev, reg | (dns->fe << 8), STREAM_CONTROL(dns->nr)); ++ return 0; ++} ++ ++static int ns_stop(struct dvbnss *nss) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ ++ ddbwritel(dev, 0x00, STREAM_CONTROL(dns->nr)); ++ ddb_dvb_input_stop(input); ++ if (dns->fe != input->nr) ++ ddb_dvb_input_stop(&dev->input[dns->fe]); ++ return 0; ++} ++ ++static int netstream_init(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_adapter *adap = dvb->adap; ++ struct dvb_netstream *ns = &dvb->dvbns; ++ struct ddb *dev = input->port->dev; ++ int i, res; ++ ++ ddbmemset(dev, STREAM_PIDS(input->nr), 0x00, 0x400); ++ if (dev->ids.devid == 0x0301dd01) ++ dev->ns_num = 15; ++ else ++ dev->ns_num = 12; ++ for (i = 0; i < dev->ns_num; i++) ++ dev->ns[i].nr = i; ++ ns->priv = input; ++ ns->set_net = ns_set_net; ++ ns->set_rtcp_msg = ns_set_rtcp_msg; ++ ns->set_ts_packets = ns_set_ts_packets; ++ ns->insert_ts_packets = ns_insert_ts_packets; ++ ns->set_pid = ns_set_pid; ++ ns->set_pids = ns_set_pids; ++ ns->set_ci = ns_set_ci; ++ ns->start = ns_start; ++ ns->stop = ns_stop; ++ ns->alloc = ns_alloc; ++ ns->free = ns_free; ++ res = dvb_netstream_init(adap, ns); ++ return res; ++} +diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h +index a3ccb31..eca8574 100644 +--- a/drivers/media/pci/ddbridge/ddbridge-regs.h ++++ b/drivers/media/pci/ddbridge/ddbridge-regs.h +@@ -1,7 +1,7 @@ + /* + * ddbridge-regs.h: Digital Devices PCIe bridge driver + * +- * Copyright (C) 2010-2011 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -21,11 +21,11 @@ + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +-/* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */ +- + /* Register Definitions */ + +-#define CUR_REGISTERMAP_VERSION 0x10000 ++#define CUR_REGISTERMAP_VERSION 0x10003 ++#define CUR_REGISTERMAP_VERSION_CI 0x10000 ++#define CUR_REGISTERMAP_VERSION_MOD 0x10000 + + #define HARDWARE_VERSION 0x00 + #define REGISTERMAP_VERSION 0x04 +@@ -37,10 +37,30 @@ + #define SPI_DATA 0x14 + + /* ------------------------------------------------------------------------- */ ++/* GPIO */ ++ ++#define GPIO_OUTPUT 0x20 ++#define GPIO_INPUT 0x24 ++#define GPIO_DIRECTION 0x28 ++ ++/* ------------------------------------------------------------------------- */ ++/* MDIO */ ++ ++#define MDIO_CTRL 0x20 ++#define MDIO_ADR 0x24 ++#define MDIO_REG 0x28 ++#define MDIO_VAL 0x2C ++ ++/* ------------------------------------------------------------------------- */ + +-/* Interrupt controller */ +-/* How many MSI's are available depends on HW (Min 2 max 8) */ +-/* How many are usable also depends on Host platform */ ++#define BOARD_CONTROL 0x30 ++ ++/* ------------------------------------------------------------------------- */ ++ ++/* Interrupt controller ++ How many MSI's are available depends on HW (Min 2 max 8) ++ How many are usable also depends on Host platform ++*/ + + #define INTERRUPT_BASE (0x40) + +@@ -57,6 +77,9 @@ + #define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20) + #define INTERRUPT_ACK (INTERRUPT_BASE + 0x20) + ++#define INTMASK_CLOCKGEN (0x00000001) ++#define INTMASK_TEMPMON (0x00000002) ++ + #define INTMASK_I2C1 (0x00000001) + #define INTMASK_I2C2 (0x00000002) + #define INTMASK_I2C3 (0x00000004) +@@ -81,6 +104,32 @@ + #define INTMASK_TSOUTPUT3 (0x00040000) + #define INTMASK_TSOUTPUT4 (0x00080000) + ++ ++/* Clock Generator ( Sil598 @ 0xAA I2c ) */ ++#define CLOCKGEN_BASE (0x80) ++#define CLOCKGEN_CONTROL (CLOCKGEN_BASE + 0x00) ++#define CLOCKGEN_INDEX (CLOCKGEN_BASE + 0x04) ++#define CLOCKGEN_WRITEDATA (CLOCKGEN_BASE + 0x08) ++#define CLOCKGEN_READDATA (CLOCKGEN_BASE + 0x0C) ++ ++/* DAC ( AD9781/AD9783 SPI ) */ ++#define DAC_BASE (0x090) ++#define DAC_CONTROL (DAC_BASE) ++#define DAC_WRITE_DATA (DAC_BASE+4) ++#define DAC_READ_DATA (DAC_BASE+8) ++ ++#define DAC_CONTROL_INSTRUCTION_REG (0xFF) ++#define DAC_CONTROL_STARTIO (0x100) ++#define DAC_CONTROL_RESET (0x200) ++ ++/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */ ++#define TEMPMON_BASE (0xA0) ++#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00) ++/* SHORT Temperature in °C x 256 */ ++#define TEMPMON_CORE (TEMPMON_BASE + 0x04) ++#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08) ++#define TEMPMON_SENSOR2 (TEMPMON_BASE + 0x0C) ++ + /* ------------------------------------------------------------------------- */ + /* I2C Master Controller */ + +@@ -90,19 +139,14 @@ + #define I2C_TIMING (0x04) + #define I2C_TASKLENGTH (0x08) /* High read, low write */ + #define I2C_TASKADDRESS (0x0C) /* High read, low write */ +- + #define I2C_MONITOR (0x1C) + +-#define I2C_BASE_1 (I2C_BASE + 0x00) +-#define I2C_BASE_2 (I2C_BASE + 0x20) +-#define I2C_BASE_3 (I2C_BASE + 0x40) +-#define I2C_BASE_4 (I2C_BASE + 0x60) +- + #define I2C_BASE_N(i) (I2C_BASE + (i) * 0x20) + + #define I2C_TASKMEM_BASE (0x1000) /* Byte offset */ +-#define I2C_TASKMEM_SIZE (0x1000) ++#define I2C_TASKMEM_SIZE (0x0800) + ++#define I2C_SPEED_666 (0x02010202) + #define I2C_SPEED_400 (0x04030404) + #define I2C_SPEED_200 (0x09080909) + #define I2C_SPEED_154 (0x0C0B0C0C) +@@ -117,35 +161,276 @@ + #define DMA_BASE_WRITE (0x100) + #define DMA_BASE_READ (0x140) + +-#define DMA_CONTROL (0x00) /* 64 */ +-#define DMA_ERROR (0x04) /* 65 ( only read instance ) */ ++#define DMA_CONTROL (0x00) ++#define DMA_ERROR (0x04) + +-#define DMA_DIAG_CONTROL (0x1C) /* 71 */ +-#define DMA_DIAG_PACKETCOUNTER_LOW (0x20) /* 72 */ +-#define DMA_DIAG_PACKETCOUNTER_HIGH (0x24) /* 73 */ +-#define DMA_DIAG_TIMECOUNTER_LOW (0x28) /* 74 */ +-#define DMA_DIAG_TIMECOUNTER_HIGH (0x2C) /* 75 */ +-#define DMA_DIAG_RECHECKCOUNTER (0x30) /* 76 ( Split completions on read ) */ +-#define DMA_DIAG_WAITTIMEOUTINIT (0x34) /* 77 */ +-#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38) /* 78 */ +-#define DMA_DIAG_WAITCOUNTER (0x3C) /* 79 */ ++#define DMA_DIAG_CONTROL (0x1C) ++#define DMA_DIAG_PACKETCOUNTER_LOW (0x20) ++#define DMA_DIAG_PACKETCOUNTER_HIGH (0x24) ++#define DMA_DIAG_TIMECOUNTER_LOW (0x28) ++#define DMA_DIAG_TIMECOUNTER_HIGH (0x2C) ++#define DMA_DIAG_RECHECKCOUNTER (0x30) ++#define DMA_DIAG_WAITTIMEOUTINIT (0x34) ++#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38) ++#define DMA_DIAG_WAITCOUNTER (0x3C) + + /* ------------------------------------------------------------------------- */ + /* DMA Buffer */ + + #define TS_INPUT_BASE (0x200) +-#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 16 + 0x00) ++#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 0x10 + 0x00) ++#define TS_INPUT_CONTROL2(i) (TS_INPUT_BASE + (i) * 0x10 + 0x04) + + #define TS_OUTPUT_BASE (0x280) +-#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 16 + 0x00) ++#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x00) ++#define TS_OUTPUT_CONTROL2(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x04) + + #define DMA_BUFFER_BASE (0x300) + +-#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 16 + 0x00) +-#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 16 + 0x04) +-#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 16 + 0x08) +-#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 16 + 0x0c) ++#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x00) ++#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x04) ++#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x08) ++#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x0c) + + #define DMA_BASE_ADDRESS_TABLE (0x2000) + #define DMA_BASE_ADDRESS_TABLE_ENTRIES (512) + ++ ++/* ------------------------------------------------------------------------- */ ++ ++#define LNB_BASE (0x400) ++#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00) ++#define LNB_CMD (7ULL << 0) ++#define LNB_CMD_NOP 0 ++#define LNB_CMD_INIT 1 ++#define LNB_CMD_STATUS 2 ++#define LNB_CMD_LOW 3 ++#define LNB_CMD_HIGH 4 ++#define LNB_CMD_OFF 5 ++#define LNB_CMD_DISEQC 6 ++#define LNB_CMD_UNI 7 ++ ++#define LNB_BUSY (1ULL << 4) ++#define LNB_TONE (1ULL << 15) ++ ++#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04) ++#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08) ++#define LNB_CONFIG(i) (LNB_BASE + (i) * 0x20 + 0x0c) ++#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10) ++#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14) ++ ++/* ------------------------------------------------------------------------- */ ++/* CI Interface (only CI-Bridge) */ ++ ++#define CI_BASE (0x400) ++#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00) ++ ++#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04) ++#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08) ++#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c) ++#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10) ++ ++#define CI_RESET_CAM (0x00000001) ++#define CI_POWER_ON (0x00000002) ++#define CI_ENABLE (0x00000004) ++#define CI_BLOCKIO_ENABLE (0x00000008) ++#define CI_BYPASS_DISABLE (0x00000010) ++#define CI_DISABLE_AUTO_OFF (0x00000020) ++ ++#define CI_CAM_READY (0x00010000) ++#define CI_CAM_DETECT (0x00020000) ++#define CI_READY (0x80000000) ++#define CI_BLOCKIO_ACTIVE (0x40000000) ++#define CI_BLOCKIO_RCVDATA (0x20000000) ++#define CI_BLOCKIO_SEND_PENDING (0x10000000) ++#define CI_BLOCKIO_SEND_COMPLETE (0x08000000) ++ ++#define CI_READ_CMD (0x40000000) ++#define CI_WRITE_CMD (0x80000000) ++ ++#define CI_BLOCKIO_SEND(i) (CI_BASE + (i) * 32 + 0x14) ++#define CI_BLOCKIO_RECEIVE(i) (CI_BASE + (i) * 32 + 0x18) ++ ++#define CI_BLOCKIO_SEND_COMMAND (0x80000000) ++#define CI_BLOCKIO_SEND_COMPLETE_ACK (0x40000000) ++#define CI_BLOCKIO_RCVDATA_ACK (0x40000000) ++ ++#define CI_BUFFER_BASE (0x3000) ++#define CI_BUFFER_SIZE (0x0800) ++#define CI_BLOCKIO_BUFFER_SIZE (CI_BUFFER_SIZE/2) ++ ++#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) ++#define CI_BLOCKIO_RECEIVE_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) ++#define CI_BLOCKIO_SEND_BUFFER(i) \ ++ (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE) ++ ++#define VCO1_BASE (0xC0) ++#define VCO1_CONTROL (VCO1_BASE + 0x00) ++#define VCO1_DATA (VCO1_BASE + 0x04) /* 24 Bit */ ++/* 1 = Trigger write, resets when done */ ++#define VCO1_CONTROL_WRITE (0x00000001) ++/* 0 = Put VCO into power down */ ++#define VCO1_CONTROL_CE (0x00000002) ++/* Muxout from VCO (usually = Lock) */ ++#define VCO1_CONTROL_MUXOUT (0x00000004) ++ ++#define VCO2_BASE (0xC8) ++#define VCO2_CONTROL (VCO2_BASE + 0x00) ++#define VCO2_DATA (VCO2_BASE + 0x04) /* 24 Bit */ ++/* 1 = Trigger write, resets when done */ ++#define VCO2_CONTROL_WRITE (0x00000001) ++/* 0 = Put VCO into power down */ ++#define VCO2_CONTROL_CE (0x00000002) ++/* Muxout from VCO (usually = Lock) */ ++#define VCO2_CONTROL_MUXOUT (0x00000004) ++ ++#define VCO3_BASE (0xD0) ++#define VCO3_CONTROL (VCO3_BASE + 0x00) ++#define VCO3_DATA (VCO3_BASE + 0x04) /* 32 Bit */ ++/* 1 = Trigger write, resets when done */ ++#define VCO3_CONTROL_WRITE (0x00000001) ++/* 0 = Put VCO into power down */ ++#define VCO3_CONTROL_CE (0x00000002) ++/* Muxout from VCO (usually = Lock) */ ++#define VCO3_CONTROL_MUXOUT (0x00000004) ++ ++#define RF_ATTENUATOR (0xD8) ++/* 0x00 = 0 dB ++ 0x01 = 1 dB ++ ... ++ 0x1F = 31 dB ++*/ ++ ++#define RF_POWER (0xE0) ++#define RF_POWER_BASE (0xE0) ++#define RF_POWER_CONTROL (RF_POWER_BASE + 0x00) ++#define RF_POWER_DATA (RF_POWER_BASE + 0x04) ++ ++#define RF_POWER_CONTROL_START (0x00000001) ++#define RF_POWER_CONTROL_DONE (0x00000002) ++#define RF_POWER_CONTROL_VALIDMASK (0x00000700) ++#define RF_POWER_CONTROL_VALID (0x00000500) ++ ++ ++/* -------------------------------------------------------------------------- ++ Output control ++*/ ++ ++#define IQOUTPUT_BASE (0x240) ++#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00) ++#define IQOUTPUT_CONTROL2 (IQOUTPUT_BASE + 0x04) ++#define IQOUTPUT_PEAK_DETECTOR (IQOUTPUT_BASE + 0x08) ++#define IQOUTPUT_POSTSCALER (IQOUTPUT_BASE + 0x0C) ++#define IQOUTPUT_PRESCALER (IQOUTPUT_BASE + 0x10) ++ ++#define IQOUTPUT_EQUALIZER_0 (IQOUTPUT_BASE + 0x14) ++#define IQOUTPUT_EQUALIZER_1 (IQOUTPUT_BASE + 0x18) ++#define IQOUTPUT_EQUALIZER_2 (IQOUTPUT_BASE + 0x1C) ++#define IQOUTPUT_EQUALIZER_3 (IQOUTPUT_BASE + 0x20) ++#define IQOUTPUT_EQUALIZER_4 (IQOUTPUT_BASE + 0x24) ++#define IQOUTPUT_EQUALIZER_5 (IQOUTPUT_BASE + 0x28) ++#define IQOUTPUT_EQUALIZER_6 (IQOUTPUT_BASE + 0x2C) ++#define IQOUTPUT_EQUALIZER_7 (IQOUTPUT_BASE + 0x30) ++#define IQOUTPUT_EQUALIZER_8 (IQOUTPUT_BASE + 0x34) ++#define IQOUTPUT_EQUALIZER_9 (IQOUTPUT_BASE + 0x38) ++#define IQOUTPUT_EQUALIZER_10 (IQOUTPUT_BASE + 0x3C) ++ ++#define IQOUTPUT_EQUALIZER(i) (IQOUTPUT_EQUALIZER_0 + (i) * 4) ++ ++#define IQOUTPUT_CONTROL_RESET (0x00000001) ++#define IQOUTPUT_CONTROL_ENABLE (0x00000002) ++#define IQOUTPUT_CONTROL_RESET_PEAK (0x00000004) ++#define IQOUTPUT_CONTROL_ENABLE_PEAK (0x00000008) ++#define IQOUTPUT_CONTROL_BYPASS_EQUALIZER (0x00000010) ++ ++ ++/* Modulator Base */ ++ ++#define MODULATOR_BASE (0x200) ++#define MODULATOR_CONTROL (MODULATOR_BASE) ++#define MODULATOR_IQTABLE_END (MODULATOR_BASE+4) ++#define MODULATOR_IQTABLE_INDEX (MODULATOR_BASE+8) ++#define MODULATOR_IQTABLE_DATA (MODULATOR_BASE+12) ++ ++#define MODULATOR_IQTABLE_INDEX_CHANNEL_MASK (0x000F0000) ++#define MODULATOR_IQTABLE_INDEX_IQ_MASK (0x00008000) ++#define MODULATOR_IQTABLE_INDEX_ADDRESS_MASK (0x000007FF) ++#define MODULATOR_IQTABLE_INDEX_SEL_I (0x00000000) ++#define MODULATOR_IQTABLE_INDEX_SEL_Q (MODULATOR_IQTABLE_INDEX_IQ_MASK) ++#define MODULATOR_IQTABLE_SIZE (2048) ++ ++ ++/* Modulator Channels */ ++ ++#define CHANNEL_BASE (0x400) ++#define CHANNEL_CONTROL(i) (CHANNEL_BASE + (i) * 64 + 0x00) ++#define CHANNEL_SETTINGS(i) (CHANNEL_BASE + (i) * 64 + 0x04) ++#define CHANNEL_RATE_INCR(i) (CHANNEL_BASE + (i) * 64 + 0x0C) ++#define CHANNEL_PCR_ADJUST_OUTL(i) (CHANNEL_BASE + (i) * 64 + 0x10) ++#define CHANNEL_PCR_ADJUST_OUTH(i) (CHANNEL_BASE + (i) * 64 + 0x14) ++#define CHANNEL_PCR_ADJUST_INL(i) (CHANNEL_BASE + (i) * 64 + 0x18) ++#define CHANNEL_PCR_ADJUST_INH(i) (CHANNEL_BASE + (i) * 64 + 0x1C) ++#define CHANNEL_PCR_ADJUST_ACCUL(i) (CHANNEL_BASE + (i) * 64 + 0x20) ++#define CHANNEL_PCR_ADJUST_ACCUH(i) (CHANNEL_BASE + (i) * 64 + 0x24) ++#define CHANNEL_PKT_COUNT_OUT(i) (CHANNEL_BASE + (i) * 64 + 0x28) ++#define CHANNEL_PKT_COUNT_IN(i) (CHANNEL_BASE + (i) * 64 + 0x2C) ++ ++#define CHANNEL_CONTROL_RESET (0x00000001) ++#define CHANNEL_CONTROL_ENABLE_DVB (0x00000002) ++#define CHANNEL_CONTROL_ENABLE_IQ (0x00000004) ++#define CHANNEL_CONTROL_ENABLE_SOURCE (0x00000008) ++#define CHANNEL_CONTROL_ENABLE_PCRADJUST (0x00000010) ++#define CHANNEL_CONTROL_FREEZE_STATUS (0x00000100) ++ ++#define CHANNEL_CONTROL_RESET_ERROR (0x00010000) ++#define CHANNEL_CONTROL_BUSY (0x01000000) ++#define CHANNEL_CONTROL_ERROR_SYNC (0x20000000) ++#define CHANNEL_CONTROL_ERROR_UNDERRUN (0x40000000) ++#define CHANNEL_CONTROL_ERROR_FATAL (0x80000000) ++ ++#define CHANNEL_SETTINGS_QAM_MASK (0x00000007) ++#define CHANNEL_SETTINGS_QAM16 (0x00000000) ++#define CHANNEL_SETTINGS_QAM32 (0x00000001) ++#define CHANNEL_SETTINGS_QAM64 (0x00000002) ++#define CHANNEL_SETTINGS_QAM128 (0x00000003) ++#define CHANNEL_SETTINGS_QAM256 (0x00000004) ++ ++ ++/* OCTONET */ ++ ++#define ETHER_BASE (0x100) ++#define ETHER_CONTROL (ETHER_BASE + 0x00) ++#define ETHER_LENGTH (ETHER_BASE + 0x04) ++ ++#define RTP_MASTER_BASE (0x120) ++#define RTP_MASTER_CONTROL (RTP_MASTER_BASE + 0x00) ++#define RTP_RTCP_INTERRUPT (RTP_MASTER_BASE + 0x04) ++#define RTP_MASTER_RTCP_SETTINGS (RTP_MASTER_BASE + 0x0c) ++ ++#define STREAM_BASE (0x400) ++#define STREAM_CONTROL(i) (STREAM_BASE + (i) * 0x20 + 0x00) ++#define STREAM_RTP_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x04) ++#define STREAM_RTCP_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x08) ++#define STREAM_RTP_SETTINGS(i) (STREAM_BASE + (i) * 0x20 + 0x0c) ++#define STREAM_INSERT_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x10) ++ ++#define STREAM_PACKET_OFF(i) ((i) * 0x200) ++#define STREAM_PACKET_ADR(i) (0x2000 + (STREAM_PACKET_OFF(i))) ++ ++#define STREAM_PIDS(i) (0x4000 + (i) * 0x400) ++ ++#define TS_CAPTURE_BASE (0x0140) ++#define TS_CAPTURE_CONTROL (TS_CAPTURE_BASE + 0x00) ++#define TS_CAPTURE_PID (TS_CAPTURE_BASE + 0x04) ++#define TS_CAPTURE_RECEIVED (TS_CAPTURE_BASE + 0x08) ++#define TS_CAPTURE_TIMEOUT (TS_CAPTURE_BASE + 0x0c) ++#define TS_CAPTURE_TABLESECTION (TS_CAPTURE_BASE + 0x10) ++ ++#define TS_CAPTURE_MEMORY (0x7000) ++ ++#define PID_FILTER_BASE (0x800) ++#define PID_FILTER_SYSTEM_PIDS(i) (PID_FILTER_BASE + (i) * 0x20) ++#define PID_FILTER_PID(i, j) (PID_FILTER_BASE + (i) * 0x20 + (j) * 4) ++ ++ ++ +diff --git a/drivers/media/pci/ddbridge/ddbridge.c b/drivers/media/pci/ddbridge/ddbridge.c +new file mode 100644 +index 0000000..9784f10 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge.c +@@ -0,0 +1,470 @@ ++/* ++ * ddbridge.c: Digital Devices PCIe bridge driver ++ * ++ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Ralph Metzler ++ * Marcus Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*#define DDB_ALT_DMA*/ ++#define DDB_USE_WORK ++/*#define DDB_TEST_THREADED*/ ++ ++#include "ddbridge.h" ++#include "ddbridge-regs.h" ++ ++static struct workqueue_struct *ddb_wq; ++ ++static int adapter_alloc; ++module_param(adapter_alloc, int, 0444); ++MODULE_PARM_DESC(adapter_alloc, ++ "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); ++ ++#ifdef CONFIG_PCI_MSI ++static int msi = 1; ++module_param(msi, int, 0444); ++MODULE_PARM_DESC(msi, ++ " Control MSI interrupts: 0-disable, 1-enable (default)"); ++#endif ++ ++#include "ddbridge-core.c" ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void ddb_unmap(struct ddb *dev) ++{ ++ if (dev->regs) ++ iounmap(dev->regs); ++ vfree(dev); ++} ++ ++ ++static void __devexit ddb_remove(struct pci_dev *pdev) ++{ ++ struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); ++ ++ ddb_ports_detach(dev); ++ ddb_i2c_release(dev); ++ ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0, MSI1_ENABLE); ++ if (dev->msi == 2) ++ free_irq(dev->pdev->irq + 1, dev); ++ free_irq(dev->pdev->irq, dev); ++#ifdef CONFIG_PCI_MSI ++ if (dev->msi) ++ pci_disable_msi(dev->pdev); ++#endif ++ ddb_ports_release(dev); ++ ddb_buffers_free(dev); ++ ddb_device_destroy(dev); ++ ++ ddb_unmap(dev); ++ pci_set_drvdata(pdev, 0); ++ pci_disable_device(pdev); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) ++#define __devinit ++#define __devinitdata ++#endif ++ ++static int __devinit ddb_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++{ ++ struct ddb *dev; ++ int stat = 0; ++ int irq_flag = IRQF_SHARED; ++ ++ if (pci_enable_device(pdev) < 0) ++ return -ENODEV; ++ ++ dev = vzalloc(sizeof(struct ddb)); ++ if (dev == NULL) ++ return -ENOMEM; ++ ++ dev->has_dma = 1; ++ dev->pdev = pdev; ++ dev->dev = &pdev->dev; ++ pci_set_drvdata(pdev, dev); ++ ++ dev->ids.vendor = id->vendor; ++ dev->ids.device = id->device; ++ dev->ids.subvendor = id->subvendor; ++ dev->ids.subdevice = id->subdevice; ++ ++ dev->info = (struct ddb_info *) id->driver_data; ++ pr_info("DDBridge driver detected: %s\n", dev->info->name); ++ ++ dev->regs_len = pci_resource_len(dev->pdev, 0); ++ dev->regs = ioremap(pci_resource_start(dev->pdev, 0), ++ pci_resource_len(dev->pdev, 0)); ++ if (!dev->regs) { ++ pr_err("DDBridge: not enough memory for register map\n"); ++ stat = -ENOMEM; ++ goto fail; ++ } ++ if (ddbreadl(dev, 0) == 0xffffffff) { ++ pr_err("DDBridge: cannot read registers\n"); ++ stat = -ENODEV; ++ goto fail; ++ } ++ ++ dev->ids.hwid = ddbreadl(dev, 0); ++ dev->ids.regmapid = ddbreadl(dev, 4); ++ ++ pr_info("HW %08x REGMAP %08x\n", ++ dev->ids.hwid, dev->ids.regmapid); ++ ++ ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI1_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI2_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI3_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI4_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI5_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI6_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI7_ENABLE); ++ ++#ifdef CONFIG_PCI_MSI ++ if (msi && pci_msi_enabled()) { ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) // OE ++ stat = pci_enable_msi_range(dev->pdev, 1, 2); ++ if (stat >= 1) { ++ dev->msi = stat; ++ pr_info(": Using %d MSI interrupts\n", dev->msi); ++ irq_flag = 0; ++ } else ++ pr_info(": MSI not available.\n"); ++#else ++ stat = pci_enable_msi_block(dev->pdev, 2); ++ if (stat == 0) { ++ dev->msi = 1; ++ pr_info("DDBrige using 2 MSI interrupts\n"); ++ } ++ if (stat == 1) ++ stat = pci_enable_msi(dev->pdev); ++ if (stat < 0) { ++ pr_info(": MSI not available.\n"); ++ } else { ++ irq_flag = 0; ++ dev->msi++; ++ } ++#endif ++ } ++ if (dev->msi == 2) { ++ stat = request_irq(dev->pdev->irq, irq_handler0, ++ irq_flag, "ddbridge", (void *) dev); ++ if (stat < 0) ++ goto fail0; ++ stat = request_irq(dev->pdev->irq + 1, irq_handler1, ++ irq_flag, "ddbridge", (void *) dev); ++ if (stat < 0) { ++ free_irq(dev->pdev->irq, dev); ++ goto fail0; ++ } ++ } else ++#endif ++ { ++#ifdef DDB_TEST_THREADED ++ stat = request_threaded_irq(dev->pdev->irq, irq_handler, ++ irq_thread, ++ irq_flag, ++ "ddbridge", (void *) dev); ++#else ++ stat = request_irq(dev->pdev->irq, irq_handler, ++ irq_flag, "ddbridge", (void *) dev); ++#endif ++ if (stat < 0) ++ goto fail0; ++ } ++ ddbwritel(dev, 0, DMA_BASE_READ); ++ if (dev->info->type != DDB_MOD) ++ ddbwritel(dev, 0, DMA_BASE_WRITE); ++ ++ /*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/ ++ if (dev->msi == 2) { ++ ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x0000000f, MSI1_ENABLE); ++ } else { ++ ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI1_ENABLE); ++ } ++ mutex_init(&dev->lnb_lock); ++ if (ddb_i2c_init(dev) < 0) ++ goto fail1; ++ ddb_ports_init(dev); ++ if (ddb_buffers_alloc(dev) < 0) { ++ pr_info(": Could not allocate buffer memory\n"); ++ goto fail2; ++ } ++ if (ddb_ports_attach(dev) < 0) ++ goto fail3; ++ ++ /* ignore if this fails */ ++ ddb_device_create(dev); ++ ++ if (dev->info->fan_num) { ++ ddbwritel(dev, 1, GPIO_DIRECTION); ++ ddbwritel(dev, 1, GPIO_OUTPUT); ++ } ++ if (dev->info->type == DDB_MOD) ++ ddbridge_mod_init(dev); ++ ++ return 0; ++ ++fail3: ++ ddb_ports_detach(dev); ++ pr_err("fail3\n"); ++ ddb_ports_release(dev); ++fail2: ++ pr_err("fail2\n"); ++ ddb_buffers_free(dev); ++ ddb_i2c_release(dev); ++fail1: ++ pr_err("fail1\n"); ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0, MSI1_ENABLE); ++ free_irq(dev->pdev->irq, dev); ++ if (dev->msi == 2) ++ free_irq(dev->pdev->irq + 1, dev); ++fail0: ++ pr_err("fail0\n"); ++ if (dev->msi) ++ pci_disable_msi(dev->pdev); ++fail: ++ pr_err("fail\n"); ++ ddb_unmap(dev); ++ pci_set_drvdata(pdev, 0); ++ pci_disable_device(pdev); ++ return -1; ++} ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static struct ddb_regset octopus_i2c = { ++ .base = 0x80, ++ .num = 0x04, ++ .size = 0x20, ++}; ++ ++static struct ddb_regmap octopus_map = { ++ .i2c = &octopus_i2c, ++}; ++ ++static struct ddb_info ddb_none = { ++ .type = DDB_NONE, ++ .name = "unknown Digital Devices PCIe card, install newer driver", ++ .regmap = &octopus_map, ++}; ++ ++static struct ddb_info ddb_octopus = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_octopusv3 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus V3 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_octopus_le = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus LE DVB adapter", ++ .port_num = 2, ++ .i2c_num = 2, ++}; ++ ++static struct ddb_info ddb_octopus_oem = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus OEM", ++ .port_num = 4, ++ .i2c_num = 4, ++ .led_num = 1, ++ .fan_num = 1, ++ .temp_num = 1, ++ .temp_bus = 0, ++}; ++ ++static struct ddb_info ddb_octopus_mini = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus Mini", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_v6 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine S2 V6 DVB adapter", ++ .port_num = 3, ++ .i2c_num = 3, ++}; ++ ++static struct ddb_info ddb_v6_5 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine S2 V6.5 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_v7 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine S2 V7 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++ .board_control = 2, ++}; ++ ++static struct ddb_info ddb_s2_48 = { ++ .type = DDB_OCTOPUS_MAX, ++ .name = "Digital Devices Cine S2 4/8", ++ .port_num = 4, ++ .i2c_num = 1, ++ .board_control = 1, ++}; ++ ++static struct ddb_info ddb_ctv7 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine CT V7 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++ .board_control = 3, ++}; ++ ++static struct ddb_info ddb_satixS2v3 = { ++ .type = DDB_OCTOPUS, ++ .name = "Mystique SaTiX-S2 V3 DVB adapter", ++ .port_num = 3, ++ .i2c_num = 3, ++}; ++ ++static struct ddb_info ddb_ci = { ++ .type = DDB_OCTOPUS_CI, ++ .name = "Digital Devices Octopus CI", ++ .port_num = 4, ++ .i2c_num = 2, ++}; ++ ++static struct ddb_info ddb_cis = { ++ .type = DDB_OCTOPUS_CI, ++ .name = "Digital Devices Octopus CI single", ++ .port_num = 3, ++ .i2c_num = 2, ++}; ++ ++static struct ddb_info ddb_dvbct = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices DVBCT V6.1 DVB adapter", ++ .port_num = 3, ++ .i2c_num = 3, ++}; ++ ++static struct ddb_info ddb_mod = { ++ .type = DDB_MOD, ++ .name = "Digital Devices DVB-C modulator", ++ .port_num = 10, ++ .temp_num = 1, ++}; ++ ++#define DDVID 0xdd01 /* Digital Devices Vendor ID */ ++ ++#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ ++ .vendor = _vend, .device = _dev, \ ++ .subvendor = _subvend, .subdevice = _subdev, \ ++ .driver_data = (unsigned long)&_driverdata } ++ ++static const struct pci_device_id ddb_id_tbl[] __devinitconst = { ++ DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), ++ DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), ++ DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), ++ DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), ++ DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), ++ DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), ++ DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), ++ /* in case sub-ids got deleted in flash */ ++ DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), ++ DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), ++ DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), ++ {0} ++}; ++MODULE_DEVICE_TABLE(pci, ddb_id_tbl); ++ ++static struct pci_driver ddb_pci_driver = { ++ .name = "ddbridge", ++ .id_table = ddb_id_tbl, ++ .probe = ddb_probe, ++ .remove = ddb_remove, ++}; ++ ++static __init int module_init_ddbridge(void) ++{ ++ int stat = -1; ++ ++ pr_info("Digital Devices PCIE bridge driver " ++ DDBRIDGE_VERSION ++ ", Copyright (C) 2010-14 Digital Devices GmbH\n"); ++ if (ddb_class_create() < 0) ++ return -1; ++ ddb_wq = create_workqueue("ddbridge"); ++ if (ddb_wq == NULL) ++ goto exit1; ++ stat = pci_register_driver(&ddb_pci_driver); ++ if (stat < 0) ++ goto exit2; ++ return stat; ++exit2: ++ destroy_workqueue(ddb_wq); ++exit1: ++ ddb_class_destroy(); ++ return stat; ++} ++ ++static __exit void module_exit_ddbridge(void) ++{ ++ pci_unregister_driver(&ddb_pci_driver); ++ destroy_workqueue(ddb_wq); ++ ddb_class_destroy(); ++} ++ ++module_init(module_init_ddbridge); ++module_exit(module_exit_ddbridge); ++ ++MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); ++MODULE_AUTHOR("Ralph Metzler, Metzler Brothers Systementwicklung"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(DDBRIDGE_VERSION); +diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h +index be87fbd..a02e91a 100644 +--- a/drivers/media/pci/ddbridge/ddbridge.h ++++ b/drivers/media/pci/ddbridge/ddbridge.h +@@ -1,7 +1,8 @@ + /* + * ddbridge.h: Digital Devices PCIe bridge driver + * +- * Copyright (C) 2010-2011 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -24,16 +25,51 @@ + #ifndef _DDBRIDGE_H_ + #define _DDBRIDGE_H_ + ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) ++#define __devexit ++#define __devinit ++#define __devinitconst ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ + #include + #include + #include + #include + #include + #include +-#include ++#include ++#include ++#include ++ + #include + #include ++#include ++#include + ++#include "dvb_netstream.h" + #include "dmxdev.h" + #include "dvbdev.h" + #include "dvb_demux.h" +@@ -41,95 +77,167 @@ + #include "dvb_ringbuffer.h" + #include "dvb_ca_en50221.h" + #include "dvb_net.h" ++ ++#include "tda18271c2dd.h" ++#include "stv6110x.h" ++#include "stv090x.h" ++#include "lnbh24.h" ++#include "drxk.h" ++#include "stv0367.h" ++#include "stv0367dd.h" ++#include "tda18212.h" ++#include "tda18212dd.h" ++#include "cxd2843.h" + #include "cxd2099.h" ++#include "stv0910.h" ++#include "stv6111.h" ++#include "lnbh25.h" + + #define DDB_MAX_I2C 4 +-#define DDB_MAX_PORT 4 ++#define DDB_MAX_PORT 10 + #define DDB_MAX_INPUT 8 +-#define DDB_MAX_OUTPUT 4 ++#define DDB_MAX_OUTPUT 10 ++ ++struct ddb_regset { ++ u32 base; ++ u32 num; ++ u32 size; ++}; ++ ++struct ddb_regmap { ++ struct ddb_regset *i2c; ++ struct ddb_regset *i2c_buf; ++ struct ddb_regset *dma; ++ struct ddb_regset *dma_buf; ++ struct ddb_regset *input; ++ struct ddb_regset *output; ++ struct ddb_regset *channel; ++ struct ddb_regset *ci; ++ struct ddb_regset *pid_filter; ++ struct ddb_regset *ns; ++}; ++ ++struct ddb_ids { ++ u16 vendor; ++ u16 device; ++ u16 subvendor; ++ u16 subdevice; ++ ++ u32 hwid; ++ u32 regmapid; ++ u32 devid; ++ u32 mac; ++}; + + struct ddb_info { + int type; + #define DDB_NONE 0 + #define DDB_OCTOPUS 1 ++#define DDB_OCTOPUS_CI 2 ++#define DDB_MOD 3 ++#define DDB_OCTONET 4 ++#define DDB_OCTOPUS_MAX 5 + char *name; +- int port_num; +- u32 port_type[DDB_MAX_PORT]; ++ u8 port_num; ++ u8 i2c_num; ++ u8 led_num; ++ u8 fan_num; ++ u8 temp_num; ++ u8 temp_bus; ++ u8 board_control; ++ u8 ns_num; ++ u8 mdio_num; ++ struct ddb_regmap *regmap; + }; + +-/* DMA_SIZE MUST be divisible by 188 and 128 !!! */ + +-#define INPUT_DMA_MAX_BUFS 32 /* hardware table limit */ ++/* DMA_SIZE MUST be smaller than 256k and ++ MUST be divisible by 188 and 128 !!! */ ++ ++#define DMA_MAX_BUFS 32 /* hardware table limit */ ++ + #define INPUT_DMA_BUFS 8 + #define INPUT_DMA_SIZE (128*47*21) ++#define INPUT_DMA_IRQ_DIV 1 + +-#define OUTPUT_DMA_MAX_BUFS 32 + #define OUTPUT_DMA_BUFS 8 + #define OUTPUT_DMA_SIZE (128*47*21) ++#define OUTPUT_DMA_IRQ_DIV 1 + + struct ddb; + struct ddb_port; + +-struct ddb_input { +- struct ddb_port *port; ++struct ddb_dma { ++ void *io; + u32 nr; +- int attached; +- +- dma_addr_t pbuf[INPUT_DMA_MAX_BUFS]; +- u8 *vbuf[INPUT_DMA_MAX_BUFS]; +- u32 dma_buf_num; +- u32 dma_buf_size; ++ dma_addr_t pbuf[DMA_MAX_BUFS]; ++ u8 *vbuf[DMA_MAX_BUFS]; ++ u32 num; ++ u32 size; ++ u32 div; ++ u32 bufreg; + ++#ifdef DDB_USE_WORK ++ struct work_struct work; ++#else + struct tasklet_struct tasklet; ++#endif + spinlock_t lock; + wait_queue_head_t wq; + int running; + u32 stat; ++ u32 ctrl; + u32 cbuf; + u32 coff; ++}; + +- struct dvb_adapter adap; ++struct ddb_dvb { ++ struct dvb_adapter *adap; ++ int adap_registered; + struct dvb_device *dev; + struct dvb_frontend *fe; + struct dvb_frontend *fe2; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dvb_net dvbnet; ++ struct dvb_netstream dvbns; + struct dmx_frontend hw_frontend; + struct dmx_frontend mem_frontend; + int users; +- int (*gate_ctrl)(struct dvb_frontend *, int); ++ u32 attached; ++ u8 input; ++ ++ int (*i2c_gate_ctrl)(struct dvb_frontend *, int); ++ int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); ++ int (*set_input)(struct dvb_frontend *fe); + }; + +-struct ddb_output { ++struct ddb_ci { ++ struct dvb_ca_en50221 en; + struct ddb_port *port; + u32 nr; +- dma_addr_t pbuf[OUTPUT_DMA_MAX_BUFS]; +- u8 *vbuf[OUTPUT_DMA_MAX_BUFS]; +- u32 dma_buf_num; +- u32 dma_buf_size; +- struct tasklet_struct tasklet; +- spinlock_t lock; +- wait_queue_head_t wq; +- int running; +- u32 stat; +- u32 cbuf; +- u32 coff; ++ struct mutex lock; ++}; + +- struct dvb_adapter adap; +- struct dvb_device *dev; ++struct ddb_io { ++ struct ddb_port *port; ++ u32 nr; ++ struct ddb_dma *dma; ++ struct ddb_io *redo; ++ struct ddb_io *redi; + }; + ++#define ddb_output ddb_io ++#define ddb_input ddb_io ++ + struct ddb_i2c { + struct ddb *dev; + u32 nr; + struct i2c_adapter adap; +- struct i2c_adapter adap2; + u32 regs; + u32 rbuf; + u32 wbuf; +- int done; +- wait_queue_head_t wq; ++ struct completion completion; + }; + + struct ddb_port { +@@ -141,43 +249,250 @@ struct ddb_port { + #define DDB_PORT_NONE 0 + #define DDB_PORT_CI 1 + #define DDB_PORT_TUNER 2 +- u32 type; +-#define DDB_TUNER_NONE 0 +-#define DDB_TUNER_DVBS_ST 1 +-#define DDB_TUNER_DVBS_ST_AA 2 +-#define DDB_TUNER_DVBCT_TR 16 +-#define DDB_TUNER_DVBCT_ST 17 +- u32 adr; ++#define DDB_PORT_LOOP 3 ++#define DDB_PORT_MOD 4 ++ char *name; ++ u32 type; ++#define DDB_TUNER_NONE 0 ++#define DDB_TUNER_DVBS_ST 1 ++#define DDB_TUNER_DVBS_ST_AA 2 ++#define DDB_TUNER_DVBCT_TR 3 ++#define DDB_TUNER_DVBCT_ST 4 ++#define DDB_CI_INTERNAL 5 ++#define DDB_CI_EXTERNAL_SONY 6 ++#define DDB_TUNER_DVBCT2_SONY_P 7 ++#define DDB_TUNER_DVBC2T2_SONY_P 8 ++#define DDB_TUNER_ISDBT_SONY_P 9 ++#define DDB_TUNER_DVBS_STV0910_P 10 ++#define DDB_TUNER_MXL5XX 11 + ++#define DDB_TUNER_XO2 16 ++#define DDB_TUNER_DVBS_STV0910 16 ++#define DDB_TUNER_DVBCT2_SONY 17 ++#define DDB_TUNER_ISDBT_SONY 18 ++#define DDB_TUNER_DVBC2T2_SONY 19 ++#define DDB_TUNER_ATSC_ST 20 ++#define DDB_TUNER_DVBC2T2_ST 21 ++ ++ u32 adr; + struct ddb_input *input[2]; + struct ddb_output *output; + struct dvb_ca_en50221 *en; ++ struct ddb_dvb dvb[2]; ++ u32 gap; ++ u32 obr; ++}; ++ ++ ++struct mod_base { ++ u32 frequency; ++ ++ u32 flat_start; ++ u32 flat_end; ++}; ++ ++struct mod_state { ++ u32 modulation; ++ u64 obitrate; ++ u64 ibitrate; ++ u32 pcr_correction; ++ ++ u32 rate_inc; ++ u32 Control; ++ u32 State; ++ u32 StateCounter; ++ s32 LastPCRAdjust; ++ s32 PCRAdjustSum; ++ s32 InPacketsSum; ++ s32 OutPacketsSum; ++ s64 PCRIncrement; ++ s64 PCRDecrement; ++ s32 PCRRunningCorr; ++ u32 OutOverflowPacketCount; ++ u32 InOverflowPacketCount; ++ u32 LastOutPacketCount; ++ u32 LastInPacketCount; ++ u64 LastOutPackets; ++ u64 LastInPackets; ++ u32 MinInputPackets; ++}; ++ ++#define CM_STARTUP_DELAY 2 ++#define CM_AVERAGE 20 ++#define CM_GAIN 10 ++ ++#define HW_LSB_SHIFT 12 ++#define HW_LSB_MASK 0x1000 ++ ++#define CM_IDLE 0 ++#define CM_STARTUP 1 ++#define CM_ADJUST 2 ++ ++#define TS_CAPTURE_LEN (4096) ++ ++/* net streaming hardware block */ ++ ++#define DDB_NS_MAX 15 ++ ++struct ddb_ns { ++ struct ddb_input *input; ++ int nr; ++ int fe; ++ u32 rtcp_udplen; ++ u32 rtcp_len; ++ u32 ts_offset; ++ u32 udplen; ++ u8 p[512]; + }; + + struct ddb { + struct pci_dev *pdev; +- unsigned char __iomem *regs; ++ struct platform_device *pfdev; ++ struct device *dev; ++ struct ddb_ids ids; ++ struct ddb_info *info; ++ int msi; ++ struct workqueue_struct *wq; ++ u32 has_dma; ++ u32 has_ns; ++ ++ struct ddb_regmap regmap; ++ unsigned char *regs; ++ u32 regs_len; + struct ddb_port port[DDB_MAX_PORT]; + struct ddb_i2c i2c[DDB_MAX_I2C]; + struct ddb_input input[DDB_MAX_INPUT]; + struct ddb_output output[DDB_MAX_OUTPUT]; ++ struct dvb_adapter adap[DDB_MAX_INPUT]; ++ struct ddb_dma dma[DDB_MAX_INPUT + DDB_MAX_OUTPUT]; ++ ++ void (*handler[32])(unsigned long); ++ unsigned long handler_data[32]; + + struct device *ddb_dev; +- int nr; ++ u32 ddb_dev_users; ++ u32 nr; + u8 iobuf[1028]; + +- struct ddb_info *info; +- int msi; ++ u8 leds; ++ u32 ts_irq; ++ u32 i2c_irq; ++ ++ int ns_num; ++ struct ddb_ns ns[DDB_NS_MAX]; ++ struct mutex mutex; ++ ++ struct dvb_device *nsd_dev; ++ u8 tsbuf[TS_CAPTURE_LEN]; ++ ++ struct mod_base mod_base; ++ struct mod_state mod[10]; ++ ++ struct mutex octonet_i2c_lock; ++ struct mutex lnb_lock; ++ u32 lnb_tone; + }; + ++ + /****************************************************************************/ + +-#define ddbwritel(_val, _adr) writel((_val), \ +- dev->regs+(_adr)) +-#define ddbreadl(_adr) readl(dev->regs+(_adr)) +-#define ddbcpyto(_adr, _src, _count) memcpy_toio(dev->regs+(_adr), (_src), (_count)) +-#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), dev->regs+(_adr), (_count)) ++static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) ++{ ++ writeb(val, (char *) (dev->regs+(adr))); ++} ++ ++static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) ++{ ++ writel(val, (char *) (dev->regs+(adr))); ++} ++ ++static inline void ddbwritew(struct ddb *dev, u16 val, u32 adr) ++{ ++ writew(val, (char *) (dev->regs+(adr))); ++} ++ ++static inline u32 ddbreadl(struct ddb *dev, u32 adr) ++{ ++ return readl((char *) (dev->regs+(adr))); ++} ++ ++static inline u32 ddbreadb(struct ddb *dev, u32 adr) ++{ ++ return readb((char *) (dev->regs+(adr))); ++} + ++#define ddbcpyto(_dev, _adr, _src, _count) \ ++ memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count)) ++ ++#define ddbcpyfrom(_dev, _dst, _adr, _count) \ ++ memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count)) ++ ++#define ddbmemset(_dev, _adr, _val, _count) \ ++ memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ + /****************************************************************************/ + ++#define dd_uint8 u8 ++#define dd_uint16 u16 ++#define dd_int16 s16 ++#define dd_uint32 u32 ++#define dd_int32 s32 ++#define dd_uint64 u64 ++#define dd_int64 s64 ++ ++#define DDMOD_FLASH_START 0x1000 ++ ++struct DDMOD_FLASH_DS { ++ dd_uint32 Symbolrate; /* kSymbols/s */ ++ dd_uint32 DACFrequency; /* kHz */ ++ dd_uint16 FrequencyResolution; /* kHz */ ++ dd_uint16 IQTableLength; ++ dd_uint16 FrequencyFactor; ++ dd_int16 PhaseCorr; /* TBD */ ++ dd_uint32 Control2; ++ dd_uint16 PostScaleI; ++ dd_uint16 PostScaleQ; ++ dd_uint16 PreScale; ++ dd_int16 EQTap[11]; ++ dd_uint16 FlatStart; ++ dd_uint16 FlatEnd; ++ dd_uint32 FlashOffsetPrecalculatedIQTables; /* 0 = none */ ++ dd_uint8 Reserved[28]; ++ ++}; ++ ++struct DDMOD_FLASH { ++ dd_uint32 Magic; ++ dd_uint16 Version; ++ dd_uint16 DataSets; ++ ++ dd_uint16 VCORefFrequency; /* MHz */ ++ dd_uint16 VCO1Frequency; /* MHz */ ++ dd_uint16 VCO2Frequency; /* MHz */ ++ ++ dd_uint16 DACAux1; /* TBD */ ++ dd_uint16 DACAux2; /* TBD */ ++ ++ dd_uint8 Reserved1[238]; ++ ++ struct DDMOD_FLASH_DS DataSet[1]; ++}; ++ ++#define DDMOD_FLASH_MAGIC 0x5F564d5F ++ ++ ++int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg); ++int ddbridge_mod_init(struct ddb *dev); ++void ddbridge_mod_output_stop(struct ddb_output *output); ++void ddbridge_mod_output_start(struct ddb_output *output); ++void ddbridge_mod_rate_handler(unsigned long data); ++ ++ ++int ddbridge_flashread(struct ddb *dev, u8 *buf, u32 addr, u32 len); ++ ++#define DDBRIDGE_VERSION "0.9.15" ++ + #endif +diff --git a/drivers/media/pci/ddbridge/octonet.c b/drivers/media/pci/ddbridge/octonet.c +new file mode 100644 +index 0000000..e803e73 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/octonet.c +@@ -0,0 +1,199 @@ ++/* ++ * octonet.c: Digital Devices network tuner driver ++ * ++ * Copyright (C) 2012-14 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include "ddbridge.h" ++#include "ddbridge-regs.h" ++ ++#include ++ ++static int adapter_alloc = 3; ++module_param(adapter_alloc, int, 0444); ++MODULE_PARM_DESC(adapter_alloc, ++"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); ++ ++#define DVB_NSD ++ ++#include "ddbridge-core.c" ++ ++static struct ddb_info ddb_octonet = { ++ .type = DDB_OCTONET, ++ .name = "Digital Devices OctopusNet network DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++ .ns_num = 12, ++ .mdio_num = 1, ++}; ++ ++static void octonet_unmap(struct ddb *dev) ++{ ++ if (dev->regs) ++ iounmap(dev->regs); ++ vfree(dev); ++} ++ ++static int __exit octonet_remove(struct platform_device *pdev) ++{ ++ struct ddb *dev; ++ ++ dev = platform_get_drvdata(pdev); ++ ++ ddb_nsd_detach(dev); ++ ddb_ports_detach(dev); ++ ddb_i2c_release(dev); ++ ++ ddbwritel(dev, 0, ETHER_CONTROL); ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ free_irq(platform_get_irq(dev->pfdev, 0), dev); ++ ++ ddb_ports_release(dev); ++ ddb_device_destroy(dev); ++ octonet_unmap(dev); ++ platform_set_drvdata(pdev, 0); ++ return 0; ++} ++ ++static int __init octonet_probe(struct platform_device *pdev) ++{ ++ struct ddb *dev; ++ struct resource *regs; ++ int i; ++ ++ dev = vzalloc(sizeof(struct ddb)); ++ if (!dev) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, dev); ++ dev->dev = &pdev->dev; ++ dev->pfdev = pdev; ++ dev->info = &ddb_octonet; ++ ++ mutex_init(&dev->mutex); ++ regs = platform_get_resource(dev->pfdev, IORESOURCE_MEM, 0); ++ if (!regs) ++ return -ENXIO; ++ dev->regs_len = (regs->end - regs->start) + 1; ++ dev_info(dev->dev, "regs_start=%08x regs_len=%08x\n", ++ (u32) regs->start, (u32) dev->regs_len); ++ dev->regs = ioremap(regs->start, dev->regs_len); ++ if (!dev->regs) { ++ dev_err(dev->dev, "ioremap failed\n"); ++ return -ENOMEM; ++ } ++ ++ dev->ids.hwid = ddbreadl(dev, 0); ++ dev->ids.regmapid = ddbreadl(dev, 4); ++ dev->ids.devid = ddbreadl(dev, 8); ++ dev->ids.mac = ddbreadl(dev, 12); ++ ++ dev->ids.vendor = dev->ids.devid & 0xffff; ++ dev->ids.device = dev->ids.devid >> 16; ++ dev->ids.subvendor = dev->ids.devid & 0xffff; ++ dev->ids.subdevice = dev->ids.devid >> 16; ++ ++ pr_info("HW %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid); ++ pr_info("MAC %08x DEVID %08x\n", dev->ids.mac, dev->ids.devid); ++ ++ ddbwritel(dev, 0, ETHER_CONTROL); ++ ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0xffffffff, INTERRUPT_STATUS); ++ for (i = 0; i < 16; i++) ++ ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i)); ++ usleep_range(5000, 6000); ++ ++ if (request_irq(platform_get_irq(dev->pfdev, 0), irq_handler, ++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, ++ "octonet-dvb", (void *) dev) < 0) ++ goto fail; ++ ++ ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x1, ETHER_CONTROL); ++ ddbwritel(dev, 14 + (vlan ? 4 : 0), ETHER_LENGTH); ++ ++ ++ mutex_init(&dev->octonet_i2c_lock); ++ if (ddb_i2c_init(dev) < 0) ++ goto fail1; ++ ++ ddb_ports_init(dev); ++ if (ddb_ports_attach(dev) < 0) ++ goto fail3; ++ ++ ddb_nsd_attach(dev); ++ ++ ddb_device_create(dev); ++ ++ return 0; ++ ++fail3: ++ ddb_ports_detach(dev); ++ dev_err(dev->dev, "fail3\n"); ++fail1: ++ dev_err(dev->dev, "fail1\n"); ++fail: ++ dev_err(dev->dev, "fail\n"); ++ ddbwritel(dev, 0, ETHER_CONTROL); ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ octonet_unmap(dev); ++ platform_set_drvdata(pdev, 0); ++ return 0; ++} ++ ++static struct platform_driver octonet_driver = { ++ .remove = __exit_p(octonet_remove), ++ .probe = octonet_probe, ++ .driver = { ++ .name = "octonet-dvb", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static __init int init_octonet(void) ++{ ++ int res; ++ ++ pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION ++ ", Copyright (C) 2010-14 Digital Devices GmbH\n"); ++ res = ddb_class_create(); ++ if (res) ++ return res; ++ res = platform_driver_probe(&octonet_driver, octonet_probe); ++ if (res) { ++ ddb_class_destroy(); ++ return res; ++ } ++ return 0; ++} ++ ++static __exit void exit_octonet(void) ++{ ++ platform_driver_unregister(&octonet_driver); ++ ddb_class_destroy(); ++} ++ ++module_init(init_octonet); ++module_exit(exit_octonet); ++ ++MODULE_DESCRIPTION("GPL"); ++MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION("0.5"); +diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig +index 637d506..3896c12 100644 +--- a/drivers/media/pci/ngene/Kconfig ++++ b/drivers/media/pci/ngene/Kconfig +@@ -1,12 +1,16 @@ + config DVB_NGENE + tristate "Micronas nGene support" + depends on DVB_CORE && PCI && I2C ++ select DVB_CXD2099 + select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT + select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT + select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT + ---help--- + Support for Micronas PCI express cards with nGene bridge. +diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile +index 5c0b5d6..42c036a 100644 +--- a/drivers/media/pci/ngene/Makefile ++++ b/drivers/media/pci/ngene/Makefile +@@ -2,7 +2,8 @@ + # Makefile for the nGene device driver + # + +-ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o ++ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-av.o \ ++ ngene-eeprom.o ngene-dvb.o + + obj-$(CONFIG_DVB_NGENE) += ngene.o + +diff --git a/drivers/media/pci/ngene/ngene-av.c b/drivers/media/pci/ngene/ngene-av.c +new file mode 100644 +index 0000000..a86459e +--- /dev/null ++++ b/drivers/media/pci/ngene/ngene-av.c +@@ -0,0 +1,348 @@ ++/* ++ * ngene-av.c: nGene PCIe bridge driver - DVB video/audio support ++ * ++ * Copyright (C) 2005-2007 Micronas ++ * ++ * Copyright (C) 2008-2009 Ralph Metzler ++ * Modifications for new nGene firmware, ++ * support for EEPROM-copying, ++ * support for new dual DVB-S2 card prototype ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* This file provides the support functions for DVB audio/video devices ++ (/dev/dvb/adapter0/[video|audio]), not to be confused with V4L2 support */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ngene.h" ++ ++#if 0 ++ ++static void *ain_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) ++{ ++ struct ngene_channel *chan = priv; ++ struct ngene *dev = chan->dev; ++ ++ if (dvb_ringbuffer_free(&dev->ain_rbuf) >= len) { ++ dvb_ringbuffer_write(&dev->ain_rbuf, buf, len); ++ wake_up_interruptible(&dev->ain_rbuf.queue); ++ } else ++ printk(KERN_INFO DEVICE_NAME ": Dropped ain packet.\n"); ++ ++ return 0; ++} ++ ++static void *vcap_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) ++{ ++ ++ struct ngene_channel *chan = priv; ++ struct ngene *dev = chan->dev; ++ ++ if (len >= 1920 * 1080) ++ len = 1920 * 1080; ++ if (dvb_ringbuffer_free(&dev->vin_rbuf) >= len) { ++ dvb_ringbuffer_write(&dev->vin_rbuf, buf, len); ++ wake_up_interruptible(&dev->vin_rbuf.queue); ++ } else { ++ ;/*printk(KERN_INFO DEVICE_NAME ": Dropped vcap packet.\n"); */ ++ } ++ return 0; ++} ++ ++static ssize_t audio_write(struct file *file, ++ const char *buf, size_t count, loff_t *ppos) ++{ ++ return -EINVAL; ++} ++ ++ssize_t audio_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int left; ++ int avail; ++ ++ left = count; ++ while (left) { ++ if (wait_event_interruptible( ++ dev->ain_rbuf.queue, ++ dvb_ringbuffer_avail(&dev->ain_rbuf) > 0) < 0) ++ return -EAGAIN; ++ avail = dvb_ringbuffer_avail(&dev->ain_rbuf); ++ if (avail > left) ++ avail = left; ++ dvb_ringbuffer_read_user(&dev->ain_rbuf, buf, avail); ++ left -= avail; ++ buf += avail; ++ } ++ return count; ++} ++ ++static int audio_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan2 = &chan->dev->channel[2]; ++ int ret; ++ ++ ret = dvb_generic_open(inode, file); ++ if (ret < 0) ++ return ret; ++ dvb_ringbuffer_flush(&dev->ain_rbuf); ++ ++ chan2->Capture1Length = MAX_AUDIO_BUFFER_SIZE; ++ chan2->pBufferExchange = ain_exchange; ++ ngene_command_stream_control(chan2->dev, chan2->number, 0x80, ++ SMODE_AUDIO_CAPTURE, 0); ++ return ret; ++} ++ ++static int audio_release(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan2 = &chan->dev->channel[2]; ++ ++ ngene_command_stream_control(dev, 2, 0, 0, 0); ++ chan2->pBufferExchange = 0; ++ ++ return dvb_generic_release(inode, file); ++} ++ ++static const struct file_operations audio_fops = { ++ .owner = THIS_MODULE, ++ .read = audio_read, ++ .write = audio_write, ++ .open = audio_open, ++ .release = audio_release, ++}; ++ ++static struct dvb_device dvbdev_audio = { ++ .priv = 0, ++ .readers = -1, ++ .writers = 1, ++ .users = 1, ++ .fops = &audio_fops, ++}; ++ ++static int video_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan0 = &chan->dev->channel[0]; ++ int ret; ++ ++ ret = dvb_generic_open(inode, file); ++ if (ret < 0) ++ return ret; ++ if ((file->f_flags & O_ACCMODE) != O_RDONLY) ++ return ret; ++ dvb_ringbuffer_flush(&dev->vin_rbuf); ++ ++ chan0->nBytesPerLine = 1920 * 2; ++ chan0->nLines = 540; ++ chan0->Capture1Length = 1920 * 2 * 540; ++ chan0->pBufferExchange = vcap_exchange; ++ chan0->itumode = 2; ++ ngene_command_stream_control(chan0->dev, chan0->number, ++ 0x80, SMODE_VIDEO_CAPTURE, 0); ++ return ret; ++} ++ ++static int video_release(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan0 = &chan->dev->channel[0]; ++ ++ ngene_command_stream_control(dev, 0, 0, 0, 0); ++ chan0->pBufferExchange = 0; ++ ++ return dvb_generic_release(inode, file); ++} ++ ++static ssize_t video_write(struct file *file, ++ const char *buf, size_t count, loff_t *ppos) ++{ ++ return -EINVAL; ++} ++ ++ssize_t video_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int left, avail; ++ ++ left = count; ++ while (left) { ++ if (wait_event_interruptible( ++ dev->vin_rbuf.queue, ++ dvb_ringbuffer_avail(&dev->vin_rbuf) > 0) < 0) ++ return -EAGAIN; ++ avail = dvb_ringbuffer_avail(&dev->vin_rbuf); ++ if (avail > left) ++ avail = left; ++ dvb_ringbuffer_read_user(&dev->vin_rbuf, buf, avail); ++ left -= avail; ++ buf += avail; ++ } ++ return count; ++} ++ ++/* Why is this not exported from dvb_core ?!?! */ ++ ++static int dvb_usercopy2(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg, ++ int (*func)(struct inode *inode, struct file *file, ++ unsigned int cmd, void *arg)) ++{ ++ char sbuf[128]; ++ void *mbuf = NULL; ++ void *parg = NULL; ++ int err = -EINVAL; ++ ++ /* Copy arguments into temp kernel buffer */ ++ switch (_IOC_DIR(cmd)) { ++ case _IOC_NONE: ++ /* ++ * For this command, the pointer is actually an integer ++ * argument. ++ */ ++ parg = (void *)arg; ++ break; ++ case _IOC_READ: /* some v4l ioctls are marked wrong ... */ ++ case _IOC_WRITE: ++ case (_IOC_WRITE | _IOC_READ): ++ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { ++ parg = sbuf; ++ } else { ++ /* too big to allocate from stack */ ++ mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); ++ if (NULL == mbuf) ++ return -ENOMEM; ++ parg = mbuf; ++ } ++ ++ err = -EFAULT; ++ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) ++ goto out; ++ break; ++ } ++ ++ /* call driver */ ++ err = func(inode, file, cmd, parg); ++ if (err == -ENOIOCTLCMD) ++ err = -EINVAL; ++ ++ if (err < 0) ++ goto out; ++ ++ /* Copy results into user buffer */ ++ switch (_IOC_DIR(cmd)) { ++ case _IOC_READ: ++ case (_IOC_WRITE | _IOC_READ): ++ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) ++ err = -EFAULT; ++ break; ++ } ++ ++out: ++ kfree(mbuf); ++ return err; ++} ++ ++static int video_do_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int ret = 0; ++ unsigned long arg = (unsigned long)parg; ++ ++ switch (cmd) { ++ case VIDEO_SET_STREAMTYPE: ++ switch (arg) { ++ case VIDEO_CAP_MPEG2: ++ /* printk(KERN_INFO DEVICE_NAME ": setting MPEG2\n"); */ ++ send_cli(dev, "vdec mpeg2\n"); ++ break; ++ case VIDEO_CAP_AVC: ++ /* printk(KERN_INFO DEVICE_NAME ": setting H264\n"); */ ++ send_cli(dev, "vdec h264\n"); ++ break; ++ case VIDEO_CAP_VC1: ++ /* printk(KERN_INFO DEVICE_NAME ": setting VC1\n"); */ ++ send_cli(dev, "vdec vc1\n"); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ break; ++ default: ++ ret = -ENOIOCTLCMD; ++ return -EINVAL; ++ } ++ return ret; ++} ++ ++static int video_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy2(inode, file, cmd, arg, video_do_ioctl); ++} ++ ++static const struct file_operations video_fops = { ++ .owner = THIS_MODULE, ++ .read = video_read, ++ .write = video_write, ++ .open = video_open, ++ .release = video_release, ++ .ioctl = video_ioctl, ++}; ++ ++static struct dvb_device dvbdev_video = { ++ .priv = 0, ++ .readers = -1, ++ .writers = 1, ++ .users = -1, ++ .fops = &video_fops, ++}; ++#endif +diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c +index 039bed3..a8a1a03 100644 +--- a/drivers/media/pci/ngene/ngene-cards.c ++++ b/drivers/media/pci/ngene/ngene-cards.c +@@ -42,8 +42,18 @@ + #include "mt2131.h" + #include "tda18271c2dd.h" + #include "drxk.h" +-#include "drxd.h" +-#include "dvb-pll.h" ++#include "tda18212dd.h" ++#include "stv0367dd.h" ++#include "cxd2843.h" ++ ++ ++enum DEMOD_TYPE { ++ DMD_NONE = 0, ++ DMD_STV0900, ++ DMD_DRXK, ++ DMD_STV0367, ++ DMD_CXD28xx, ++}; + + + /****************************************************************************/ +@@ -86,8 +96,98 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) + return 0; + } + ++#if 0 ++static int tuner_attach_mt2060(struct ngene_channel *chan) ++{ ++ struct ngene *dev = chan->dev; ++ void *tconf = dev->card_info->tuner_config[chan->number]; ++ u8 drxa = dev->card_info->demoda[chan->number]; ++ struct dvb_frontend *fe = chan->fe, *fe2; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ fe->misc_priv = chan; ++#else ++ fe->sec_priv = chan; ++#endif ++ fe->ops.i2c_gate_ctrl = dev->card_info->gate_ctrl; ++ ++ dev->card_info->gate_ctrl(fe, 1); ++ fe2 = mt2060_attach(fe, &chan->i2c_adapter, tconf, 1220); ++ dev->card_info->gate_ctrl(fe, 0); ++ ++ i2c_write_register(&chan->i2c_adapter, drxa, 3, 4); ++ write_demod(&chan->i2c_adapter, drxa, 0x1012, 15); ++ write_demod(&chan->i2c_adapter, drxa, 0x1007, 0xc27); ++ write_demod(&chan->i2c_adapter, drxa, 0x0020, 0x003); ++ ++ return fe2 ? 0 : -ENODEV; ++} ++ ++static int tuner_attach_xc3028(struct ngene_channel *chan) ++{ ++ struct ngene *dev = chan->dev; ++ void *tconf = dev->card_info->tuner_config[chan->number]; ++ struct dvb_frontend *fe = chan->fe, *fe2; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ fe->misc_priv = chan; ++#else ++ fe->sec_priv = chan; ++#endif ++ fe->ops.i2c_gate_ctrl = dev->card_info->gate_ctrl; ++ ++ dev->card_info->gate_ctrl(fe, 1); ++ fe2 = xc3028_attach(fe, &chan->i2c_adapter, tconf); ++ dev->card_info->gate_ctrl(fe, 0); ++ ++ /*chan->fe->ops.tuner_ops.set_frequency(chan->fe,231250000);*/ ++ ++ return fe2 ? 0 : -ENODEV; ++} ++ ++static int demod_attach_drxd(struct ngene_channel *chan) ++{ ++ void *feconf = chan->dev->card_info->fe_config[chan->number]; ++ ++ chan->fe = drxd_attach(feconf, ++ chan, &chan->i2c_adapter, ++ &chan->dev->pci_dev->dev); ++ return (chan->fe) ? 0 : -ENODEV; ++} ++ ++static int demod_attach_drxh(struct ngene_channel *chan) ++{ ++ void *feconf = chan->dev->card_info->fe_config[chan->number]; ++ ++ chan->fe = drxh_attach(feconf, chan, ++ &chan->i2c_adapter, &chan->dev->pci_dev->dev); ++ return (chan->fe) ? 0 : -ENODEV; ++} ++ ++static int demod_attach_stb0899(struct ngene_channel *chan) ++{ ++ void *feconf = chan->dev->card_info->fe_config[chan->number]; ++ ++ chan->fe = stb0899_attach(feconf, ++ chan, &chan->i2c_adapter, ++ &chan->dev->pci_dev->dev); ++ if (chan->fe) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) ++ chan->set_tone = chan->fe->ops->set_tone; ++ chan->fe->ops->set_tone = lnbh21_set_tone; ++ chan->fe->ops->set_voltage = lnbh21_set_voltage; ++#else ++ chan->set_tone = chan->fe->ops.set_tone; ++ chan->fe->ops.set_tone = lnbh21_set_tone; ++ chan->fe->ops.set_voltage = lnbh21_set_voltage; ++#endif ++ } ++ ++ return (chan->fe) ? 0 : -ENODEV; ++} ++#endif + +-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) ++static int locked_gate_ctrl(struct dvb_frontend *fe, int enable) + { + struct ngene_channel *chan = fe->sec_priv; + int status; +@@ -121,12 +221,41 @@ static int tuner_attach_tda18271(struct ngene_channel *chan) + return 0; + } + ++static int tuner_attach_tda18212dd(struct ngene_channel *chan) ++{ ++ struct i2c_adapter *i2c; ++ struct dvb_frontend *fe; ++ u8 addr = (chan->number & 1) ? 0x63 : 0x60; ++ ++ if (chan->demod_type == DMD_CXD28xx && chan->number < 2) ++ addr ^= 0x04; ++ i2c = &chan->dev->channel[0].i2c_adapter; ++ fe = dvb_attach(tda18212dd_attach, chan->fe, i2c, addr); ++ if (!fe) { ++ printk(KERN_ERR "No TDA18212 found!\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++ + static int tuner_attach_probe(struct ngene_channel *chan) + { +- if (chan->demod_type == 0) ++ switch(chan->demod_type) ++ { ++ case DMD_STV0900: + return tuner_attach_stv6110(chan); +- if (chan->demod_type == 1) ++ ++ case DMD_DRXK: + return tuner_attach_tda18271(chan); ++ ++ case DMD_STV0367: ++ case DMD_CXD28xx: ++ return tuner_attach_tda18212dd(chan); ++ ++ default: ++ pr_err("Unknown demod %x\n", chan->demod_type); ++ break; ++ } + return -EINVAL; + } + +@@ -184,6 +313,26 @@ static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) + return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; + } + ++static int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1} }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ + static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + u16 reg, u8 *val) + { +@@ -195,6 +344,15 @@ static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; + } + ++static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ + static int port_has_stv0900(struct i2c_adapter *i2c, int port) + { + u8 val; +@@ -218,18 +376,154 @@ static int demod_attach_drxk(struct ngene_channel *chan, + struct drxk_config config; + + memset(&config, 0, sizeof(config)); +- config.microcode_name = "drxk_a3.mc"; +- config.qam_demod_parameter_count = 4; + config.adr = 0x29 + (chan->number ^ 2); ++ config.microcode_name = "drxk_a3.mc"; + ++#ifdef USE_API3 ++ chan->fe = dvb_attach(drxk_attach, &config, i2c, &chan->fe2); ++#else + chan->fe = dvb_attach(drxk_attach, &config, i2c); ++#endif + if (!chan->fe) { + printk(KERN_ERR "No DRXK found!\n"); + return -ENODEV; + } + chan->fe->sec_priv = chan; + chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; +- chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int port_has_stv0367(struct i2c_adapter *i2c, int port) ++{ ++ u8 val; ++ ++ if (i2c_read_reg16(i2c, 0x1c + (port ^ 1), 0xf000, &val) < 0) ++ return 0; ++ if (val != 0x60) ++ return 0; ++ return 1; ++} ++ ++static int demod_attach_stv0367dd(struct ngene_channel *chan, ++ struct i2c_adapter *i2c) ++{ ++ struct stv0367_cfg cfg; ++ ++ memset(&cfg, 0, sizeof cfg); ++ cfg.adr = 0x1c + (chan->number ^ 1); ++ ++ chan->fe = dvb_attach(stv0367_attach, i2c, &cfg, &chan->fe2); ++ if (!chan->fe) { ++ printk(KERN_ERR "No stv0367 found!\n"); ++ return -ENODEV; ++ } ++ chan->fe->sec_priv = chan; ++ chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int port_has_xo2(struct i2c_adapter *i2c, int port, u8 *id) ++{ ++ u8 addr = (port < 2) ? 0x14 : 0x10; ++ u8 val; ++ u8 probe[1] = { 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = addr, .flags = 0, ++ .buf = probe, .len = 1 }, ++ { .addr = addr, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++#if 0 ++ u8 cfg[] = { 0x79, 0x00, 0x00 }; ++ struct i2c_msg cmsg = { .addr = 0x44, .flags = 0, ++ .buf = cfg, .len = 3 }; ++ if (port == 0) ++ i2c_transfer(i2c, &cmsg, 1); ++ pr_info("chan %d addr %x\n", port, addr); ++ msleep(1000); ++#endif ++ val = i2c_transfer(i2c, msgs, 2); ++ if (val != 2) ++ return 0; ++ ++ if (data[0] != 'D' || data[1] != 'F') ++ return 0; ++ ++ *id = data[2]; ++ return 1; ++} ++ ++static int init_xo2(struct i2c_adapter *i2c, int port) ++{ ++ u8 addr = (port < 2) ? 0x14 : 0x10; ++ u8 val, data[2]; ++ int res; ++ ++ if (port & 1) ++ return 0; ++ ++ res = i2c_read_regs(i2c, addr, 0x04, data, 2); ++ if (res < 0) ++ return res; ++ ++ if (data[0] != 0x01) { ++ pr_info("Invalid XO2\n"); ++ return -1; ++ } ++ ++ i2c_read_reg(i2c, addr, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, addr, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, addr, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, addr, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, addr, 0x08, 0x87); ++ ++ return 0; ++} ++ ++#define DDB_TUNER_XO2 16 ++#define DDB_TUNER_DVBS_STV0910 16 ++#define DDB_TUNER_DVBCT2_SONY 17 ++#define DDB_TUNER_ISDBT_SONY 18 ++#define DDB_TUNER_DVBC2T2_SONY 19 ++#define DDB_TUNER_ATSC_ST 20 ++#define DDB_TUNER_DVBC2T2_ST 21 ++ ++static char *xo2names[] = { ++ "DUAL DVB-S2", ++ "DUAL DVB-C/T/T2", ++ "DUAL DVB-ISDBT", ++ "DUAL DVB-C/C2/T/T2", ++ "DUAL ATSC", ++ "DUAL DVB-C/C2/T/T2", ++ "", "" ++}; ++ ++struct cxd2843_cfg cxd2843[] = { ++ { .adr = 0x68, }, ++ { .adr = 0x69, }, ++ { .adr = 0x6c, }, ++ { .adr = 0x6d, }, ++}; ++ ++static int demod_attach_cxd2843(struct ngene_channel *chan, ++ struct i2c_adapter *i2c) ++{ ++ chan->fe = dvb_attach(cxd2843_attach, i2c, cxd2843+chan->number); ++ if (!chan->fe) { ++ pr_err("No cxd2837/38/43 found!\n"); ++ return -ENODEV; ++ } ++ chan->fe->sec_priv = chan; ++ chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; + return 0; + } + +@@ -240,6 +534,7 @@ static int cineS2_probe(struct ngene_channel *chan) + u8 buf[3]; + struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; + int rc; ++ u8 id; + + /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ + if (chan->number < 2) +@@ -247,8 +542,33 @@ static int cineS2_probe(struct ngene_channel *chan) + else + i2c = &chan->dev->channel[1].i2c_adapter; + +- if (port_has_stv0900(i2c, chan->number)) { +- chan->demod_type = 0; ++ if (port_has_xo2(i2c, chan->number, &id)) { ++ id >>= 2; ++ if (id > 5) { ++ pr_info("Channel %d: Unknown XO2 DuoFlex %u\n", ++ chan->number, id); ++ return -ENODEV; ++ } ++ init_xo2(i2c, chan->number); ++ switch(DDB_TUNER_XO2 + id) ++ { ++ case DDB_TUNER_DVBCT2_SONY: ++ case DDB_TUNER_ISDBT_SONY: ++ case DDB_TUNER_DVBC2T2_SONY: ++ chan->demod_type = DMD_CXD28xx; ++ pr_info("Channel %d: %s\n", chan->number, xo2names[id]); ++ demod_attach_cxd2843(chan, i2c); ++ break; ++ default: ++ pr_info("Channel %d: %s not supported yet\n", ++ chan->number, xo2names[id]); ++ return -ENODEV; ++ } ++ ++ } else if (chan->dev->channel[0].demod_type != DMD_CXD28xx && ++ port_has_stv0900(i2c, chan->number)) { ++ chan->demod_type = DMD_STV0900; ++ pr_info("Channel %d: STV0900\n", chan->number); + fe_conf = chan->dev->card_info->fe_config[chan->number]; + /* demod found, attach it */ + rc = demod_attach_stv0900(chan); +@@ -276,9 +596,17 @@ static int cineS2_probe(struct ngene_channel *chan) + printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); + return -EIO; + } ++ + } else if (port_has_drxk(i2c, chan->number^2)) { +- chan->demod_type = 1; ++ chan->demod_type = DMD_DRXK; ++ pr_info("Channel %d: DRXK\n", chan->number); + demod_attach_drxk(chan, i2c); ++ ++ } else if (port_has_stv0367(i2c, chan->number)) { ++ chan->demod_type = DMD_STV0367; ++ pr_info("Channel %d: STV0367\n", chan->number); ++ demod_attach_stv0367dd(chan, i2c); ++ + } else { + printk(KERN_ERR "No demod found on chan %d\n", chan->number); + return -ENODEV; +@@ -315,249 +643,140 @@ static int demod_attach_lg330x(struct ngene_channel *chan) + return (chan->fe) ? 0 : -ENODEV; + } + +-static int demod_attach_drxd(struct ngene_channel *chan) +-{ +- struct drxd_config *feconf; +- +- feconf = chan->dev->card_info->fe_config[chan->number]; +- +- chan->fe = dvb_attach(drxd_attach, feconf, chan, +- &chan->i2c_adapter, &chan->dev->pci_dev->dev); +- if (!chan->fe) { +- pr_err("No DRXD found!\n"); +- return -ENODEV; +- } +- return 0; +-} ++/****************************************************************************/ ++/* Switch control (I2C gates, etc.) *****************************************/ ++/****************************************************************************/ + +-static int tuner_attach_dtt7520x(struct ngene_channel *chan) ++#if 0 ++static int avf_output(struct ngene_channel *chan, int state) + { +- struct drxd_config *feconf; +- +- feconf = chan->dev->card_info->fe_config[chan->number]; +- +- if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address, +- &chan->i2c_adapter, +- feconf->pll_type)) { +- pr_err("No pll(%d) found!\n", feconf->pll_type); +- return -ENODEV; +- } ++ if (chan->dev->card_info->avf[chan->number]) ++ i2c_write_register(&chan->i2c_adapter, ++ chan->dev->card_info->avf[chan->number], ++ 0xf2, state ? 0x89 : 0x80); + return 0; + } + +-/****************************************************************************/ +-/* EEPROM TAGS **************************************************************/ +-/****************************************************************************/ +- +-#define MICNG_EE_START 0x0100 +-#define MICNG_EE_END 0x0FF0 +- +-#define MICNG_EETAG_END0 0x0000 +-#define MICNG_EETAG_END1 0xFFFF +- +-/* 0x0001 - 0x000F reserved for housekeeping */ +-/* 0xFFFF - 0xFFFE reserved for housekeeping */ +- +-/* Micronas assigned tags +- EEProm tags for hardware support */ +- +-#define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */ +-#define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */ +- +-#define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ +-#define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ ++/* Viper expander: sw11,sw12,sw21,sw22,i2csw1,i2csw2,tsen1,tsen2 */ + +-/* Tag range for OEMs */ ++static int exp_set(struct ngene *dev) ++{ ++ return i2c_write(&dev->channel[0].i2c_adapter, ++ dev->card_info->exp, dev->exp_val); ++} + +-#define MICNG_EETAG_OEM_FIRST 0xC000 +-#define MICNG_EETAG_OEM_LAST 0xFFEF ++static int exp_init(struct ngene *dev) ++{ ++ if (!dev->card_info->exp) ++ return 0; ++ dev->exp_val = dev->card_info->exp_init; ++ return exp_set(dev); ++} + +-static int i2c_write_eeprom(struct i2c_adapter *adapter, +- u8 adr, u16 reg, u8 data) ++static int exp_set_bit(struct ngene *dev, int bit, int val) + { +- u8 m[3] = {(reg >> 8), (reg & 0xff), data}; +- struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, +- .len = sizeof(m)}; ++ if (val) ++ set_bit(bit, &dev->exp_val); ++ else ++ clear_bit(bit, &dev->exp_val); ++ return exp_set(dev); ++} + +- if (i2c_transfer(adapter, &msg, 1) != 1) { +- pr_err(DEVICE_NAME ": Error writing EEPROM!\n"); +- return -EIO; ++static int viper_switch_ctrl(struct ngene_channel *chan, int type, int val) ++{ ++ switch (type) { ++ case 0: /* I2C tuner gate on/off */ ++ return exp_set_bit(chan->dev, 4 + chan->number, val); ++ case 1: /* Stream: 0=TS 1=ITU */ ++ avf_output(chan, val); ++ return exp_set_bit(chan->dev, 6 + chan->number, val); ++ case 2: /* Input: 0=digital 1=analog antenna input */ ++ exp_set_bit(chan->dev, 0 + chan->number * 2, val ? 0 : 1); ++ exp_set_bit(chan->dev, 1 + chan->number * 2, val ? 1 : 0); ++ break; + } + return 0; + } + +-static int i2c_read_eeprom(struct i2c_adapter *adapter, +- u8 adr, u16 reg, u8 *data, int len) ++static int viper_switch_ctrl2(struct ngene_channel *chan, int type, int val) + { +- u8 msg[2] = {(reg >> 8), (reg & 0xff)}; +- struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, +- .buf = msg, .len = 2 }, +- {.addr = adr, .flags = I2C_M_RD, +- .buf = data, .len = len} }; +- +- if (i2c_transfer(adapter, msgs, 2) != 2) { +- pr_err(DEVICE_NAME ": Error reading EEPROM\n"); +- return -EIO; ++ switch (type) { ++ case 0: /* I2C tuner gate on/off */ ++ return exp_set_bit(chan->dev, 4 + chan->number, val); ++ case 1: /* Stream: 0=TS 1=ITU */ ++ avf_output(chan, val); ++ return exp_set_bit(chan->dev, 6 + chan->number, val); ++ case 2: /* Input: 0=digital 1=analog antenna input */ ++ exp_set_bit(chan->dev, 0 + chan->number * 2, val ? 0 : 1); ++ exp_set_bit(chan->dev, 1 + chan->number * 2, 0); ++ break; + } + return 0; + } + +-static int ReadEEProm(struct i2c_adapter *adapter, +- u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) ++static int viper_gate_ctrl(struct dvb_frontend *fe, int enable) + { +- int status = 0; +- u16 Addr = MICNG_EE_START, Length, tag = 0; +- u8 EETag[3]; +- +- while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { +- if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) +- return -1; +- tag = (EETag[0] << 8) | EETag[1]; +- if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) +- return -1; +- if (tag == Tag) +- break; +- Addr += sizeof(u16) + 1 + EETag[2]; +- } +- if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { +- pr_err(DEVICE_NAME +- ": Reached EOEE @ Tag = %04x Length = %3d\n", +- tag, EETag[2]); +- return -1; +- } +- Length = EETag[2]; +- if (Length > MaxLen) +- Length = (u16) MaxLen; +- if (Length > 0) { +- Addr += sizeof(u16) + 1; +- status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length); +- if (!status) { +- *pLength = EETag[2]; +-#if 0 +- if (Length < EETag[2]) +- status = STATUS_BUFFER_OVERFLOW; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ struct ngene_channel *chan = fe->misc_priv; ++#else /* Why is there no misc_priv available anymore !?!?! */ ++ /* Well, just abuse sec :-) */ ++ struct ngene_channel *chan = fe->sec_priv; + #endif +- } +- } +- return status; ++ struct ngene *dev = chan->dev; ++ ++ return dev->card_info->switch_ctrl(chan, 0, enable); + } + +-static int WriteEEProm(struct i2c_adapter *adapter, +- u16 Tag, u32 Length, u8 *data) ++static int python_switch_ctrl(struct ngene_channel *chan, int type, int val) + { +- int status = 0; +- u16 Addr = MICNG_EE_START; +- u8 EETag[3]; +- u16 tag = 0; +- int retry, i; +- +- while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { +- if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) +- return -1; +- tag = (EETag[0] << 8) | EETag[1]; +- if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) +- return -1; +- if (tag == Tag) +- break; +- Addr += sizeof(u16) + 1 + EETag[2]; +- } +- if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { +- pr_err(DEVICE_NAME +- ": Reached EOEE @ Tag = %04x Length = %3d\n", +- tag, EETag[2]); +- return -1; +- } +- +- if (Length > EETag[2]) +- return -EINVAL; +- /* Note: We write the data one byte at a time to avoid +- issues with page sizes. (which are different for +- each manufacture and eeprom size) +- */ +- Addr += sizeof(u16) + 1; +- for (i = 0; i < Length; i++, Addr++) { +- status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]); +- +- if (status) +- break; +- +- /* Poll for finishing write cycle */ +- retry = 10; +- while (retry) { +- u8 Tmp; +- +- msleep(50); +- status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1); +- if (status) +- break; +- if (Tmp != data[i]) +- pr_err(DEVICE_NAME +- "eeprom write error\n"); +- retry -= 1; +- } +- if (status) { +- pr_err(DEVICE_NAME +- ": Timeout polling eeprom\n"); +- break; +- } ++ switch (type) { ++ case 0: /* I2C tuner gate on/off */ ++ if (chan->number > 1) ++ return -EINVAL; ++ return ngene_command_gpio_set(chan->dev, 3 + chan->number, val); ++ case 1: /* Stream: 0=TS 1=ITU */ ++ avf_output(chan, val); ++ return 0; + } +- return status; ++ return 0; + } + +-static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data) ++static int viper_reset_xc(struct dvb_frontend *fe) + { +- int stat; +- u8 buf[2]; +- u32 len = 0; +- +- stat = ReadEEProm(adapter, tag, 2, buf, &len); +- if (stat) +- return stat; +- if (len != 2) +- return -EINVAL; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ struct ngene_channel *chan = fe->misc_priv; ++#else ++ struct ngene_channel *chan = fe->sec_priv; ++#endif ++ struct ngene *dev = chan->dev; + +- *data = (buf[0] << 8) | buf[1]; +- return 0; +-} ++ printk(KERN_INFO DEVICE_NAME ": Reset XC3028\n"); + +-static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data) +-{ +- int stat; +- u8 buf[2]; ++ if (chan->number > 1) ++ return -EINVAL; + +- buf[0] = data >> 8; +- buf[1] = data & 0xff; +- stat = WriteEEProm(adapter, tag, 2, buf); +- if (stat) +- return stat; ++ ngene_command_gpio_set(dev, 3 + chan->number, 0); ++ msleep(150); ++ ngene_command_gpio_set(dev, 3 + chan->number, 1); + return 0; + } + +-static s16 osc_deviation(void *priv, s16 deviation, int flag) ++static int python_gate_ctrl(struct dvb_frontend *fe, int enable) + { +- struct ngene_channel *chan = priv; +- struct i2c_adapter *adap = &chan->i2c_adapter; +- u16 data = 0; +- +- if (flag) { +- data = (u16) deviation; +- pr_info(DEVICE_NAME ": write deviation %d\n", +- deviation); +- eeprom_write_ushort(adap, 0x1000 + chan->number, data); +- } else { +- if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data)) +- data = 0; +- pr_info(DEVICE_NAME ": read deviation %d\n", +- (s16) data); +- } ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ struct ngene_channel *chan = fe->misc_priv; ++#else /* Why is there no misc_priv available anymore !?!?! */ ++ struct ngene_channel *chan = fe->sec_priv; ++#endif ++ struct ngene *dev = chan->dev; + +- return (s16) data; ++ if (chan->number == 0) ++ return ngene_command_gpio_set(dev, 3, enable); ++ if (chan->number == 1) ++ return ngene_command_gpio_set(dev, 4, enable); ++ return -EINVAL; + } +- +-/****************************************************************************/ +-/* Switch control (I2C gates, etc.) *****************************************/ +-/****************************************************************************/ +- ++#endif + + static struct stv090x_config fe_cineS2 = { + .device = STV0900, +@@ -696,7 +915,7 @@ static struct ngene_info ngene_info_m780 = { + .demod_attach = { NULL, demod_attach_lg330x }, + + /* Ensure these are NULL else the frame will call them (as funcs) */ +- .tuner_attach = { NULL, NULL, NULL, NULL }, ++ .tuner_attach = { 0, 0, 0, 0 }, + .fe_config = { NULL, &aver_m780 }, + .avf = { 0 }, + +@@ -705,14 +924,18 @@ static struct ngene_info ngene_info_m780 = { + .fw_version = 15, + }; + ++/****************************************************************************/ ++ ++#if 0 + static struct drxd_config fe_terratec_dvbt_0 = { + .index = 0, + .demod_address = 0x70, + .demod_revision = 0xa2, + .demoda_address = 0x00, + .pll_address = 0x60, +- .pll_type = DVB_PLL_THOMSON_DTT7520X, ++ .pll_type = DRXD_PLL_DTT7520X, + .clock = 20000, ++ .pll_set = ngene_pll_set_th_dtt7520x, + .osc_deviation = osc_deviation, + }; + +@@ -722,8 +945,9 @@ static struct drxd_config fe_terratec_dvbt_1 = { + .demod_revision = 0xa2, + .demoda_address = 0x00, + .pll_address = 0x60, +- .pll_type = DVB_PLL_THOMSON_DTT7520X, ++ .pll_type = DRXD_PLL_DTT7520X, + .clock = 20000, ++ .pll_set = ngene_pll_set_th_dtt7520x, + .osc_deviation = osc_deviation, + }; + +@@ -732,13 +956,293 @@ static struct ngene_info ngene_info_terratec = { + .name = "Terratec Integra/Cinergy2400i Dual DVB-T", + .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, + .demod_attach = {demod_attach_drxd, demod_attach_drxd}, +- .tuner_attach = {tuner_attach_dtt7520x, tuner_attach_dtt7520x}, + .fe_config = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1}, + .i2c_access = 1, + }; + + /****************************************************************************/ + ++static struct mt2060_config tuner_python_0 = { ++ .i2c_address = 0x60, ++ .clock_out = 3, ++ .input = 0 ++}; ++ ++static struct mt2060_config tuner_python_1 = { ++ .i2c_address = 0x61, ++ .clock_out = 3, ++ .input = 1 ++}; ++ ++static struct drxd_config fe_python_0 = { ++ .index = 0, ++ .demod_address = 0x71, ++ .demod_revision = 0xb1, ++ .demoda_address = 0x41, ++ .clock = 16000, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct drxd_config fe_python_1 = { ++ .index = 1, ++ .demod_address = 0x70, ++ .demod_revision = 0xb1, ++ .demoda_address = 0x45, ++ .clock = 16000, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct ngene_info ngene_info_python = { ++ .type = NGENE_PYTHON, ++ .name = "Micronas MicPython/Hedgehog Dual DVB-T", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxd, demod_attach_drxd}, ++ .tuner_attach = {tuner_attach_mt2060, tuner_attach_mt2060}, ++ .fe_config = {&fe_python_0, &fe_python_1}, ++ .tuner_config = {&tuner_python_0, &tuner_python_1}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .demoda = {0x41, 0x45}, ++ .gate_ctrl = python_gate_ctrl, ++ .switch_ctrl = python_switch_ctrl, ++}; ++ ++/****************************************************************************/ ++ ++static struct drxd_config fe_appb_dvbt_0 = { ++ .index = 0, ++ .demod_address = 0x71, ++ .demod_revision = 0xa2, ++ .demoda_address = 0x41, ++ .pll_address = 0x63, ++ .pll_type = DRXD_PLL_MT3X0823, ++ .clock = 20000, ++ .pll_set = ngene_pll_set_mt_3x0823, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct drxd_config fe_appb_dvbt_1 = { ++ .index = 1, ++ .demod_address = 0x70, ++ .demod_revision = 0xa2, ++ .demoda_address = 0x45, ++ .pll_address = 0x60, ++ .pll_type = DRXD_PLL_MT3X0823, ++ .clock = 20000, ++ .pll_set = ngene_pll_set_mt_3x0823, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct ngene_info ngene_info_appboard = { ++ .type = NGENE_APP, ++ .name = "Micronas Application Board Dual DVB-T", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_drxd, demod_attach_drxd}, ++ .fe_config = {&fe_appb_dvbt_0, &fe_appb_dvbt_1}, ++ .avf = {0x43, 0x47}, ++}; ++ ++static struct ngene_info ngene_info_appboard_ntsc = { ++ .type = NGENE_APP, ++ .name = "Micronas Application Board Dual DVB-T", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_drxd, demod_attach_drxd}, ++ .fe_config = {&fe_appb_dvbt_0, &fe_appb_dvbt_1}, ++ .avf = {0x43, 0x47}, ++ .ntsc = 1, ++}; ++ ++/****************************************************************************/ ++ ++static struct stb0899_config fe_sidewinder_0 = { ++ .demod_address = 0x68, ++ .pll_address = 0x63, ++}; ++ ++static struct stb0899_config fe_sidewinder_1 = { ++ .demod_address = 0x6b, ++ .pll_address = 0x60, ++}; ++ ++static struct ngene_info ngene_info_sidewinder = { ++ .type = NGENE_SIDEWINDER, ++ .name = "Micronas MicSquirrel/Sidewinder Dual DVB-S2", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_stb0899, demod_attach_stb0899}, ++ .fe_config = {&fe_sidewinder_0, &fe_sidewinder_1}, ++ .lnb = {0x0b, 0x08}, ++}; ++ ++/****************************************************************************/ ++/* Yet unnamed S2 card with dual DVB-S2 demod */ ++/****************************************************************************/ ++ ++static struct stv0900_config fe_s2_0 = { ++ .addr = 0x68, ++ .pll = 0x63, ++ .pll_type = 0, ++ .nr = 0, ++}; ++ ++static struct stv0900_config fe_s2_1 = { ++ .addr = 0x68, ++ .pll = 0x60, ++ .pll_type = 0, ++ .nr = 1, ++}; ++ ++static struct ngene_info ngene_info_s2 = { ++ .type = NGENE_SIDEWINDER, ++ .name = "S2", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, ++ NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, ++ .fe_config = {&fe_s2_0, &fe_s2_1}, ++ .lnb = {0x0b, 0x08}, ++ .tsf = {3, 3}, ++ .fw_version = 15, ++}; ++ ++static struct stv0900_config fe_s2b_0 = { ++ .addr = 0x68, ++ .pll = 0x60, ++ .pll_type = 0x10, ++ .nr = 0, ++}; ++ ++static struct stv0900_config fe_s2b_1 = { ++ .addr = 0x68, ++ .pll = 0x63, ++ .pll_type = 0x10, ++ .nr = 1, ++}; ++ ++static struct ngene_info ngene_info_s2_b = { ++ .type = NGENE_SIDEWINDER, ++ .name = "S2 V2", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, ++ NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, ++ .fe_config = {&fe_s2b_0, &fe_s2b_1}, ++ .lnb = {0x0b, 0x08}, ++ .tsf = {3, 3}, ++ .fw_version = 17, ++}; ++ ++/****************************************************************************/ ++ ++static struct xc3028_config tuner_viper_0 = { ++ .adr = 0x61, ++ .reset = viper_reset_xc ++}; ++ ++static struct xc3028_config tuner_viper_1 = { ++ .adr = 0x64, ++ .reset = viper_reset_xc ++}; ++ ++static struct drxh_config fe_viper_h_0 = {.adr = 0x2b}; ++ ++static struct drxh_config fe_viper_h_1 = {.adr = 0x29}; ++ ++static struct drxh_config fe_viper_l_0 = {.adr = 0x2b, .type = 3931}; ++ ++static struct drxh_config fe_viper_l_1 = {.adr = 0x29, .type = 3931}; ++ ++static struct ngene_info ngene_info_viper_v1 = { ++ .type = NGENE_VIPER, ++ .name = "Micronas MicViper Dual ATSC DRXH", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_h_0, &fe_viper_h_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x20, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl, ++ .tsf = {2, 2}, ++}; ++ ++static struct ngene_info ngene_info_viper_v2 = { ++ .type = NGENE_VIPER, ++ .name = "Micronas MicViper Dual ATSC DRXL", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_l_0, &fe_viper_l_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x38, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl, ++ .tsf = {2, 2}, ++}; ++ ++/****************************************************************************/ ++ ++static struct ngene_info ngene_info_vbox_v1 = { ++ .type = NGENE_VBOX_V1, ++ .name = "VBox Cat's Eye 164E", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_h_0, &fe_viper_h_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x20, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl, ++ .tsf = {2, 2}, ++}; ++ ++/****************************************************************************/ ++ ++static struct ngene_info ngene_info_vbox_v2 = { ++ .type = NGENE_VBOX_V2, ++ .name = "VBox Cat's Eye 164E", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_h_0, &fe_viper_h_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x20, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl2, ++ .tsf = {2, 2}, ++}; ++ ++/****************************************************************************/ ++ ++static struct ngene_info ngene_info_racer = { ++ .type = NGENE_RACER, ++ .name = "Micronas MicRacer HDTV Decoder Card", ++ .io_type = {NGENE_IO_HDTV, NGENE_IO_NONE, ++ NGENE_IO_AIN, NGENE_IO_NONE, ++ NGENE_IO_TSOUT}, ++ .i2s = {0, 0, 1, 0}, ++ .fw_version = 17, ++}; ++#endif + + + /****************************************************************************/ +@@ -753,6 +1257,8 @@ static struct ngene_info ngene_info_terratec = { + /****************************************************************************/ + + static const struct pci_device_id ngene_id_tbl[] = { ++ NGENE_ID(0x18c3, 0xab04, ngene_info_cineS2), ++ NGENE_ID(0x18c3, 0xab05, ngene_info_cineS2v5), + NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), + NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), + NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), +@@ -761,7 +1267,32 @@ static const struct pci_device_id ngene_id_tbl[] = { + NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex), + NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex), + NGENE_ID(0x1461, 0x062e, ngene_info_m780), ++#if 0 /* not (yet?) supported */ ++ NGENE_ID(0x18c3, 0x0000, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x0004, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x8011, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x8015, ngene_info_appboard_ntsc), + NGENE_ID(0x153b, 0x1167, ngene_info_terratec), ++ NGENE_ID(0x18c3, 0x0030, ngene_info_python), ++ NGENE_ID(0x18c3, 0x0052, ngene_info_sidewinder), ++ NGENE_ID(0x18c3, 0x8f00, ngene_info_racer), ++ NGENE_ID(0x18c3, 0x0041, ngene_info_viper_v1), ++ NGENE_ID(0x18c3, 0x0042, ngene_info_viper_v2), ++ NGENE_ID(0x14f3, 0x0041, ngene_info_vbox_v1), ++ NGENE_ID(0x14f3, 0x0043, ngene_info_vbox_v2), ++ NGENE_ID(0x18c3, 0xabcd, ngene_info_s2), ++ NGENE_ID(0x18c3, 0xabc2, ngene_info_s2_b), ++ NGENE_ID(0x18c3, 0xabc3, ngene_info_s2_b), ++ NGENE_ID(0x18c3, 0x0001, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x0005, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x0009, ngene_info_appboard_atsc), ++ NGENE_ID(0x18c3, 0x000b, ngene_info_appboard_atsc), ++ NGENE_ID(0x18c3, 0x0010, ngene_info_shrek_50_fp), ++ NGENE_ID(0x18c3, 0x0011, ngene_info_shrek_60_fp), ++ NGENE_ID(0x18c3, 0x0012, ngene_info_shrek_50), ++ NGENE_ID(0x18c3, 0x0013, ngene_info_shrek_60), ++ NGENE_ID(0x18c3, 0x0000, ngene_info_hognose), ++#endif + {0} + }; + MODULE_DEVICE_TABLE(pci, ngene_id_tbl); +@@ -798,7 +1329,7 @@ static void ngene_resume(struct pci_dev *dev) + printk(KERN_INFO DEVICE_NAME ": resume\n"); + } + +-static const struct pci_error_handlers ngene_errors = { ++static struct pci_error_handlers ngene_errors = { + .error_detected = ngene_error_detected, + .link_reset = ngene_link_reset, + .slot_reset = ngene_slot_reset, +diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c +index e29bc3af..84510db 100644 +--- a/drivers/media/pci/ngene/ngene-core.c ++++ b/drivers/media/pci/ngene/ngene-core.c +@@ -57,13 +57,15 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + + #define dprintk if (debug) printk + +-#define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) +-#define ngwritel(dat, adr) writel((dat), dev->iomem + (adr)) +-#define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) ++#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) ++#define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr))) ++#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) + #define ngreadl(adr) readl(dev->iomem + (adr)) + #define ngreadb(adr) readb(dev->iomem + (adr)) +-#define ngcpyto(adr, src, count) memcpy_toio(dev->iomem + (adr), (src), (count)) +-#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), dev->iomem + (adr), (count)) ++#define ngcpyto(adr, src, count) memcpy_toio((char *) \ ++ (dev->iomem + (adr)), (src), (count)) ++#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \ ++ (dev->iomem + (adr)), (count)) + + /****************************************************************************/ + /* nGene interrupt handler **************************************************/ +@@ -84,6 +86,14 @@ static void event_tasklet(unsigned long data) + if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify)) + dev->RxEventNotify(dev, Event.TimeStamp, + Event.RXCharacter); ++#if 0 ++ if ((Event.GPIOStatus & 0x80) && (dev->Gpio2EventNotify)) ++ dev->Gpio2EventNotify(dev, Event.TimeStamp, ++ Event.GPIOStatus & 0x1f); ++ if ((Event.GPIOStatus & 0x40) && (dev->Gpio3EventNotify)) ++ dev->Gpio3EventNotify(dev, Event.TimeStamp, ++ Event.GPIOStatus & 0x1f); ++#endif + } + } + +@@ -212,6 +222,13 @@ static irqreturn_t irq_handler(int irq, void *dev_id) + u8 nextWriteIndex = + (dev->EventQueueWriteIndex + 1) & + (EVENT_QUEUE_SIZE - 1); ++#if 0 ++ printk(KERN_ERR DEVICE_NAME ++ ": Event interrupt %02x Uart = %02x Gpio = %02x\n", ++ dev->EventBuffer->EventStatus, ++ dev->EventBuffer->UARTStatus, ++ dev->EventBuffer->GPIOStatus); ++#endif + if (nextWriteIndex != dev->EventQueueReadIndex) { + dev->EventQueue[dev->EventQueueWriteIndex] = + *(dev->EventBuffer); +@@ -256,16 +273,22 @@ static void dump_command_io(struct ngene *dev) + u8 buf[8], *b; + + ngcpyfrom(buf, HOST_TO_NGENE, 8); +- printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf); ++ printk(KERN_ERR "host_to_ngene (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ HOST_TO_NGENE, buf[0], buf[1], buf[2], buf[3], ++ buf[4], buf[5], buf[6], buf[7]); + + ngcpyfrom(buf, NGENE_TO_HOST, 8); +- printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf); ++ printk(KERN_ERR "ngene_to_host (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ NGENE_TO_HOST, buf[0], buf[1], buf[2], buf[3], ++ buf[4], buf[5], buf[6], buf[7]); + + b = dev->hosttongene; +- printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b); ++ printk(KERN_ERR "dev->hosttongene (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + + b = dev->ngenetohost; +- printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b); ++ printk(KERN_ERR "dev->ngenetohost (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + } + + static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) +@@ -314,12 +337,24 @@ static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) + ngwritel(1, FORCE_INT); + + ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ); ++#if 0 ++ if (ret < 0) ++ return ret; ++ if (!dev->cmd_done) ++ ; ++#endif + if (!ret) { + /*ngwritel(0, FORCE_NMI);*/ + + printk(KERN_ERR DEVICE_NAME + ": Command timeout cmd=%02x prev=%02x\n", + com->cmd.hdr.Opcode, dev->prev_cmd); ++#if 0 ++ printk(KERN_ERR DEVICE_NAME ": Icounts=%08x\n", ++ ngreadl(NGENE_INT_COUNTS)); ++ if (ngreadl(NGENE_INT_COUNTS) == 0xffffffff) ++ ngwritel(0, NGENE_INT_ENABLE); ++#endif + dump_command_io(dev); + return -1; + } +@@ -346,6 +381,19 @@ int ngene_command(struct ngene *dev, struct ngene_command *com) + return result; + } + ++#if 0 ++int ngene_command_nop(struct ngene *dev) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = CMD_NOP; ++ com.cmd.hdr.Length = 0; ++ com.in_len = 0; ++ com.out_len = 0; ++ ++ return ngene_command(dev, &com); ++} ++#endif + + static int ngene_command_load_firmware(struct ngene *dev, + u8 *ngene_fw, u32 size) +@@ -380,6 +428,83 @@ static int ngene_command_load_firmware(struct ngene *dev, + return ngene_command(dev, &com); + } + ++#if 0 ++int ngene_command_imem_read(struct ngene *dev, u8 adr, u8 *data, int type) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = type ? CMD_SFR_READ : CMD_IRAM_READ; ++ com.cmd.hdr.Length = 1; ++ com.cmd.SfrIramRead.address = adr; ++ com.in_len = 1; ++ com.out_len = 2; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ *data = com.cmd.raw8[1]; ++ return 0; ++} ++ ++int ngene_command_imem_write(struct ngene *dev, u8 adr, u8 data, int type) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = type ? CMD_SFR_WRITE : CMD_IRAM_WRITE; ++ com.cmd.hdr.Length = 2; ++ com.cmd.SfrIramWrite.address = adr; ++ com.cmd.SfrIramWrite.data = data; ++ com.in_len = 2; ++ com.out_len = 1; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int ngene_command_config_uart(struct ngene *dev, u8 config, ++ tx_cb_t *tx_cb, rx_cb_t *rx_cb) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = CMD_CONFIGURE_UART; ++ com.cmd.hdr.Length = sizeof(struct FW_CONFIGURE_UART) - 2; ++ com.cmd.ConfigureUart.UartControl = config; ++ com.in_len = sizeof(struct FW_CONFIGURE_UART); ++ com.out_len = 0; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ dev->TxEventNotify = tx_cb; ++ dev->RxEventNotify = rx_cb; ++ ++ dprintk(KERN_DEBUG DEVICE_NAME ": Set UART config %02x.\n", config); ++ ++ return 0; ++} ++ ++static void tx_cb(struct ngene *dev, u32 ts) ++{ ++ dev->tx_busy = 0; ++ wake_up_interruptible(&dev->tx_wq); ++} ++ ++static void rx_cb(struct ngene *dev, u32 ts, u8 c) ++{ ++ int rp = dev->uart_rp; ++ int nwp, wp = dev->uart_wp; ++ ++ /* dprintk(KERN_DEBUG DEVICE_NAME ": %c\n", c); */ ++ nwp = (wp + 1) % (UART_RBUF_LEN); ++ if (nwp == rp) ++ return; ++ dev->uart_rbuf[wp] = c; ++ dev->uart_wp = nwp; ++ wake_up_interruptible(&dev->rx_wq); ++} ++#endif + + static int ngene_command_config_buf(struct ngene *dev, u8 config) + { +@@ -425,6 +550,18 @@ int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level) + return ngene_command(dev, &com); + } + ++#if 0 ++/* The reset is only wired to GPIO4 on MicRacer Revision 1.10 ! ++ Also better set bootdelay to 1 in nvram or less. */ ++static void ngene_reset_decypher(struct ngene *dev) ++{ ++ printk(KERN_INFO DEVICE_NAME ": Resetting Decypher.\n"); ++ ngene_command_gpio_set(dev, 4, 0); ++ msleep(1); ++ ngene_command_gpio_set(dev, 4, 1); ++ msleep(2000); ++} ++#endif + + /* + 02000640 is sample on rising edge. +@@ -510,6 +647,17 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags) + } + } + ++#if 0 ++static void clear_tsin(struct ngene_channel *chan) ++{ ++ struct SBufferHeader *Cur = chan->nextBuffer; ++ ++ do { ++ memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR)); ++ Cur = Cur->Next; ++ } while (Cur != chan->nextBuffer); ++} ++#endif + + static void flush_buffers(struct ngene_channel *chan) + { +@@ -730,6 +878,14 @@ void set_transfer(struct ngene_channel *chan, int state) + if (dev->card_info->switch_ctrl) + dev->card_info->switch_ctrl(chan, 1, state ^ 1); + ++#if 0 ++ /* Disable AVF output if present. */ ++ if (dev->card_info->avf[chan->number]) ++ i2c_write_register(&chan->i2c_adapter, ++ chan->dev->card_info->avf[chan->number], ++ 0xf2, state ? 0x80 : 0x89); ++ ++#endif + if (state) { + spin_lock_irq(&chan->state_lock); + +@@ -750,8 +906,8 @@ void set_transfer(struct ngene_channel *chan, int state) + if (chan->mode & NGENE_IO_TSIN) + chan->pBufferExchange = tsin_exchange; + spin_unlock_irq(&chan->state_lock); +- } +- /* else printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", ++ } else ++ ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", + ngreadl(0x9310)); */ + + ret = ngene_command_stream_control(dev, chan->number, +@@ -769,6 +925,89 @@ void set_transfer(struct ngene_channel *chan, int state) + } + } + ++#if 0 ++/****************************************************************************/ ++/* Decypher firmware loading ************************************************/ ++/****************************************************************************/ ++ ++#define DECYPHER_FW "decypher.fw" ++ ++static int dec_ts_send(struct ngene *dev, u8 *buf, u32 len) ++{ ++#if 0 ++ if (wait_event_interruptible(dev->tsout_rbuf.queue, ++ dvb_ringbuffer_free ++ (&dev->tsout_rbuf) >= len) < 0) ++ return 0; ++#else ++ while (dvb_ringbuffer_free(&dev->tsout_rbuf) < len) ++ msleep(1); ++ ++#endif ++ ++ dvb_ringbuffer_write(&dev->tsout_rbuf, buf, len); ++ ++ return len; ++} ++ ++u8 dec_fw_fill_ts[188] = { 0x47, 0x09, 0x0e, 0x10, 0xff, 0xff, 0x00, 0x00 }; ++ ++int dec_fw_send(struct ngene *dev, u8 *fw, u32 size) ++{ ++ struct ngene_channel *chan = &dev->channel[4]; ++ u32 len = 180, cc = 0; ++ u8 buf[8] = { 0x47, 0x09, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00 }; ++ ++ set_transfer(chan, 1); ++ msleep(100); ++ while (size) { ++ len = 180; ++ if (len > size) ++ len = size; ++ buf[3] = 0x10 | (cc & 0x0f); ++ buf[4] = (cc >> 8); ++ buf[5] = cc & 0xff; ++ buf[6] = len; ++ ++ dec_ts_send(dev, buf, 8); ++ dec_ts_send(dev, fw, len); ++ if (len < 180) ++ dec_ts_send(dev, dec_fw_fill_ts + len + 8, 180 - len); ++ cc++; ++ size -= len; ++ fw += len; ++ } ++ for (len = 0; len < 512; len++) ++ dec_ts_send(dev, dec_fw_fill_ts, 188); ++ while (dvb_ringbuffer_avail(&dev->tsout_rbuf)) ++ msleep(10); ++ msleep(100); ++ set_transfer(chan, 0); ++ return 0; ++} ++ ++int dec_fw_boot(struct ngene *dev) ++{ ++ u32 size; ++ const struct firmware *fw = NULL; ++ u8 *dec_fw; ++ ++ if (request_firmware(&fw, DECYPHER_FW, &dev->pci_dev->dev) < 0) { ++ printk(KERN_ERR DEVICE_NAME ++ ": %s not found. Check hotplug directory.\n", ++ DECYPHER_FW); ++ return -1; ++ } ++ printk(KERN_INFO DEVICE_NAME ": Booting decypher firmware file %s\n", ++ DECYPHER_FW); ++ ++ size = fw->size; ++ dec_fw = (u8 *)fw->data; ++ dec_fw_send(dev, dec_fw, size); ++ release_firmware(fw); ++ return 0; ++} ++#endif + + /****************************************************************************/ + /* nGene hardware init and release functions ********************************/ +@@ -908,6 +1147,7 @@ static int AllocateRingBuffers(struct pci_dev *pci_dev, + { + dma_addr_t tmp; + u32 i, j; ++ int status = 0; + u32 SCListMemSize = pRingBuffer->NumBuffers + * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) : + NUM_SCATTER_GATHER_ENTRIES) +@@ -1007,12 +1247,14 @@ static int AllocateRingBuffers(struct pci_dev *pci_dev, + + } + +- return 0; ++ return status; + } + + static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer, + struct SRingBufferDescriptor *pRingBuffer) + { ++ int status = 0; ++ + /* Copy pointer to scatter gather list in TSRingbuffer + structure for buffer 2 + Load number of buffer +@@ -1033,7 +1275,7 @@ static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer, + pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1; + Cur = Cur->Next; + } +- return 0; ++ return status; + } + + static u32 RingBufferSizes[MAX_STREAM] = { +@@ -1060,6 +1302,85 @@ static u32 Buffer2Sizes[MAX_STREAM] = { + 0 + }; + ++#if 0 ++static int allocate_buffer(struct pci_dev *pci_dev, dma_addr_t of, ++ struct SRingBufferDescriptor *rbuf, ++ u32 entries, u32 size1, u32 size2) ++{ ++ if (create_ring_buffer(pci_dev, rbuf, entries) < 0) ++ return -ENOMEM; ++ ++ if (AllocateRingBuffers(pci_dev, of, rbuf, size1, size2) < 0) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static int channel_allocate_buffers(struct ngene_channel *chan) ++{ ++ struct ngene *dev = chan->dev; ++ int type = dev->card_info->io_type[chan->number]; ++ int status; ++ ++ chan->State = KSSTATE_STOP; ++ ++ if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) { ++ status = create_ring_buffer(dev->pci_dev, ++ &chan->RingBuffer, ++ RingBufferSizes[chan->number]); ++ if (status < 0) ++ return -ENOMEM; ++ ++ if (type & (NGENE_IO_TV | NGENE_IO_AIN)) { ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->RingBuffer, ++ Buffer1Sizes[chan->number], ++ Buffer2Sizes[chan-> ++ number]); ++ if (status < 0) ++ return -ENOMEM; ++ } else if (type & NGENE_IO_HDTV) { ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->RingBuffer, ++ MAX_HDTV_BUFFER_SIZE, 0); ++ if (status < 0) ++ return -ENOMEM; ++ } ++ } ++ ++ if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { ++ ++ status = create_ring_buffer(dev->pci_dev, ++ &chan->TSRingBuffer, RING_SIZE_TS); ++ if (status < 0) ++ return -ENOMEM; ++ ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->TSRingBuffer, ++ MAX_TS_BUFFER_SIZE, 0); ++ if (status) ++ return -ENOMEM; ++ } ++ ++ if (type & NGENE_IO_TSOUT) { ++ status = create_ring_buffer(dev->pci_dev, ++ &chan->TSIdleBuffer, 1); ++ if (status < 0) ++ return -ENOMEM; ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->TSIdleBuffer, ++ MAX_TS_BUFFER_SIZE, 0); ++ if (status) ++ return -ENOMEM; ++ FillTSIdleBuffer(&chan->TSIdleBuffer, &chan->TSRingBuffer); ++ } ++ return 0; ++} ++#endif + + static int AllocCommonBuffers(struct ngene *dev) + { +@@ -1073,11 +1394,12 @@ static int AllocCommonBuffers(struct ngene *dev) + dev->ngenetohost = dev->FWInterfaceBuffer + 256; + dev->EventBuffer = dev->FWInterfaceBuffer + 512; + +- dev->OverflowBuffer = pci_zalloc_consistent(dev->pci_dev, +- OVERFLOW_BUFFER_SIZE, +- &dev->PAOverflowBuffer); ++ dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev, ++ OVERFLOW_BUFFER_SIZE, ++ &dev->PAOverflowBuffer); + if (!dev->OverflowBuffer) + return -ENOMEM; ++ memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE); + + for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) { + int type = dev->card_info->io_type[i]; +@@ -1312,6 +1634,10 @@ static int ngene_buffer_config(struct ngene *dev) + u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }; + u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 }; + u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 }; ++#if 0 ++ u8 tsin34_config[6] = { 0x00, 0x00, 0x00, 0x60, 0x60, 0x00 }; ++ u8 tsio35_config[6] = { 0x00, 0x00, 0x00, 0x60, 0x00, 0x60 }; ++#endif + u8 *bconf = tsin12_config; + + if (dev->card_info->io_type[2]&NGENE_IO_TSIN && +@@ -1321,10 +1647,22 @@ static int ngene_buffer_config(struct ngene *dev) + dev->ci.en) + bconf = tsio1235_config; + } ++#if 0 ++ if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { ++ bconf = hdtv_config; ++ ngene_reset_decypher(dev); ++ } ++#endif + stat = ngene_command_config_free_buf(dev, bconf); + } else { + int bconf = BUFFER_CONFIG_4422; + ++#if 0 ++ if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { ++ bconf = BUFFER_CONFIG_8022; ++ ngene_reset_decypher(dev); ++ } ++#endif + if (dev->card_info->io_type[3] == NGENE_IO_TSIN) + bconf = BUFFER_CONFIG_3333; + stat = ngene_command_config_buf(dev, bconf); +@@ -1397,8 +1735,10 @@ static int ngene_start(struct ngene *dev) + if (stat < 0) + goto fail; + +- return 0; ++ if (!stat) ++ return stat; + ++ /* otherwise error: fall through */ + fail: + ngwritel(0, NGENE_INT_ENABLE); + free_irq(dev->pci_dev->irq, dev); +@@ -1590,7 +1930,7 @@ static void cxd_detach(struct ngene *dev) + + dvb_ca_en50221_release(ci->en); + kfree(ci->en); +- ci->en = NULL; ++ ci->en = 0; + } + + /***********************************/ +@@ -1616,7 +1956,7 @@ static void ngene_unlink(struct ngene *dev) + + void ngene_shutdown(struct pci_dev *pdev) + { +- struct ngene *dev = pci_get_drvdata(pdev); ++ struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); + + if (!dev || !shutdown_workaround) + return; +@@ -1642,6 +1982,7 @@ void ngene_remove(struct pci_dev *pdev) + cxd_detach(dev); + ngene_stop(dev); + ngene_release_buffers(dev); ++ pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); + } + +@@ -1681,10 +2022,36 @@ int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) + + + dev->i2c_current_bus = -1; ++#if 0 ++ exp_init(dev); ++ ++ /* Disable analog TV decoder chips if present */ ++ if (dev->card_info->msp[0]) ++ i2c_write_msp_register(&dev->channel[0].i2c_adapter, ++ dev->card_info->msp[0], 0x00, 0x0000); ++ if (dev->card_info->msp[1]) ++ i2c_write_msp_register(&dev->channel[1].i2c_adapter, ++ dev->card_info->msp[1], 0x00, 0x0000); ++ { ++ u16 data; ++ read_msp(&dev->channel[0].i2c_adapter, ++ dev->card_info->msp[0], 0x00, &data); ++ } ++ if (dev->card_info->avf[0]) ++ i2c_write_register(&dev->channel[0].i2c_adapter, ++ dev->card_info->avf[0], 0xf2, 0x80); ++ if (dev->card_info->avf[1]) ++ i2c_write_register(&dev->channel[1].i2c_adapter, ++ dev->card_info->avf[1], 0xf2, 0x80); ++ if (copy_eeprom) { ++ i2c_copy_eeprom(&dev->channel[0].i2c_adapter, 0x50, 0x52); ++ i2c_dump_eeprom(&dev->channel[0].i2c_adapter, 0x52); ++ } ++ /*i2c_check_eeprom(&dev->i2c_adapter);*/ ++#endif + + /* Register DVB adapters and devices for both channels */ +- stat = init_channels(dev); +- if (stat < 0) ++ if (init_channels(dev) < 0) + goto fail2; + + return 0; +@@ -1695,5 +2062,6 @@ fail1: + ngene_release_buffers(dev); + fail0: + pci_disable_device(pci_dev); ++ pci_set_drvdata(pci_dev, NULL); + return stat; + } +diff --git a/drivers/media/pci/ngene/ngene-dvb.c b/drivers/media/pci/ngene/ngene-dvb.c +index 59bb285..8049e2b 100644 +--- a/drivers/media/pci/ngene/ngene-dvb.c ++++ b/drivers/media/pci/ngene/ngene-dvb.c +@@ -42,12 +42,321 @@ + + #include "ngene.h" + ++#if 0 ++int ngene_stream_control(struct ngene *dev, u8 stream, u8 control, u8 mode, ++ u16 lines, u16 bpl, u16 vblines, u16 vbibpl) ++{ ++ if (!(mode & SMODE_TRANSPORT_STREAM)) ++ return -EINVAL; ++ ++ if (lines * bpl > MAX_VIDEO_BUFFER_SIZE) ++ return -EINVAL; ++ ++ if ((mode & SMODE_TRANSPORT_STREAM) && (((bpl * lines) & 0xff) != 0)) ++ return -EINVAL; ++ ++ if ((mode & SMODE_VIDEO_CAPTURE) && (bpl & 7) != 0) ++ return -EINVAL; ++ ++ return ngene_command_stream_control(dev, stream, control, mode, 0); ++} ++#endif + + /****************************************************************************/ + /* COMMAND API interface ****************************************************/ + /****************************************************************************/ ++#if 0 ++ ++static int command_do_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int err = 0; ++ ++ switch (cmd) { ++ case IOCTL_MIC_NO_OP: ++ err = ngene_command_nop(dev); ++ break; ++ ++ case IOCTL_MIC_DOWNLOAD_FIRMWARE: ++ break; ++ ++ case IOCTL_MIC_I2C_READ: ++ { ++ MIC_I2C_READ *msg = parg; ++ ++ err = ngene_command_i2c_read(dev, msg->I2CAddress >> 1, ++ msg->OutData, msg->OutLength, ++ msg->OutData, msg->InLength, 1); ++ break; ++ } ++ ++ case IOCTL_MIC_I2C_WRITE: ++ { ++ MIC_I2C_WRITE *msg = parg; ++ ++ err = ngene_command_i2c_write(dev, msg->I2CAddress >> 1, ++ msg->Data, msg->Length); ++ break; ++ } ++ ++ case IOCTL_MIC_TEST_GETMEM: ++ { ++ MIC_MEM *m = parg; ++ ++ if (m->Length > 64 * 1024 || m->Start + m->Length > 64 * 1024) ++ return -EINVAL; ++ ++ /* WARNING, only use this on x86, ++ other archs may not swallow this */ ++ err = copy_to_user(m->Data, dev->iomem + m->Start, m->Length); ++ break; ++ } ++ ++ case IOCTL_MIC_TEST_SETMEM: ++ { ++ MIC_MEM *m = parg; ++ ++ if (m->Length > 64 * 1024 || m->Start + m->Length > 64 * 1024) ++ return -EINVAL; ++ ++ err = copy_from_user(dev->iomem + m->Start, m->Data, m->Length); ++ break; ++ } ++ ++ case IOCTL_MIC_SFR_READ: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_read(dev, m->Address, &m->Data, 1); ++ break; ++ } ++ ++ case IOCTL_MIC_SFR_WRITE: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_write(dev, m->Address, m->Data, 1); ++ break; ++ } ++ ++ case IOCTL_MIC_IRAM_READ: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_read(dev, m->Address, &m->Data, 0); ++ break; ++ } ++ ++ case IOCTL_MIC_IRAM_WRITE: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_write(dev, m->Address, m->Data, 0); ++ break; ++ } ++ ++ case IOCTL_MIC_STREAM_CONTROL: ++ { ++ MIC_STREAM_CONTROL *m = parg; ++ ++ err = ngene_stream_control(dev, m->Stream, m->Control, m->Mode, ++ m->nLines, m->nBytesPerLine, ++ m->nVBILines, m->nBytesPerVBILine); ++ break; ++ } ++ ++ default: ++ err = -EINVAL; ++ break; ++ } ++ return err; ++} ++ ++static int command_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ void *parg = (void *)arg, *pbuf = NULL; ++ char buf[64]; ++ int res = -EFAULT; ++ ++ if (_IOC_DIR(cmd) & _IOC_WRITE) { ++ parg = buf; ++ if (_IOC_SIZE(cmd) > sizeof(buf)) { ++ pbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); ++ if (!pbuf) ++ return -ENOMEM; ++ parg = pbuf; ++ } ++ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) ++ goto error; ++ } ++ res = command_do_ioctl(inode, file, cmd, parg); ++ if (res < 0) ++ goto error; ++ if (_IOC_DIR(cmd) & _IOC_READ) ++ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) ++ res = -EFAULT; ++error: ++ kfree(pbuf); ++ return res; ++} ++ ++struct page *ngene_nopage(struct vm_area_struct *vma, ++ unsigned long address, int *type) ++{ ++ return 0; ++} ++ ++static int ngene_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ ++ unsigned long size = vma->vm_end - vma->vm_start; ++ unsigned long off = vma->vm_pgoff << PAGE_SHIFT; ++ unsigned long padr = pci_resource_start(dev->pci_dev, 0) + off; ++ unsigned long psize = pci_resource_len(dev->pci_dev, 0) - off; ++ ++ if (size > psize) ++ return -EINVAL; ++ ++ if (io_remap_pfn_range(vma, vma->vm_start, padr >> PAGE_SHIFT, size, ++ vma->vm_page_prot)) ++ return -EAGAIN; ++ return 0; ++} ++ ++ ++static int write_uart(struct ngene *dev, u8 *data, int len) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = CMD_WRITE_UART; ++ com.cmd.hdr.Length = len; ++ memcpy(com.cmd.WriteUart.Data, data, len); ++ com.cmd.WriteUart.Data[len] = 0; ++ com.cmd.WriteUart.Data[len + 1] = 0; ++ com.in_len = len; ++ com.out_len = 0; + +-static ssize_t ts_write(struct file *file, const char __user *buf, ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int send_cli(struct ngene *dev, char *cmd) ++{ ++ /* printk(KERN_INFO DEVICE_NAME ": %s", cmd); */ ++ return write_uart(dev, cmd, strlen(cmd)); ++} ++ ++static int send_cli_val(struct ngene *dev, char *cmd, u32 val) ++{ ++ char s[32]; ++ ++ snprintf(s, 32, "%s %d\n", cmd, val); ++ /* printk(KERN_INFO DEVICE_NAME ": %s", s); */ ++ return write_uart(dev, s, strlen(s)); ++} ++ ++static int ngene_command_write_uart_user(struct ngene *dev, ++ const u8 *data, int len) ++{ ++ struct ngene_command com; ++ ++ dev->tx_busy = 1; ++ com.cmd.hdr.Opcode = CMD_WRITE_UART; ++ com.cmd.hdr.Length = len; ++ ++ if (copy_from_user(com.cmd.WriteUart.Data, data, len)) ++ return -EFAULT; ++ com.in_len = len; ++ com.out_len = 0; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static ssize_t uart_write(struct file *file, const char *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int len, ret = 0; ++ size_t left = count; ++ ++ while (left) { ++ len = left; ++ if (len > 250) ++ len = 250; ++ ret = wait_event_interruptible(dev->tx_wq, dev->tx_busy == 0); ++ if (ret < 0) ++ return ret; ++ ngene_command_write_uart_user(dev, buf, len); ++ left -= len; ++ buf += len; ++ } ++ return count; ++} ++ ++static ssize_t uart_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int left; ++ int wp, rp, avail, len; ++ ++ if (!dev->uart_rbuf) ++ return -EINVAL; ++ if (count > 128) ++ count = 128; ++ left = count; ++ while (left) { ++ if (wait_event_interruptible(dev->rx_wq, ++ dev->uart_wp != dev->uart_rp) < 0) ++ return -EAGAIN; ++ wp = dev->uart_wp; ++ rp = dev->uart_rp; ++ avail = (wp - rp); ++ ++ if (avail < 0) ++ avail += UART_RBUF_LEN; ++ if (avail > left) ++ avail = left; ++ if (wp < rp) { ++ len = UART_RBUF_LEN - rp; ++ if (len > avail) ++ len = avail; ++ if (copy_to_user(buf, dev->uart_rbuf + rp, len)) ++ return -EFAULT; ++ if (len < avail) ++ if (copy_to_user(buf + len, dev->uart_rbuf, ++ avail - len)) ++ return -EFAULT; ++ } else { ++ if (copy_to_user(buf, dev->uart_rbuf + rp, avail)) ++ return -EFAULT; ++ } ++ dev->uart_rp = (rp + avail) % UART_RBUF_LEN; ++ left -= avail; ++ buf += avail; ++ } ++ return count; ++} ++ ++#endif ++ ++static ssize_t ts_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) + { + struct dvb_device *dvbdev = file->private_data; +@@ -59,12 +368,12 @@ static ssize_t ts_write(struct file *file, const char __user *buf, + (&dev->tsout_rbuf) >= count) < 0) + return 0; + +- dvb_ringbuffer_write_user(&dev->tsout_rbuf, buf, count); ++ dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); + + return count; + } + +-static ssize_t ts_read(struct file *file, char __user *buf, ++static ssize_t ts_read(struct file *file, char *buf, + size_t count, loff_t *ppos) + { + struct dvb_device *dvbdev = file->private_data; +@@ -97,6 +406,7 @@ static const struct file_operations ci_fops = { + }; + + struct dvb_device ngene_dvbdev_ci = { ++ .priv = 0, + .readers = -1, + .writers = -1, + .users = -1, +@@ -132,6 +442,11 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) + struct ngene_channel *chan = priv; + struct ngene *dev = chan->dev; + ++#if 0 ++ printk(KERN_INFO DEVICE_NAME ": tsin %08x %02x %02x %02x %02x\n", ++ len, ((u8 *) buf)[512 * 188], ((u8 *) buf)[0], ++ ((u8 *) buf)[1], ((u8 *) buf)[2]); ++#endif + + if (flags & DF_SWAP32) + swap_buffer(buf, len); +@@ -190,12 +505,49 @@ void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) + return buf; + } + ++#if 0 ++static void set_dto(struct ngene_channel *chan, u32 rate) ++{ ++ u64 val = rate * 0x89705f41ULL; /* times val for 2^26 Hz */ ++ ++ val = ((val >> 25) + 1) >> 1; ++ chan->AudioDTOValue = (u32) val; ++ /* chan->AudioDTOUpdated=1; */ ++ /* printk(KERN_INFO DEVICE_NAME ": Setting DTO to %08x\n", val); */ ++} ++#endif + + + int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) + { + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct ngene_channel *chan = dvbdmx->priv; ++#if 0 ++ struct ngene *dev = chan->dev; ++ ++ if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) { ++ switch (dvbdmxfeed->pes_type) { ++ case DMX_TS_PES_VIDEO: ++ send_cli_val(dev, "vpid", dvbdmxfeed->pid); ++ send_cli(dev, "res 1080i50\n"); ++ /* send_cli(dev, "vdec mpeg2\n"); */ ++ break; ++ ++ case DMX_TS_PES_AUDIO: ++ send_cli_val(dev, "apid", dvbdmxfeed->pid); ++ send_cli(dev, "start\n"); ++ break; ++ ++ case DMX_TS_PES_PCR: ++ send_cli_val(dev, "pcrpid", dvbdmxfeed->pid); ++ break; ++ ++ default: ++ break; ++ } ++ ++ } ++#endif + + if (chan->users == 0) { + if (!chan->dev->cmd_timeout_workaround || !chan->running) +@@ -209,6 +561,27 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) + { + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct ngene_channel *chan = dvbdmx->priv; ++#if 0 ++ struct ngene *dev = chan->dev; ++ ++ if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) { ++ switch (dvbdmxfeed->pes_type) { ++ case DMX_TS_PES_VIDEO: ++ send_cli(dev, "stop\n"); ++ break; ++ ++ case DMX_TS_PES_AUDIO: ++ break; ++ ++ case DMX_TS_PES_PCR: ++ break; ++ ++ default: ++ break; ++ } ++ ++ } ++#endif + + if (--chan->users) + return chan->users; +diff --git a/drivers/media/pci/ngene/ngene-eeprom.c b/drivers/media/pci/ngene/ngene-eeprom.c +new file mode 100644 +index 0000000..281d9f9 +--- /dev/null ++++ b/drivers/media/pci/ngene/ngene-eeprom.c +@@ -0,0 +1,284 @@ ++/* ++ * ngene-eeprom.c: nGene PCIe bridge driver - eeprom support ++ * ++ * Copyright (C) 2005-2007 Micronas ++ * ++ * Copyright (C) 2008-2009 Ralph Metzler ++ * Modifications for new nGene firmware, ++ * support for EEPROM-copying, ++ * support for new dual DVB-S2 card prototype ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#if 0 ++static int copy_eeprom; ++module_param(copy_eeprom, int, 0444); ++MODULE_PARM_DESC(copy_eeprom, "Copy eeprom."); ++ ++#define MICNG_EE_START 0x0100 ++#define MICNG_EE_END 0x0FF0 ++ ++#define MICNG_EETAG_END0 0x0000 ++#define MICNG_EETAG_END1 0xFFFF ++ ++/* 0x0001 - 0x000F reserved for housekeeping */ ++/* 0xFFFF - 0xFFFE reserved for housekeeping */ ++ ++/* Micronas assigned tags ++ EEProm tags for hardware support */ ++ ++#define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */ ++#define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */ ++ ++#define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ ++#define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ ++ ++/* Tag range for OEMs */ ++ ++#define MICNG_EETAG_OEM_FIRST 0xC000 ++#define MICNG_EETAG_OEM_LAST 0xFFEF ++ ++static int i2c_write_eeprom(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 data) ++{ ++ u8 m[3] = {(reg >> 8), (reg & 0xff), data}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, ++ .len = sizeof(m)}; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ dprintk(KERN_ERR DEVICE_NAME ": Error writing EEPROM!\n"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int i2c_read_eeprom(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 *data, int len) ++{ ++ u8 msg[2] = {(reg >> 8), (reg & 0xff)}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = data, .len = len} }; ++ ++ if (i2c_transfer(adapter, msgs, 2) != 2) { ++ dprintk(KERN_ERR DEVICE_NAME ": Error reading EEPROM\n"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ReadEEProm(struct i2c_adapter *adapter, ++ u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) ++{ ++ int status = 0; ++ u16 Addr = MICNG_EE_START, Length, tag = 0; ++ u8 EETag[3]; ++ ++ while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { ++ if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) ++ return -1; ++ tag = (EETag[0] << 8) | EETag[1]; ++ if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) ++ return -1; ++ if (tag == Tag) ++ break; ++ Addr += sizeof(u16) + 1 + EETag[2]; ++ } ++ if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Reached EOEE @ Tag = %04x Length = %3d\n", ++ tag, EETag[2]); ++ return -1; ++ } ++ Length = EETag[2]; ++ if (Length > MaxLen) ++ Length = (u16) MaxLen; ++ if (Length > 0) { ++ Addr += sizeof(u16) + 1; ++ status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length); ++ if (!status) { ++ *pLength = EETag[2]; ++ if (Length < EETag[2]) ++ ; /*status=STATUS_BUFFER_OVERFLOW; */ ++ } ++ } ++ return status; ++} ++ ++static int WriteEEProm(struct i2c_adapter *adapter, ++ u16 Tag, u32 Length, u8 *data) ++{ ++ int status = 0; ++ u16 Addr = MICNG_EE_START; ++ u8 EETag[3]; ++ u16 tag = 0; ++ int retry, i; ++ ++ while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { ++ if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) ++ return -1; ++ tag = (EETag[0] << 8) | EETag[1]; ++ if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) ++ return -1; ++ if (tag == Tag) ++ break; ++ Addr += sizeof(u16) + 1 + EETag[2]; ++ } ++ if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Reached EOEE @ Tag = %04x Length = %3d\n", ++ tag, EETag[2]); ++ return -1; ++ } ++ ++ if (Length > EETag[2]) ++ return -EINVAL; ++ /* Note: We write the data one byte at a time to avoid ++ issues with page sizes. (which are different for ++ each manufacture and eeprom size) ++ */ ++ Addr += sizeof(u16) + 1; ++ for (i = 0; i < Length; i++, Addr++) { ++ status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]); ++ ++ if (status) ++ break; ++ ++ /* Poll for finishing write cycle */ ++ retry = 10; ++ while (retry) { ++ u8 Tmp; ++ ++ msleep(50); ++ status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1); ++ if (status) ++ break; ++ if (Tmp != data[i]) ++ printk(KERN_ERR DEVICE_NAME ++ "eeprom write error\n"); ++ retry -= 1; ++ } ++ if (status) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Timeout polling eeprom\n"); ++ break; ++ } ++ } ++ return status; ++} ++ ++static void i2c_init_eeprom(struct i2c_adapter *adapter) ++{ ++ u8 tags[] = {0x10, 0x00, 0x02, 0x00, 0x00, ++ 0x10, 0x01, 0x02, 0x00, 0x00, ++ 0x00, 0x00, 0x00}; ++ ++ int i; ++ ++ for (i = 0; i < sizeof(tags); i++) ++ i2c_write_eeprom(adapter, 0x50, 0x0100 + i, tags[i]); ++} ++ ++int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data) ++{ ++ int stat; ++ u8 buf[2]; ++ u32 len = 0; ++ ++ stat = ReadEEProm(adapter, tag, 2, buf, &len); ++ if (stat) ++ return stat; ++ if (len != 2) ++ return -EINVAL; ++ ++ *data = (buf[0] << 8) | buf[1]; ++ return 0; ++} ++ ++static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data) ++{ ++ int stat; ++ u8 buf[2]; ++ ++ buf[0] = data >> 8; ++ buf[1] = data & 0xff; ++ stat = WriteEEProm(adapter, tag, 2, buf); ++ if (stat) ++ return stat; ++ return 0; ++} ++ ++int i2c_dump_eeprom(struct i2c_adapter *adapter, u8 adr) ++{ ++ u8 buf[64]; ++ int i; ++ ++ if (i2c_read_eeprom(adapter, adr, 0x0000, buf, sizeof(buf))) { ++ printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); ++ return -1; ++ } ++ for (i = 0; i < sizeof(buf); i++) { ++ if (!(i & 15)) ++ printk(KERN_DEBUG "\n"); ++ printk(KERN_DEBUG "%02x ", buf[i]); ++ } ++ printk("\n"); ++ ++ return 0; ++} ++ ++int i2c_copy_eeprom(struct i2c_adapter *adapter, u8 adr, u8 adr2) ++{ ++ u8 buf[64]; ++ int i; ++ ++ if (i2c_read_eeprom(adapter, adr, 0x0000, buf, sizeof(buf))) { ++ printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); ++ return -1; ++ } ++ buf[36] = 0xc3; ++ buf[39] = 0xab; ++ for (i = 0; i < sizeof(buf); i++) { ++ i2c_write_eeprom(adapter, adr2, i, buf[i]); ++ msleep(10); ++ } ++ return 0; ++} ++ ++int i2c_check_eeprom(struct i2c_adapter *adapter) ++{ ++ u8 buf[13]; ++ ++ i2c_dump_eeprom(adapter); ++ ++ if (i2c_read_eeprom(adapter, 0x50, 0x0100, buf, sizeof(buf))) { ++ printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); ++ return -1; ++ } ++ if (buf[0] != 0x10 || buf[1] != 0x00) { ++ printk(KERN_INFO DEVICE_NAME ++ ": Initializing EEPROM TAG area\n"); ++ i2c_init_eeprom(adapter); ++ } ++ return 0; ++} ++ ++#endif +diff --git a/drivers/media/pci/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c +index d28554f..601bea4 100644 +--- a/drivers/media/pci/ngene/ngene-i2c.c ++++ b/drivers/media/pci/ngene/ngene-i2c.c +@@ -77,6 +77,11 @@ static int ngene_command_i2c_write(struct ngene *dev, u8 adr, + { + struct ngene_command com; + ++#if 0 ++ /* Probing by writing 0 bytes does not work */ ++ if (!outlen) ++ outlen++; ++#endif + + com.cmd.hdr.Opcode = CMD_I2C_WRITE; + com.cmd.hdr.Length = outlen + 1; +@@ -148,6 +153,39 @@ done: + return num; + } + ++#if 0 ++static int ngene_i2c_algo_control(struct i2c_adapter *adap, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct ngene_channel *chan = ++ (struct ngene_channel *)i2c_get_adapdata(adap); ++ ++ switch (cmd) { ++ case IOCTL_MIC_TUN_RDY: ++ chan->tun_rdy = 1; ++ if (chan->dec_rdy == 1) ++ chan->tun_dec_rdy = 1; ++ break; ++ ++ case IOCTL_MIC_DEC_RDY: ++ chan->dec_rdy = 1; ++ if (chan->tun_rdy == 1) ++ chan->tun_dec_rdy = 1; ++ break; ++ ++ case IOCTL_MIC_TUN_DETECT: ++ { ++ int *palorbtsc = (int *)arg; ++ *palorbtsc = chan->dev->card_info->ntsc; ++ break; ++ } ++ ++ default: ++ break; ++ } ++ return 0; ++} ++#endif + + static u32 ngene_i2c_functionality(struct i2c_adapter *adap) + { +@@ -174,3 +212,78 @@ int ngene_i2c_init(struct ngene *dev, int dev_nr) + return i2c_add_adapter(adap); + } + ++#if 0 ++int i2c_write(struct i2c_adapter *adapter, u8 adr, u8 data) ++{ ++ u8 m[1] = {data}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 1}; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Failed to write to I2C adr %02x!\n", adr); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write_register(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 data) ++{ ++ u8 m[2] = {reg, data}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2}; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Failed to write to I2C register %02x@%02x!\n", ++ reg, adr); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write_read(struct i2c_adapter *adapter, ++ u8 adr, u8 *w, u8 wlen, u8 *r, u8 rlen) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = w, .len = wlen}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = r, .len = rlen} }; ++ ++ if (i2c_transfer(adapter, msgs, 2) != 2) { ++ printk(KERN_ERR DEVICE_NAME ": error in i2c_write_read\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int test_dec_i2c(struct i2c_adapter *adapter, int reg) ++{ ++ u8 data[256] = { reg, 0x00, 0x93, 0x78, 0x43, 0x45 }; ++ u8 data2[256]; ++ int i; ++ ++ memset(data2, 0, 256); ++ i2c_write_read(adapter, 0x66, data, 2, data2, 4); ++ for (i = 0; i < 4; i++) ++ printk(KERN_DEBUG "%02x ", data2[i]); ++ printk(KERN_DEBUG "\n"); ++ ++ return 0; ++} ++ ++static int i2c_write_msp_register(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u16 data) ++{ ++ u8 m[3] = {reg, (data >> 8) & 0xff, data & 0xff}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 3 }; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Failed to write to I2C register %02x@%02x!\n", ++ reg, adr); ++ return -1; ++ } ++ return 0; ++} ++ ++#endif +diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h +index 51e2fbd..e3ae00c 100644 +--- a/drivers/media/pci/ngene/ngene.h ++++ b/drivers/media/pci/ngene/ngene.h +@@ -653,6 +653,11 @@ struct ngene_channel { + struct dmx_frontend mem_frontend; + int users; + struct video_device *v4l_dev; ++#if 0 ++ struct dvb_device *command_dev; ++ struct dvb_device *audio_dev; ++ struct dvb_device *video_dev; ++#endif + struct dvb_device *ci_dev; + struct tasklet_struct demux_tasklet; + +@@ -691,6 +696,9 @@ struct ngene_channel { + struct mychip *mychip; + struct snd_card *soundcard; + u8 *evenbuffer; ++#if 0 ++ u8 *soundbuffer; ++#endif + u8 dma_on; + int soundstreamon; + int audiomute; +@@ -737,7 +745,7 @@ typedef void (tx_cb_t)(struct ngene *, u32); + struct ngene { + int nr; + struct pci_dev *pci_dev; +- unsigned char __iomem *iomem; ++ unsigned char *iomem; + + /*struct i2c_adapter i2c_adapter;*/ + +@@ -849,6 +857,10 @@ struct ngene_info { + u8 lnb[4]; + int i2c_access; + u8 ntsc; ++#if 0 ++ u8 exp; ++ u8 exp_init; ++#endif + u8 tsf[4]; + u8 i2s[4]; + +@@ -885,6 +897,25 @@ struct ngene_buffer { + }; + #endif + ++#if 0 ++int ngene_command_stream_control(struct ngene *dev, ++ u8 stream, u8 control, u8 mode, u8 flags); ++int ngene_command_nop(struct ngene *dev); ++int ngene_command_i2c_read(struct ngene *dev, u8 adr, ++ u8 *out, u8 outlen, u8 *in, u8 inlen, int flag); ++int ngene_command_i2c_write(struct ngene *dev, u8 adr, u8 *out, u8 outlen); ++int ngene_command_imem_read(struct ngene *dev, u8 adr, u8 *data, int type); ++int ngene_command_imem_write(struct ngene *dev, u8 adr, u8 data, int type); ++int ngene_stream_control(struct ngene *dev, u8 stream, u8 control, u8 mode, ++ u16 lines, u16 bpl, u16 vblines, u16 vbibpl); ++ ++int ngene_v4l2_init(struct ngene_channel *chan); ++void ngene_v4l2_remove(struct ngene_channel *chan); ++int ngene_snd_exit(struct ngene_channel *chan); ++int ngene_snd_init(struct ngene_channel *chan); ++ ++struct i2c_client *avf4910a_attach(struct i2c_adapter *adap, int addr); ++#endif + + /* Provided by ngene-core.c */ + int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id); +@@ -914,6 +945,15 @@ int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, + struct dmx_frontend *mem_frontend, + struct dvb_adapter *dvb_adapter); + ++/* Provided by ngene-eeprom.c */ ++#if 0 ++int i2c_copy_eeprom(struct i2c_adapter *adapter, u8 adr, u8 adr2); ++int i2c_dump_eeprom(struct i2c_adapter *adapter, u8 adr); ++int i2c_check_eeprom(struct i2c_adapter *adapter); ++int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data); ++int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data); ++#endif ++ + #endif + + /* LocalWords: Endif +diff --git a/include/uapi/linux/dvb/mod.h b/include/uapi/linux/dvb/mod.h +new file mode 100644 +index 0000000..c733a39 +--- /dev/null ++++ b/include/uapi/linux/dvb/mod.h +@@ -0,0 +1,22 @@ ++#ifndef _UAPI_DVBMOD_H_ ++#define _UAPI_DVBMOD_H_ ++ ++#include ++#include "frontend.h" ++ ++struct dvb_mod_params { ++ __u32 base_frequency; ++ __u32 attenuator; ++}; ++ ++struct dvb_mod_channel_params { ++ enum fe_modulation modulation; ++ __u64 input_bitrate; /* 2^-32 Hz */ ++ int pcr_correction; ++}; ++ ++ ++#define DVB_MOD_SET _IOW('o', 208, struct dvb_mod_params) ++#define DVB_MOD_CHANNEL_SET _IOW('o', 209, struct dvb_mod_channel_params) ++ ++#endif /*_UAPI_DVBMOD_H_*/ +diff --git a/include/uapi/linux/dvb/ns.h b/include/uapi/linux/dvb/ns.h +new file mode 100644 +index 0000000..691c65d +--- /dev/null ++++ b/include/uapi/linux/dvb/ns.h +@@ -0,0 +1,68 @@ ++#ifndef _UAPI_DVBNS_H_ ++#define _UAPI_DVBNS_H_ ++ ++#include ++ ++struct dvb_ns_params { ++ __u8 smac[6]; ++ __u8 dmac[6]; ++ __u8 sip[16]; ++ __u8 dip[16]; ++ __u16 sport; ++ __u16 dport; ++ __u16 sport2; ++ __u16 dport2; ++ __u8 ssrc[8]; ++ __u8 flags; ++ __u8 qos; ++ __u16 vlan; ++ __u8 ttl; ++}; ++ ++#define DVB_NS_IPV6 1 ++#define DVB_NS_RTP 2 ++#define DVB_NS_RTCP 4 ++#define DVB_NS_RTP_TO 8 ++ ++struct dvb_ns_rtcp { ++ __u8 *msg; ++ __u16 len; ++}; ++ ++struct dvb_ns_packet { ++ __u8 *buf; ++ __u8 count; ++}; ++ ++struct dvb_nsd_ts { ++ __u16 pid; ++ __u16 num; ++ __u16 input; ++ __u16 timeout; ++ __u16 len; ++ __u8 *ts; ++ __u8 mode; ++ __u8 table; ++ ++ __u8 filter_mask; ++ __u8 section; ++ __u16 section_id; ++}; ++ ++#define NS_SET_NET _IOW('o', 192, struct dvb_ns_params) ++#define NS_START _IO('o', 193) ++#define NS_STOP _IO('o', 194) ++#define NS_SET_PID _IOW('o', 195, __u16) ++#define NS_SET_PIDS _IOW('o', 196, __u8 *) ++#define NS_SET_RTCP_MSG _IOW('o', 197, struct dvb_ns_rtcp) ++ ++#define NSD_START_GET_TS _IOWR('o', 198, struct dvb_nsd_ts) ++#define NSD_STOP_GET_TS _IOWR('o', 199, struct dvb_nsd_ts) ++#define NSD_CANCEL_GET_TS _IO('o', 200) ++#define NSD_POLL_GET_TS _IOWR('o', 201, struct dvb_nsd_ts) ++ ++#define NS_SET_PACKETS _IOW('o', 202, struct dvb_ns_packet) ++#define NS_INSERT_PACKETS _IOW('o', 203, __u8) ++#define NS_SET_CI _IOW('o', 204, __u8) ++ ++#endif /*_UAPI_DVBNS_H_*/ +-- +2.1.4 + diff --git a/packages/linux/patches/4.1.12/linux-222-stb0899_signal_quality.patch b/packages/linux/patches/4.3/linux-222-stb0899_signal_quality.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-222-stb0899_signal_quality.patch rename to packages/linux/patches/4.3/linux-222-stb0899_signal_quality.patch diff --git a/packages/linux/patches/4.1.12/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch b/packages/linux/patches/4.3/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch rename to packages/linux/patches/4.3/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch diff --git a/packages/linux/patches/4.1.12/linux-227-ds3000-invalid-symbol-rate.patch b/packages/linux/patches/4.3/linux-227-ds3000-invalid-symbol-rate.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-227-ds3000-invalid-symbol-rate.patch rename to packages/linux/patches/4.3/linux-227-ds3000-invalid-symbol-rate.patch diff --git a/packages/linux/patches/4.1.12/linux-230-elgato-eyetv-sat-v3.patch b/packages/linux/patches/4.3/linux-230-elgato-eyetv-sat-v3.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-230-elgato-eyetv-sat-v3.patch rename to packages/linux/patches/4.3/linux-230-elgato-eyetv-sat-v3.patch diff --git a/packages/linux/patches/4.1.12/linux-706-Sitecom-N300.patch b/packages/linux/patches/4.3/linux-706-Sitecom-N300.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-706-Sitecom-N300.patch rename to packages/linux/patches/4.3/linux-706-Sitecom-N300.patch diff --git a/packages/linux/patches/4.1.12/linux-950-saa716x_PCIe_interface_chipset.patch b/packages/linux/patches/4.3/linux-950-saa716x_PCIe_interface_chipset.todo similarity index 100% rename from packages/linux/patches/4.1.12/linux-950-saa716x_PCIe_interface_chipset.patch rename to packages/linux/patches/4.3/linux-950-saa716x_PCIe_interface_chipset.todo diff --git a/packages/linux/patches/4.1.12/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch b/packages/linux/patches/4.3/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch rename to packages/linux/patches/4.3/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch diff --git a/packages/linux/patches/4.3/linux-999-i915-implement-passthrough-colors.patch b/packages/linux/patches/4.3/linux-999-i915-implement-passthrough-colors.patch new file mode 100644 index 0000000000..2ccfd8ae8a --- /dev/null +++ b/packages/linux/patches/4.3/linux-999-i915-implement-passthrough-colors.patch @@ -0,0 +1,125 @@ +From 2ede4f1aabc37c6726c4edf39636d6411957bfad Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Wed, 30 Sep 2015 20:57:49 +0200 +Subject: [PATCH] Implement Color Range (passthrough) by lauri v1 Initial v2 + Fix a hunk + +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_drv.h | 7 +++++++ + drivers/gpu/drm/i915/intel_hdmi.c | 17 +++++++++++++++-- + drivers/gpu/drm/i915/intel_modes.c | 1 + + 4 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 7d53d7e..5d45cd8 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -3206,6 +3206,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val); + #define INTEL_BROADCAST_RGB_AUTO 0 + #define INTEL_BROADCAST_RGB_FULL 1 + #define INTEL_BROADCAST_RGB_LIMITED 2 ++#define INTEL_BROADCAST_RGB_VIDEO 3 + + static inline uint32_t i915_vgacntrl_reg(struct drm_device *dev) + { +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 68d1f74..637d13b 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -299,6 +299,12 @@ struct intel_crtc_state { + */ + bool limited_color_range; + ++ /* ++ * Use reduced/limited/broadcast rgb range without compressing ++ * ++ */ ++ bool video_color_range; ++ + /* DP has a bunch of special case unfortunately, so mark the pipe + * accordingly. */ + bool has_dp_encoder; +@@ -574,6 +580,7 @@ struct intel_hdmi { + int ddc_bus; + uint32_t color_range; + bool color_range_auto; ++ bool color_range_video; + bool has_hdmi_sink; + bool has_audio; + enum hdmi_force_audio force_audio; +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index bfbe07b..8a45c16 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -437,7 +437,8 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, + } + + if (intel_hdmi->rgb_quant_range_selectable) { +- if (intel_crtc->config->limited_color_range) ++ if (intel_crtc->config->limited_color_range || ++ intel_crtc->config->video_color_range) + frame.avi.quantization_range = + HDMI_QUANTIZATION_RANGE_LIMITED; + else +@@ -1017,6 +1018,9 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + if (intel_hdmi->color_range) + pipe_config->limited_color_range = true; + ++ if (intel_hdmi->color_range_video) ++ pipe_config->video_color_range = true; ++ + if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev)) + pipe_config->has_pch_encoder = true; + +@@ -1209,25 +1213,34 @@ intel_hdmi_set_property(struct drm_connector *connector, + if (property == dev_priv->broadcast_rgb_property) { + bool old_auto = intel_hdmi->color_range_auto; + uint32_t old_range = intel_hdmi->color_range; ++ bool old_range_video = intel_hdmi->color_range_video; + + switch (val) { + case INTEL_BROADCAST_RGB_AUTO: + intel_hdmi->color_range_auto = true; ++ intel_hdmi->color_range_video = false; + break; + case INTEL_BROADCAST_RGB_FULL: + intel_hdmi->color_range_auto = false; + intel_hdmi->color_range = 0; ++ intel_hdmi->color_range_video = false; + break; + case INTEL_BROADCAST_RGB_LIMITED: + intel_hdmi->color_range_auto = false; + intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; ++ intel_hdmi->color_range_video = true; + break; ++ case INTEL_BROADCAST_RGB_VIDEO: ++ intel_hdmi->color_range_auto = false; ++ intel_hdmi->color_range = 0; ++ intel_hdmi->color_range_video = true; + default: + return -EINVAL; + } + + if (old_auto == intel_hdmi->color_range_auto && +- old_range == intel_hdmi->color_range) ++ old_range == intel_hdmi->color_range && ++ old_range_video == intel_hdmi->color_range_video) + return 0; + + goto done; +diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c +index 0e860f3..db39cbb 100644 +--- a/drivers/gpu/drm/i915/intel_modes.c ++++ b/drivers/gpu/drm/i915/intel_modes.c +@@ -103,6 +103,7 @@ static const struct drm_prop_enum_list broadcast_rgb_names[] = { + { INTEL_BROADCAST_RGB_AUTO, "Automatic" }, + { INTEL_BROADCAST_RGB_FULL, "Full" }, + { INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" }, ++ { INTEL_BROADCAST_RGB_VIDEO, "Video 16:235 pass-through" }, + }; + + void +-- +2.1.4 + diff --git a/packages/linux/patches/4.1.12/linux-999-i915-use-legacy-turbo.patch b/packages/linux/patches/4.3/linux-999-i915-use-legacy-turbo.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-999-i915-use-legacy-turbo.patch rename to packages/linux/patches/4.3/linux-999-i915-use-legacy-turbo.patch diff --git a/packages/linux/patches/4.1.12/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch b/packages/linux/patches/4.3/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch rename to packages/linux/patches/4.3/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch diff --git a/packages/linux/patches/4.1.12/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch b/packages/linux/patches/4.3/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch similarity index 100% rename from packages/linux/patches/4.1.12/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch rename to packages/linux/patches/4.3/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch diff --git a/projects/Generic/linux/linux.x86_64.conf b/projects/Generic/linux/linux.x86_64.conf index 3280f0fd31..51f262c8b2 100644 --- a/projects/Generic/linux/linux.x86_64.conf +++ b/projects/Generic/linux/linux.x86_64.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.1.10 Kernel Configuration +# Linux/x86_64 4.3.0 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -36,7 +36,6 @@ CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_X86_64_SMP=y -CONFIG_X86_HT=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y @@ -82,10 +81,11 @@ CONFIG_HAVE_ARCH_AUDITSYSCALL=y # CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y # CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y @@ -123,22 +123,11 @@ CONFIG_BSD_PROCESS_ACCT=y # RCU Subsystem # CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y # CONFIG_TASKS_RCU is not set CONFIG_RCU_STALL_COMMON=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_RCU_USER_QS=y -CONFIG_CONTEXT_TRACKING_FORCE=y -CONFIG_RCU_FANOUT=32 -CONFIG_RCU_FANOUT_LEAF=16 -# CONFIG_RCU_FANOUT_EXACT is not set -CONFIG_RCU_FAST_NO_HZ=y # CONFIG_TREE_RCU_TRACE is not set -CONFIG_RCU_KTHREAD_PRIO=0 -CONFIG_RCU_NOCB_CPU=y -# CONFIG_RCU_NOCB_CPU_NONE is not set -# CONFIG_RCU_NOCB_CPU_ZERO is not set -CONFIG_RCU_NOCB_CPU_ALL=y # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m @@ -147,12 +136,14 @@ CONFIG_LOG_BUF_SHIFT=16 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_PIDS is not set CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y @@ -169,6 +160,7 @@ CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y # CONFIG_CHECKPOINT_RESTORE is not set CONFIG_NAMESPACES=y CONFIG_UTS_NS=y @@ -218,7 +210,9 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y # CONFIG_AIO is not set CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set CONFIG_PCI_QUIRKS=y +CONFIG_MEMBARRIER=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y @@ -234,12 +228,13 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_SLUB_CPU_PARTIAL=y -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_DATA_VERIFICATION is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y CONFIG_OPROFILE_NMI_TIMER=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set # CONFIG_UPROBES is not set # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -253,6 +248,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -285,6 +281,7 @@ CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y @@ -305,6 +302,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_MODULE_SIG is not set # CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULES_TREE_LOOKUP=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y @@ -358,8 +356,10 @@ CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_ARCH_USE_QUEUE_RWLOCK=y -CONFIG_QUEUE_RWLOCK=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y CONFIG_FREEZER=y # @@ -411,6 +411,7 @@ CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set # CONFIG_X86_MCE is not set +# CONFIG_VM86 is not set CONFIG_X86_16BIT=y CONFIG_X86_ESPFIX64=y CONFIG_X86_VSYSCALL_EMULATION=y @@ -474,6 +475,9 @@ CONFIG_CLEANCACHE=y # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y # CONFIG_X86_PMEM_LEGACY is not set CONFIG_X86_CHECK_BIOS_CORRUPTION=y CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y @@ -498,6 +502,7 @@ CONFIG_HZ_300=y CONFIG_HZ=300 CONFIG_SCHED_HRTICK=y # CONFIG_KEXEC is not set +# CONFIG_KEXEC_FILE is not set # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y @@ -510,6 +515,7 @@ CONFIG_HOTPLUG_CPU=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init usbcore.autosuspend=-1" # CONFIG_CMDLINE_OVERRIDE is not set +CONFIG_MODIFY_LDT_SYSCALL=y CONFIG_HAVE_LIVEPATCH=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y @@ -519,6 +525,7 @@ CONFIG_USE_PERCPU_NUMA_NODE_ID=y # CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set # CONFIG_HIBERNATION is not set CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y @@ -538,6 +545,7 @@ CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS_POWER is not set +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y # CONFIG_ACPI_EC_DEBUGFS is not set # CONFIG_ACPI_AC is not set CONFIG_ACPI_BATTERY=y @@ -545,6 +553,8 @@ CONFIG_ACPI_BUTTON=y CONFIG_ACPI_VIDEO=y CONFIG_ACPI_FAN=y # CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_IDLE=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_PROCESSOR_AGGREGATOR=y @@ -562,6 +572,7 @@ CONFIG_ACPI_HOTPLUG_IOAPIC=y # CONFIG_ACPI_CUSTOM_METHOD is not set # CONFIG_ACPI_BGRT is not set # CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +# CONFIG_ACPI_NFIT is not set CONFIG_HAVE_ACPI_APEI=y CONFIG_HAVE_ACPI_APEI_NMI=y # CONFIG_ACPI_APEI is not set @@ -636,6 +647,7 @@ CONFIG_PCIEASPM_DEFAULT=y CONFIG_PCIE_PME=y CONFIG_PCI_BUS_ADDR_T_64BIT=y CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set # CONFIG_PCI_STUB is not set @@ -703,7 +715,6 @@ CONFIG_IP_MROUTE=y # CONFIG_NET_UDP_TUNNEL is not set # CONFIG_NET_FOU is not set # CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_GENEVE is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set @@ -725,6 +736,7 @@ CONFIG_IPV6=y # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set # CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set @@ -749,6 +761,7 @@ CONFIG_BRIDGE_NETFILTER=m # # Core Netfilter Configuration # +# CONFIG_NETFILTER_INGRESS is not set CONFIG_NETFILTER_NETLINK=m # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set @@ -866,6 +879,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m # CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_DUP_IPV4 is not set # CONFIG_NF_LOG_ARP is not set # CONFIG_NF_LOG_IPV4 is not set CONFIG_NF_REJECT_IPV4=m @@ -893,6 +907,7 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m # CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_NF_DUP_IPV6 is not set CONFIG_NF_REJECT_IPV6=m # CONFIG_NF_LOG_IPV6 is not set CONFIG_NF_NAT_IPV6=m @@ -975,6 +990,7 @@ CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m +CONFIG_BT_HS=y CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set # CONFIG_BT_DEBUGFS is not set @@ -984,8 +1000,10 @@ CONFIG_BT_LE=y # CONFIG_BT_INTEL=m CONFIG_BT_BCM=m +CONFIG_BT_RTL=m CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set # CONFIG_BT_HCIBCM203X is not set @@ -1028,12 +1046,14 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set CONFIG_HAVE_BPF_JIT=y # @@ -1071,6 +1091,7 @@ CONFIG_DMA_SHARED_BUFFER=y CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y # CONFIG_MTD is not set +# CONFIG_OF is not set CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y # CONFIG_PARPORT is not set CONFIG_PNP=y @@ -1099,7 +1120,6 @@ CONFIG_BLK_DEV_NVME=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set @@ -1158,6 +1178,11 @@ CONFIG_ALTERA_STAPL=m # # CONFIG_INTEL_MIC_BUS is not set +# +# SCIF Bus Driver +# +# CONFIG_SCIF_BUS is not set + # # Intel MIC Host Driver # @@ -1165,9 +1190,15 @@ CONFIG_ALTERA_STAPL=m # # Intel MIC Card Driver # + +# +# SCIF Driver +# # CONFIG_GENWQE is not set # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -1240,6 +1271,7 @@ CONFIG_SCSI_MVSAS=y # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_VMWARE_PVSCSI is not set +# CONFIG_SCSI_SNIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -1382,6 +1414,7 @@ CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y CONFIG_TUN=y +# CONFIG_TUN_VNET_CROSS_LE is not set CONFIG_VETH=m # CONFIG_NLMON is not set # CONFIG_ARCNET is not set @@ -1426,6 +1459,11 @@ CONFIG_CNIC=y CONFIG_TIGON3=y # CONFIG_BNX2X is not set # CONFIG_NET_VENDOR_BROCADE is not set +CONFIG_NET_VENDOR_CAVIUM=y +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_THUNDER_NIC_VF is not set +# CONFIG_THUNDER_NIC_BGX is not set +# CONFIG_LIQUIDIO is not set # CONFIG_NET_VENDOR_CHELSIO is not set # CONFIG_NET_VENDOR_CISCO is not set # CONFIG_CX_ECAT is not set @@ -1440,6 +1478,7 @@ CONFIG_NET_TULIP=y CONFIG_ULI526X=y # CONFIG_NET_VENDOR_DLINK is not set # CONFIG_NET_VENDOR_EMULEX is not set +CONFIG_NET_VENDOR_EZCHIP=y # CONFIG_NET_VENDOR_EXAR is not set # CONFIG_NET_VENDOR_HP is not set CONFIG_NET_VENDOR_INTEL=y @@ -1489,6 +1528,7 @@ CONFIG_8139TOO=y # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set CONFIG_R8169=y +CONFIG_NET_VENDOR_RENESAS=y # CONFIG_NET_VENDOR_RDC is not set CONFIG_NET_VENDOR_ROCKER=y # CONFIG_NET_VENDOR_SAMSUNG is not set @@ -1501,6 +1541,7 @@ CONFIG_SIS190=y # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_SUN is not set +CONFIG_NET_VENDOR_SYNOPSYS=y # CONFIG_NET_VENDOR_TEHUTI is not set # CONFIG_NET_VENDOR_TI is not set CONFIG_NET_VENDOR_VIA=y @@ -1516,6 +1557,7 @@ CONFIG_PHYLIB=y # # MII PHY device drivers # +# CONFIG_AQUANTIA_PHY is not set CONFIG_AT803X_PHY=y CONFIG_AMD_PHY=y CONFIG_MARVELL_PHY=y @@ -1524,6 +1566,7 @@ CONFIG_MARVELL_PHY=y # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set # CONFIG_SMSC_PHY is not set CONFIG_BROADCOM_PHY=y # CONFIG_BCM7XXX_PHY is not set @@ -1534,8 +1577,12 @@ CONFIG_REALTEK_PHY=y # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set # CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_OCTEON is not set # CONFIG_MDIO_BCM_UNIMAC is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -1554,6 +1601,7 @@ CONFIG_USB_NET_DRIVERS=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set CONFIG_USB_RTL8152=m +# CONFIG_USB_LAN78XX is not set CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_AX88179_178A=m @@ -1581,6 +1629,7 @@ CONFIG_USB_NET_RNDIS_HOST=m # CONFIG_USB_IPHETH is not set # CONFIG_USB_SIERRA_NET is not set # CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set CONFIG_WLAN=y CONFIG_LIBERTAS_THINFIRM=m # CONFIG_LIBERTAS_THINFIRM_DEBUG is not set @@ -1745,12 +1794,14 @@ CONFIG_ZD1211RW=m # # CONFIG_WAN is not set # CONFIG_VMXNET3 is not set +# CONFIG_FUJITSU_ES is not set # CONFIG_ISDN is not set # # Input device support # CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_SPARSEKMAP is not set @@ -1837,6 +1888,7 @@ CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y # CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set # CONFIG_TOUCHSCREEN_BU21013 is not set @@ -1864,6 +1916,7 @@ CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set # CONFIG_TOUCHSCREEN_WM97XX is not set CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_TOUCHSCREEN_USB_EGALAX=y @@ -1883,7 +1936,7 @@ CONFIG_TOUCHSCREEN_USB_EGALAX=y # CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set # CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set # CONFIG_TOUCHSCREEN_USB_NEXIO is not set -# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC_SERIO is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set @@ -1911,6 +1964,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set # CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set # @@ -1966,6 +2020,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # # Non-8250 serial port support # +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set @@ -2005,6 +2060,7 @@ CONFIG_I2C_MUX=m # # CONFIG_I2C_MUX_PCA9541 is not set # CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=y @@ -2042,6 +2098,7 @@ CONFIG_I2C_VIAPRO=y # # CONFIG_I2C_DESIGNWARE_PLATFORM is not set # CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_PXA_PCI is not set @@ -2154,6 +2211,7 @@ CONFIG_SENSORS_FAM15H_POWER=m # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set # CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_DELL_SMM is not set # CONFIG_SENSORS_I5K_AMB is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set @@ -2229,6 +2287,7 @@ CONFIG_SENSORS_IT87=m # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set # CONFIG_SENSORS_TMP103 is not set @@ -2255,21 +2314,22 @@ CONFIG_SENSORS_W83627EHF=y CONFIG_SENSORS_ATK0110=m CONFIG_THERMAL=y CONFIG_THERMAL_HWMON=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_GOV_FAIR_SHARE is not set CONFIG_THERMAL_GOV_STEP_WISE=y # CONFIG_THERMAL_GOV_BANG_BANG is not set # CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_EMULATION is not set CONFIG_INTEL_POWERCLAMP=m +CONFIG_INTEL_SOC_DTS_IOSF_CORE=m CONFIG_INTEL_SOC_DTS_THERMAL=m # CONFIG_INT340X_THERMAL is not set - -# -# Texas Instruments thermal drivers -# +# CONFIG_INTEL_PCH_THERMAL is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -2312,6 +2372,7 @@ CONFIG_MFD_CORE=y # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_DA9052_I2C is not set # CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set @@ -2320,7 +2381,8 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set # CONFIG_LPC_ICH is not set CONFIG_LPC_SCH=y -# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_MFD_INTEL_LPSS_ACPI is not set +# CONFIG_MFD_INTEL_LPSS_PCI is not set # CONFIG_MFD_JANZ_CMODIO is not set # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set @@ -2545,17 +2607,18 @@ CONFIG_MEDIA_PCI_SUPPORT=y # # Media capture support # +# CONFIG_VIDEO_SOLO6X10 is not set +# CONFIG_VIDEO_TW68 is not set +# CONFIG_VIDEO_ZORAN is not set # # Media capture/analog TV support # # CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_ZORAN is not set # CONFIG_VIDEO_HEXIUM_GEMINI is not set # CONFIG_VIDEO_HEXIUM_ORION is not set # CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_SOLO6X10 is not set -# CONFIG_VIDEO_TW68 is not set +# CONFIG_VIDEO_DT3155 is not set # # Media capture/analog/hybrid TV support @@ -2604,6 +2667,7 @@ CONFIG_DVB_SMIPCIE=m # CONFIG_V4L_PLATFORM_DRIVERS is not set # CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set # # Supported MMC/SDIO adapters @@ -2626,10 +2690,6 @@ CONFIG_CYPRESS_FIRMWARE=m CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_VIDEO_SAA7146=m CONFIG_VIDEO_SAA7146_VV=m -CONFIG_SAA716X_SUPPORT=y -CONFIG_SAA716X_CORE=m -CONFIG_DVB_SAA716X_BUDGET=m -CONFIG_DVB_SAA716X_HYBRID=m CONFIG_SMS_SIANO_MDTV=m CONFIG_SMS_SIANO_RC=y # CONFIG_SMS_SIANO_DEBUGFS is not set @@ -2727,7 +2787,6 @@ CONFIG_MEDIA_TUNER_R820T=m # # Multistandard (satellite) frontends # -CONFIG_DVB_CX24120=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m @@ -2740,9 +2799,6 @@ CONFIG_DVB_M88DS3103=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_SI2165=m -CONFIG_DVB_STV0367DD=m -CONFIG_DVB_TDA18212DD=m -CONFIG_DVB_CXD2843=m # # DVB-S (satellite) frontends @@ -2767,6 +2823,7 @@ CONFIG_DVB_TDA826X=m CONFIG_DVB_TUA6100=m CONFIG_DVB_CX24116=m CONFIG_DVB_CX24117=m +CONFIG_DVB_CX24120=m CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m CONFIG_DVB_DS3000=m @@ -2873,14 +2930,11 @@ CONFIG_INTEL_GTT=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=16 CONFIG_VGA_SWITCHEROO=y - -# -# Direct Rendering Manager -# CONFIG_DRM=y CONFIG_DRM_MIPI_DSI=y CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_TTM=y @@ -2896,11 +2950,10 @@ CONFIG_DRM_TTM=y CONFIG_DRM_RADEON=y # CONFIG_DRM_RADEON_USERPTR is not set # CONFIG_DRM_RADEON_UMS is not set +# CONFIG_DRM_AMDGPU is not set # CONFIG_DRM_NOUVEAU is not set # CONFIG_DRM_I810 is not set CONFIG_DRM_I915=y -CONFIG_DRM_I915_KMS=y -CONFIG_DRM_I915_FBDEV=y # CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT is not set # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set @@ -2920,6 +2973,11 @@ CONFIG_DRM_PANEL=y # # Display Panels # +CONFIG_DRM_BRIDGE=y + +# +# Display Interface Bridges +# # # Frame buffer Devices @@ -2933,11 +2991,11 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_SYS_FOPS=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -2989,11 +3047,13 @@ CONFIG_FB_EFI=y # CONFIG_FB_BROADSHEET is not set # CONFIG_FB_AUO_K190X is not set # CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SM712 is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_PM8941_WLED is not set # CONFIG_BACKLIGHT_SAHARA is not set # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set @@ -3031,11 +3091,11 @@ CONFIG_SND_HRTIMER=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_MAX_CARDS=32 # CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y -CONFIG_SND_KCTL_JACK=y CONFIG_SND_DMA_SGBUF=y # CONFIG_SND_RAWMIDI_SEQ is not set # CONFIG_SND_OPL3_LIB_SEQ is not set @@ -3118,20 +3178,16 @@ CONFIG_SND_VIRTUOSO=m # CONFIG_SND_HDA=m CONFIG_SND_HDA_INTEL=m -CONFIG_SND_HDA_DSP_LOADER=y -CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_HDA_HWDEP=y CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=1 -CONFIG_SND_HDA_INPUT_JACK=y CONFIG_SND_HDA_PATCH_LOADER=y CONFIG_SND_HDA_CODEC_REALTEK=m CONFIG_SND_HDA_CODEC_ANALOG=m CONFIG_SND_HDA_CODEC_SIGMATEL=m CONFIG_SND_HDA_CODEC_VIA=m CONFIG_SND_HDA_CODEC_HDMI=m -CONFIG_SND_HDA_I915=y CONFIG_SND_HDA_CODEC_CIRRUS=m CONFIG_SND_HDA_CODEC_CONEXANT=m CONFIG_SND_HDA_CODEC_CA0110=m @@ -3142,6 +3198,9 @@ CONFIG_SND_HDA_CODEC_SI3054=m CONFIG_SND_HDA_GENERIC=m CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 CONFIG_SND_HDA_CORE=m +CONFIG_SND_HDA_DSP_LOADER=y +CONFIG_SND_HDA_I915=y +CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m @@ -3197,6 +3256,7 @@ CONFIG_DRAGONRISE_FF=y # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_GEMBIRD is not set # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set @@ -3281,6 +3341,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set # CONFIG_USB_MON is not set # CONFIG_USB_WUSB_CBAF is not set @@ -3290,6 +3351,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_C67X00_HCD is not set CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y +# CONFIG_USB_XHCI_PLATFORM is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y @@ -3478,6 +3540,7 @@ CONFIG_MMC_SDHCI_ACPI=y CONFIG_MMC_REALTEK_PCI=m CONFIG_MMC_REALTEK_USB=m CONFIG_MMC_TOSHIBA_PCI=m +# CONFIG_MMC_MTK is not set CONFIG_MEMSTICK=m # CONFIG_MEMSTICK_DEBUG is not set @@ -3518,13 +3581,13 @@ CONFIG_LEDS_CLASS_FLASH=y # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_INTEL_SS4200 is not set # CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set # CONFIG_LEDS_LM355x is not set # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set -# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -3544,12 +3607,15 @@ CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_CAMERA is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y # CONFIG_EDAC is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_SYSTOHC=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" # CONFIG_RTC_DEBUG is not set # @@ -3616,7 +3682,6 @@ CONFIG_RTC_DRV_CMOS=y # # on-CPU RTC drivers # -# CONFIG_RTC_DRV_XGENE is not set # # HID Sensor RTC drivers @@ -3632,6 +3697,7 @@ CONFIG_UIO=y # CONFIG_UIO_SERCOS3 is not set # CONFIG_UIO_PCI_GENERIC is not set # CONFIG_UIO_NETX is not set +# CONFIG_UIO_PRUSS is not set # CONFIG_UIO_MF624 is not set # CONFIG_VIRT_DRIVERS is not set @@ -3655,7 +3721,6 @@ CONFIG_R8712U=m CONFIG_RTS5208=y # CONFIG_VT6655 is not set CONFIG_VT6656=m -# CONFIG_FB_SM7XX is not set # CONFIG_FB_SM750 is not set # CONFIG_FB_XGI is not set # CONFIG_FT1000 is not set @@ -3667,7 +3732,6 @@ CONFIG_VT6656=m # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set CONFIG_STAGING_MEDIA=y CONFIG_DVB_CXD2099=m -# CONFIG_VIDEO_DT3155 is not set CONFIG_DVB_MN88472=m CONFIG_DVB_MN88473=m CONFIG_LIRC_STAGING=y @@ -3683,7 +3747,6 @@ CONFIG_LIRC_XBOX=m # # Android # -# CONFIG_USB_WPAN_HCD is not set # CONFIG_WIMAX_GDM72XX is not set # CONFIG_LTE_GDM724X is not set # CONFIG_FIREWIRE_SERIAL is not set @@ -3693,7 +3756,7 @@ CONFIG_LIRC_XBOX=m # CONFIG_GS_FPGABOOT is not set # CONFIG_CRYPTO_SKEIN is not set # CONFIG_UNISYSSPAR is not set -# CONFIG_I2O is not set +# CONFIG_MOST is not set # CONFIG_X86_PLATFORM_DEVICES is not set # CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y @@ -3736,6 +3799,7 @@ CONFIG_CLKBLD_I8253=y # # SOC (System On Chip) specific Drivers # +# CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set # CONFIG_EXTCON is not set @@ -3752,10 +3816,16 @@ CONFIG_CLKBLD_I8253=y # PHY Subsystem # # CONFIG_GENERIC_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_BCM_KONA_USB2_PHY is not set CONFIG_POWERCAP=y CONFIG_INTEL_RAPL=m # CONFIG_MCB is not set + +# +# Performance monitor support +# CONFIG_RAS=y CONFIG_THUNDERBOLT=m @@ -3763,6 +3833,8 @@ CONFIG_THUNDERBOLT=m # Android # # CONFIG_ANDROID is not set +# CONFIG_LIBNVDIMM is not set +# CONFIG_NVMEM is not set # # Firmware Drivers @@ -3782,6 +3854,7 @@ CONFIG_ISCSI_IBFT=y # EFI (Extensible Firmware Interface) Support # CONFIG_EFI_VARS=y +CONFIG_EFI_ESRT=y CONFIG_EFI_RUNTIME_WRAPPERS=y # @@ -3791,7 +3864,7 @@ CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y # CONFIG_EXT4_ENCRYPTION is not set @@ -3872,6 +3945,7 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -4063,7 +4137,6 @@ CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_ARCH_KMEMCHECK=y CONFIG_HAVE_ARCH_KASAN=y # CONFIG_KASAN is not set -CONFIG_KASAN_SHADOW_OFFSET=0xdffffc0000000000 # CONFIG_DEBUG_SHIRQ is not set # @@ -4083,6 +4156,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHED_INFO is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set @@ -4118,8 +4192,8 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_CPU_STALL_INFO is not set # CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set @@ -4161,6 +4235,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set # CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -4189,8 +4264,11 @@ CONFIG_DEFAULT_IO_DELAY_TYPE=0 # CONFIG_DEBUG_BOOT_PARAMS is not set # CONFIG_CPA_DEBUG is not set CONFIG_OPTIMIZE_INLINING=y +# CONFIG_DEBUG_ENTRY is not set # CONFIG_DEBUG_NMI_SELFTEST is not set # CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set +CONFIG_X86_DEBUG_FPU=y +# CONFIG_PUNIT_ATOM_DEBUG is not set # # Security options @@ -4220,13 +4298,17 @@ CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +# CONFIG_CRYPTO_RSA is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_NULL2=y # CONFIG_CRYPTO_PCRYPT is not set CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set @@ -4239,7 +4321,9 @@ CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m # # Block modes @@ -4269,6 +4353,8 @@ CONFIG_CRYPTO_CRC32C=y # CONFIG_CRYPTO_CRC32_PCLMUL is not set # CONFIG_CRYPTO_CRCT10DIF is not set CONFIG_CRYPTO_GHASH=m +# CONFIG_CRYPTO_POLY1305 is not set +# CONFIG_CRYPTO_POLY1305_X86_64 is not set CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m @@ -4311,6 +4397,8 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set # CONFIG_CRYPTO_SALSA20_X86_64 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_CHACHA20_X86_64 is not set # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set @@ -4328,6 +4416,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set @@ -4335,12 +4424,23 @@ CONFIG_CRYPTO_DES=y # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_DRBG_MENU is not set +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m # CONFIG_CRYPTO_USER_API_HASH is not set # CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set # CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set CONFIG_HAVE_KVM=y CONFIG_KVM_COMPAT=y # CONFIG_VIRTUALIZATION is not set @@ -4404,7 +4504,6 @@ CONFIG_GLOB=y # CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_AVERAGE=y # CONFIG_CORDIC is not set # CONFIG_DDR is not set CONFIG_OID_REGISTRY=y @@ -4413,4 +4512,7 @@ CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_ARCH_HAS_MMIO_FLUSH=y diff --git a/projects/Nvidia_Legacy/linux/linux.x86_64.conf b/projects/Nvidia_Legacy/linux/linux.x86_64.conf index 2ae98cf6b4..da0bd174ec 100644 --- a/projects/Nvidia_Legacy/linux/linux.x86_64.conf +++ b/projects/Nvidia_Legacy/linux/linux.x86_64.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.1.10 Kernel Configuration +# Linux/x86_64 4.3.0 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -36,7 +36,6 @@ CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_X86_64_SMP=y -CONFIG_X86_HT=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y @@ -82,10 +81,11 @@ CONFIG_HAVE_ARCH_AUDITSYSCALL=y # CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y # CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y @@ -123,22 +123,11 @@ CONFIG_BSD_PROCESS_ACCT=y # RCU Subsystem # CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y # CONFIG_TASKS_RCU is not set CONFIG_RCU_STALL_COMMON=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_RCU_USER_QS=y -CONFIG_CONTEXT_TRACKING_FORCE=y -CONFIG_RCU_FANOUT=32 -CONFIG_RCU_FANOUT_LEAF=16 -# CONFIG_RCU_FANOUT_EXACT is not set -CONFIG_RCU_FAST_NO_HZ=y # CONFIG_TREE_RCU_TRACE is not set -CONFIG_RCU_KTHREAD_PRIO=0 -CONFIG_RCU_NOCB_CPU=y -# CONFIG_RCU_NOCB_CPU_NONE is not set -# CONFIG_RCU_NOCB_CPU_ZERO is not set -CONFIG_RCU_NOCB_CPU_ALL=y # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m @@ -147,21 +136,38 @@ CONFIG_LOG_BUF_SHIFT=16 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set -# CONFIG_CGROUP_FREEZER is not set -# CONFIG_CGROUP_DEVICE is not set -# CONFIG_CPUSETS is not set -# CONFIG_CGROUP_CPUACCT is not set -# CONFIG_MEMCG is not set -# CONFIG_CGROUP_PERF is not set -# CONFIG_CGROUP_SCHED is not set -# CONFIG_BLK_CGROUP is not set +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_PIDS is not set +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y # CONFIG_CHECKPOINT_RESTORE is not set -# CONFIG_NAMESPACES is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +# CONFIG_USER_NS is not set +CONFIG_PID_NS=y +CONFIG_NET_NS=y # CONFIG_SCHED_AUTOGROUP is not set # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y @@ -204,7 +210,9 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y # CONFIG_AIO is not set CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set CONFIG_PCI_QUIRKS=y +CONFIG_MEMBARRIER=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y @@ -220,12 +228,13 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_SLUB_CPU_PARTIAL=y -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_DATA_VERIFICATION is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y CONFIG_OPROFILE_NMI_TIMER=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set # CONFIG_UPROBES is not set # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -239,6 +248,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -271,6 +281,7 @@ CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y @@ -291,11 +302,13 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_MODULE_SIG is not set # CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULES_TREE_LOOKUP=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_THROTTLING is not set # CONFIG_BLK_CMDLINE_PARSER is not set # @@ -330,6 +343,7 @@ CONFIG_BLOCK_COMPAT=y CONFIG_IOSCHED_NOOP=y # CONFIG_IOSCHED_DEADLINE is not set CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" @@ -342,8 +356,10 @@ CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_ARCH_USE_QUEUE_RWLOCK=y -CONFIG_QUEUE_RWLOCK=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y CONFIG_FREEZER=y # @@ -395,6 +411,7 @@ CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set # CONFIG_X86_MCE is not set +# CONFIG_VM86 is not set CONFIG_X86_16BIT=y CONFIG_X86_ESPFIX64=y CONFIG_X86_VSYSCALL_EMULATION=y @@ -458,6 +475,9 @@ CONFIG_CLEANCACHE=y # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y # CONFIG_X86_PMEM_LEGACY is not set CONFIG_X86_CHECK_BIOS_CORRUPTION=y CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y @@ -482,6 +502,7 @@ CONFIG_HZ_300=y CONFIG_HZ=300 CONFIG_SCHED_HRTICK=y # CONFIG_KEXEC is not set +# CONFIG_KEXEC_FILE is not set # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y @@ -494,6 +515,7 @@ CONFIG_HOTPLUG_CPU=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init usbcore.autosuspend=-1" # CONFIG_CMDLINE_OVERRIDE is not set +CONFIG_MODIFY_LDT_SYSCALL=y CONFIG_HAVE_LIVEPATCH=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y @@ -503,6 +525,7 @@ CONFIG_USE_PERCPU_NUMA_NODE_ID=y # CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set # CONFIG_HIBERNATION is not set CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y @@ -522,6 +545,7 @@ CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS_POWER is not set +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y # CONFIG_ACPI_EC_DEBUGFS is not set # CONFIG_ACPI_AC is not set CONFIG_ACPI_BATTERY=y @@ -529,6 +553,8 @@ CONFIG_ACPI_BUTTON=y CONFIG_ACPI_VIDEO=y CONFIG_ACPI_FAN=y # CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_IDLE=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_PROCESSOR_AGGREGATOR=y @@ -546,6 +572,7 @@ CONFIG_ACPI_HOTPLUG_IOAPIC=y # CONFIG_ACPI_CUSTOM_METHOD is not set # CONFIG_ACPI_BGRT is not set # CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +# CONFIG_ACPI_NFIT is not set CONFIG_HAVE_ACPI_APEI=y CONFIG_HAVE_ACPI_APEI_NMI=y # CONFIG_ACPI_APEI is not set @@ -620,6 +647,7 @@ CONFIG_PCIEASPM_DEFAULT=y CONFIG_PCIE_PME=y CONFIG_PCI_BUS_ADDR_T_64BIT=y CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set # CONFIG_PCI_STUB is not set @@ -687,7 +715,6 @@ CONFIG_IP_MROUTE=y # CONFIG_NET_UDP_TUNNEL is not set # CONFIG_NET_FOU is not set # CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_GENEVE is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set @@ -709,6 +736,7 @@ CONFIG_IPV6=y # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set # CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set @@ -728,11 +756,12 @@ CONFIG_NET_PTP_CLASSIFY=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y -# CONFIG_BRIDGE_NETFILTER is not set +CONFIG_BRIDGE_NETFILTER=m # # Core Netfilter Configuration # +# CONFIG_NETFILTER_INGRESS is not set CONFIG_NETFILTER_NETLINK=m # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set @@ -798,7 +827,7 @@ CONFIG_NETFILTER_XT_NAT=m # # Xtables matches # -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m # CONFIG_NETFILTER_XT_MATCH_BPF is not set # CONFIG_NETFILTER_XT_MATCH_CGROUP is not set # CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set @@ -807,7 +836,7 @@ CONFIG_NETFILTER_XT_NAT=m # CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set # CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set # CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set -# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m # CONFIG_NETFILTER_XT_MATCH_CPU is not set # CONFIG_NETFILTER_XT_MATCH_DCCP is not set # CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set @@ -828,6 +857,7 @@ CONFIG_NETFILTER_XT_MATCH_IPRANGE=m # CONFIG_NETFILTER_XT_MATCH_NFACCT is not set # CONFIG_NETFILTER_XT_MATCH_OSF is not set CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set @@ -849,6 +879,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m # CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_DUP_IPV4 is not set # CONFIG_NF_LOG_ARP is not set # CONFIG_NF_LOG_IPV4 is not set CONFIG_NF_REJECT_IPV4=m @@ -876,6 +907,7 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m # CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_NF_DUP_IPV6 is not set CONFIG_NF_REJECT_IPV6=m # CONFIG_NF_LOG_IPV6 is not set CONFIG_NF_NAT_IPV6=m @@ -958,6 +990,7 @@ CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m +CONFIG_BT_HS=y CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set # CONFIG_BT_DEBUGFS is not set @@ -967,8 +1000,10 @@ CONFIG_BT_LE=y # CONFIG_BT_INTEL=m CONFIG_BT_BCM=m +CONFIG_BT_RTL=m CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set # CONFIG_BT_HCIBCM203X is not set @@ -1011,12 +1046,14 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set CONFIG_HAVE_BPF_JIT=y # @@ -1033,7 +1070,7 @@ CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_FW_LOADER=y CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="bnx2/bnx2-mips-06-6.2.1.fw bnx2/bnx2-mips-09-6.2.1a.fw bnx2/bnx2-rv2p-06-6.0.15.fw bnx2/bnx2-rv2p-09-6.0.17.fw bnx2/bnx2-rv2p-09ax-6.0.17.fw tigon/tg3.bin tigon/tg3_tso5.bin tigon/tg3_tso.bin rtl_nic/rtl8105e-1.fw rtl_nic/rtl8106e-1.fw rtl_nic/rtl8106e-2.fw rtl_nic/rtl8107e-1.fw rtl_nic/rtl8107e-2.fw rtl_nic/rtl8168d-1.fw rtl_nic/rtl8168d-2.fw rtl_nic/rtl8168e-1.fw rtl_nic/rtl8168e-2.fw rtl_nic/rtl8168e-3.fw rtl_nic/rtl8168f-1.fw rtl_nic/rtl8168f-2.fw rtl_nic/rtl8168g-1.fw rtl_nic/rtl8168g-2.fw rtl_nic/rtl8168g-3.fw rtl_nic/rtl8168h-1.fw rtl_nic/rtl8168h-2.fw rtl_nic/rtl8402-1.fw rtl_nic/rtl8411-1.fw rtl_nic/rtl8411-2.fw" +CONFIG_EXTRA_FIRMWARE="i915/bxt_dmc_ver1_04.bin i915/bxt_dmc_ver1_05.bin i915/bxt_dmc_ver1_06.bin i915/bxt_dmc_ver1.bin i915/skl_dmc_ver1_21.bin i915/skl_dmc_ver1_22.bin i915/skl_dmc_ver1.bin i915/skl_guc_ver1_1059.bin i915/skl_guc_ver1.bin i915/skl_guc_ver4_3.bin i915/skl_guc_ver4.bin bnx2/bnx2-mips-06-6.2.1.fw bnx2/bnx2-mips-09-6.2.1a.fw bnx2/bnx2-rv2p-06-6.0.15.fw bnx2/bnx2-rv2p-09-6.0.17.fw bnx2/bnx2-rv2p-09ax-6.0.17.fw tigon/tg3.bin tigon/tg3_tso5.bin tigon/tg3_tso.bin rtl_nic/rtl8105e-1.fw rtl_nic/rtl8106e-1.fw rtl_nic/rtl8106e-2.fw rtl_nic/rtl8107e-1.fw rtl_nic/rtl8107e-2.fw rtl_nic/rtl8168d-1.fw rtl_nic/rtl8168d-2.fw rtl_nic/rtl8168e-1.fw rtl_nic/rtl8168e-2.fw rtl_nic/rtl8168e-3.fw rtl_nic/rtl8168f-1.fw rtl_nic/rtl8168f-2.fw rtl_nic/rtl8168g-1.fw rtl_nic/rtl8168g-2.fw rtl_nic/rtl8168g-3.fw rtl_nic/rtl8168h-1.fw rtl_nic/rtl8168h-2.fw rtl_nic/rtl8402-1.fw rtl_nic/rtl8411-1.fw rtl_nic/rtl8411-2.fw radeon/ARUBA_me.bin radeon/ARUBA_pfp.bin radeon/ARUBA_rlc.bin radeon/BARTS_mc.bin radeon/BARTS_me.bin radeon/BARTS_pfp.bin radeon/BARTS_smc.bin radeon/bonaire_ce.bin radeon/BONAIRE_ce.bin radeon/BONAIRE_mc2.bin radeon/bonaire_mc.bin radeon/BONAIRE_mc.bin radeon/bonaire_me.bin radeon/BONAIRE_me.bin radeon/bonaire_mec.bin radeon/BONAIRE_mec.bin radeon/bonaire_pfp.bin radeon/BONAIRE_pfp.bin radeon/bonaire_rlc.bin radeon/BONAIRE_rlc.bin radeon/bonaire_sdma.bin radeon/BONAIRE_sdma.bin radeon/bonaire_smc.bin radeon/BONAIRE_smc.bin radeon/BONAIRE_uvd.bin radeon/BONAIRE_vce.bin radeon/BTC_rlc.bin radeon/CAICOS_mc.bin radeon/CAICOS_me.bin radeon/CAICOS_pfp.bin radeon/CAICOS_smc.bin radeon/CAYMAN_mc.bin radeon/CAYMAN_me.bin radeon/CAYMAN_pfp.bin radeon/CAYMAN_rlc.bin radeon/CAYMAN_smc.bin radeon/CEDAR_me.bin radeon/CEDAR_pfp.bin radeon/CEDAR_rlc.bin radeon/CEDAR_smc.bin radeon/CYPRESS_me.bin radeon/CYPRESS_pfp.bin radeon/CYPRESS_rlc.bin radeon/CYPRESS_smc.bin radeon/CYPRESS_uvd.bin radeon/hainan_ce.bin radeon/HAINAN_ce.bin radeon/HAINAN_mc2.bin radeon/hainan_mc.bin radeon/HAINAN_mc.bin radeon/hainan_me.bin radeon/HAINAN_me.bin radeon/hainan_pfp.bin radeon/HAINAN_pfp.bin radeon/hainan_rlc.bin radeon/HAINAN_rlc.bin radeon/hainan_smc.bin radeon/HAINAN_smc.bin radeon/hawaii_ce.bin radeon/HAWAII_ce.bin radeon/HAWAII_mc2.bin radeon/hawaii_mc.bin radeon/HAWAII_mc.bin radeon/hawaii_me.bin radeon/HAWAII_me.bin radeon/hawaii_mec.bin radeon/HAWAII_mec.bin radeon/hawaii_pfp.bin radeon/HAWAII_pfp.bin radeon/hawaii_rlc.bin radeon/HAWAII_rlc.bin radeon/hawaii_sdma.bin radeon/HAWAII_sdma.bin radeon/hawaii_smc.bin radeon/HAWAII_smc.bin radeon/JUNIPER_me.bin radeon/JUNIPER_pfp.bin radeon/JUNIPER_rlc.bin radeon/JUNIPER_smc.bin radeon/kabini_ce.bin radeon/KABINI_ce.bin radeon/kabini_me.bin radeon/KABINI_me.bin radeon/kabini_mec.bin radeon/KABINI_mec.bin radeon/kabini_pfp.bin radeon/KABINI_pfp.bin radeon/kabini_rlc.bin radeon/KABINI_rlc.bin radeon/kabini_sdma.bin radeon/KABINI_sdma.bin radeon/kaveri_ce.bin radeon/KAVERI_ce.bin radeon/kaveri_me.bin radeon/KAVERI_me.bin radeon/kaveri_mec2.bin radeon/kaveri_mec.bin radeon/KAVERI_mec.bin radeon/kaveri_pfp.bin radeon/KAVERI_pfp.bin radeon/kaveri_rlc.bin radeon/KAVERI_rlc.bin radeon/kaveri_sdma.bin radeon/KAVERI_sdma.bin radeon/mullins_ce.bin radeon/MULLINS_ce.bin radeon/mullins_me.bin radeon/MULLINS_me.bin radeon/mullins_mec.bin radeon/MULLINS_mec.bin radeon/mullins_pfp.bin radeon/MULLINS_pfp.bin radeon/mullins_rlc.bin radeon/MULLINS_rlc.bin radeon/mullins_sdma.bin radeon/MULLINS_sdma.bin radeon/oland_ce.bin radeon/OLAND_ce.bin radeon/OLAND_mc2.bin radeon/oland_mc.bin radeon/OLAND_mc.bin radeon/oland_me.bin radeon/OLAND_me.bin radeon/oland_pfp.bin radeon/OLAND_pfp.bin radeon/oland_rlc.bin radeon/OLAND_rlc.bin radeon/oland_smc.bin radeon/OLAND_smc.bin radeon/PALM_me.bin radeon/PALM_pfp.bin radeon/pitcairn_ce.bin radeon/PITCAIRN_ce.bin radeon/PITCAIRN_mc2.bin radeon/pitcairn_mc.bin radeon/PITCAIRN_mc.bin radeon/pitcairn_me.bin radeon/PITCAIRN_me.bin radeon/pitcairn_pfp.bin radeon/PITCAIRN_pfp.bin radeon/pitcairn_rlc.bin radeon/PITCAIRN_rlc.bin radeon/pitcairn_smc.bin radeon/PITCAIRN_smc.bin radeon/R100_cp.bin radeon/R200_cp.bin radeon/R300_cp.bin radeon/R420_cp.bin radeon/R520_cp.bin radeon/R600_me.bin radeon/R600_pfp.bin radeon/R600_rlc.bin radeon/R600_uvd.bin radeon/R700_rlc.bin radeon/REDWOOD_me.bin radeon/REDWOOD_pfp.bin radeon/REDWOOD_rlc.bin radeon/REDWOOD_smc.bin radeon/RS600_cp.bin radeon/RS690_cp.bin radeon/RS780_me.bin radeon/RS780_pfp.bin radeon/RS780_uvd.bin radeon/RV610_me.bin radeon/RV610_pfp.bin radeon/RV620_me.bin radeon/RV620_pfp.bin radeon/RV630_me.bin radeon/RV630_pfp.bin radeon/RV635_me.bin radeon/RV635_pfp.bin radeon/RV670_me.bin radeon/RV670_pfp.bin radeon/RV710_me.bin radeon/RV710_pfp.bin radeon/RV710_smc.bin radeon/RV710_uvd.bin radeon/RV730_me.bin radeon/RV730_pfp.bin radeon/RV730_smc.bin radeon/RV740_smc.bin radeon/RV770_me.bin radeon/RV770_pfp.bin radeon/RV770_smc.bin radeon/RV770_uvd.bin radeon/SUMO2_me.bin radeon/SUMO2_pfp.bin radeon/SUMO_me.bin radeon/SUMO_pfp.bin radeon/SUMO_rlc.bin radeon/SUMO_uvd.bin radeon/tahiti_ce.bin radeon/TAHITI_ce.bin radeon/TAHITI_mc2.bin radeon/tahiti_mc.bin radeon/TAHITI_mc.bin radeon/tahiti_me.bin radeon/TAHITI_me.bin radeon/tahiti_pfp.bin radeon/TAHITI_pfp.bin radeon/tahiti_rlc.bin radeon/TAHITI_rlc.bin radeon/tahiti_smc.bin radeon/TAHITI_smc.bin radeon/TAHITI_uvd.bin radeon/TURKS_mc.bin radeon/TURKS_me.bin radeon/TURKS_pfp.bin radeon/TURKS_smc.bin radeon/verde_ce.bin radeon/VERDE_ce.bin radeon/VERDE_mc2.bin radeon/verde_mc.bin radeon/VERDE_mc.bin radeon/verde_me.bin radeon/VERDE_me.bin radeon/verde_pfp.bin radeon/VERDE_pfp.bin radeon/verde_rlc.bin radeon/VERDE_rlc.bin radeon/verde_smc.bin radeon/VERDE_smc.bin" CONFIG_EXTRA_FIRMWARE_DIR="firmware" # CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set CONFIG_WANT_DEV_COREDUMP=y @@ -1054,6 +1091,7 @@ CONFIG_DMA_SHARED_BUFFER=y CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y # CONFIG_MTD is not set +# CONFIG_OF is not set CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y # CONFIG_PARPORT is not set CONFIG_PNP=y @@ -1076,13 +1114,12 @@ CONFIG_BLK_DEV_LOOP_MIN_COUNT=0 # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_DRBD is not set CONFIG_BLK_DEV_NBD=y -# CONFIG_BLK_DEV_NVME is not set +CONFIG_BLK_DEV_NVME=y # CONFIG_BLK_DEV_SKD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set @@ -1141,6 +1178,11 @@ CONFIG_ALTERA_STAPL=m # # CONFIG_INTEL_MIC_BUS is not set +# +# SCIF Bus Driver +# +# CONFIG_SCIF_BUS is not set + # # Intel MIC Host Driver # @@ -1148,9 +1190,15 @@ CONFIG_ALTERA_STAPL=m # # Intel MIC Card Driver # + +# +# SCIF Driver +# # CONFIG_GENWQE is not set # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -1223,6 +1271,7 @@ CONFIG_SCSI_MVSAS=y # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_VMWARE_PVSCSI is not set +# CONFIG_SCSI_SNIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -1357,14 +1406,16 @@ CONFIG_NET_CORE=y # CONFIG_EQUALIZER is not set # CONFIG_NET_FC is not set # CONFIG_NET_TEAM is not set -# CONFIG_MACVLAN is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set # CONFIG_IPVLAN is not set # CONFIG_VXLAN is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y CONFIG_TUN=y -# CONFIG_VETH is not set +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m # CONFIG_NLMON is not set # CONFIG_ARCNET is not set @@ -1408,6 +1459,11 @@ CONFIG_CNIC=y CONFIG_TIGON3=y # CONFIG_BNX2X is not set # CONFIG_NET_VENDOR_BROCADE is not set +CONFIG_NET_VENDOR_CAVIUM=y +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_THUNDER_NIC_VF is not set +# CONFIG_THUNDER_NIC_BGX is not set +# CONFIG_LIQUIDIO is not set # CONFIG_NET_VENDOR_CHELSIO is not set # CONFIG_NET_VENDOR_CISCO is not set # CONFIG_CX_ECAT is not set @@ -1422,6 +1478,7 @@ CONFIG_NET_TULIP=y CONFIG_ULI526X=y # CONFIG_NET_VENDOR_DLINK is not set # CONFIG_NET_VENDOR_EMULEX is not set +CONFIG_NET_VENDOR_EZCHIP=y # CONFIG_NET_VENDOR_EXAR is not set # CONFIG_NET_VENDOR_HP is not set CONFIG_NET_VENDOR_INTEL=y @@ -1471,6 +1528,7 @@ CONFIG_8139TOO=y # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set CONFIG_R8169=y +CONFIG_NET_VENDOR_RENESAS=y # CONFIG_NET_VENDOR_RDC is not set CONFIG_NET_VENDOR_ROCKER=y # CONFIG_NET_VENDOR_SAMSUNG is not set @@ -1483,6 +1541,7 @@ CONFIG_SIS190=y # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_SUN is not set +CONFIG_NET_VENDOR_SYNOPSYS=y # CONFIG_NET_VENDOR_TEHUTI is not set # CONFIG_NET_VENDOR_TI is not set CONFIG_NET_VENDOR_VIA=y @@ -1498,6 +1557,7 @@ CONFIG_PHYLIB=y # # MII PHY device drivers # +# CONFIG_AQUANTIA_PHY is not set CONFIG_AT803X_PHY=y CONFIG_AMD_PHY=y CONFIG_MARVELL_PHY=y @@ -1506,6 +1566,7 @@ CONFIG_MARVELL_PHY=y # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set # CONFIG_SMSC_PHY is not set CONFIG_BROADCOM_PHY=y # CONFIG_BCM7XXX_PHY is not set @@ -1516,8 +1577,12 @@ CONFIG_REALTEK_PHY=y # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set # CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_OCTEON is not set # CONFIG_MDIO_BCM_UNIMAC is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -1536,6 +1601,7 @@ CONFIG_USB_NET_DRIVERS=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set CONFIG_USB_RTL8152=m +# CONFIG_USB_LAN78XX is not set CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_AX88179_178A=m @@ -1563,6 +1629,7 @@ CONFIG_USB_NET_RNDIS_HOST=m # CONFIG_USB_IPHETH is not set # CONFIG_USB_SIERRA_NET is not set # CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set CONFIG_WLAN=y CONFIG_LIBERTAS_THINFIRM=m # CONFIG_LIBERTAS_THINFIRM_DEBUG is not set @@ -1727,12 +1794,14 @@ CONFIG_ZD1211RW=m # # CONFIG_WAN is not set # CONFIG_VMXNET3 is not set +# CONFIG_FUJITSU_ES is not set # CONFIG_ISDN is not set # # Input device support # CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_SPARSEKMAP is not set @@ -1819,6 +1888,7 @@ CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y # CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set # CONFIG_TOUCHSCREEN_BU21013 is not set @@ -1846,6 +1916,7 @@ CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set # CONFIG_TOUCHSCREEN_WM97XX is not set CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_TOUCHSCREEN_USB_EGALAX=y @@ -1893,6 +1964,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set # CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set # @@ -1922,7 +1994,7 @@ CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -1948,6 +2020,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # # Non-8250 serial port support # +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set @@ -1987,6 +2060,7 @@ CONFIG_I2C_MUX=m # # CONFIG_I2C_MUX_PCA9541 is not set # CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=y @@ -2024,6 +2098,7 @@ CONFIG_I2C_VIAPRO=y # # CONFIG_I2C_DESIGNWARE_PLATFORM is not set # CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_PXA_PCI is not set @@ -2136,6 +2211,7 @@ CONFIG_SENSORS_FAM15H_POWER=m # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set # CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_DELL_SMM is not set # CONFIG_SENSORS_I5K_AMB is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set @@ -2211,6 +2287,7 @@ CONFIG_SENSORS_IT87=m # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set # CONFIG_SENSORS_TMP103 is not set @@ -2237,21 +2314,22 @@ CONFIG_SENSORS_W83627EHF=y CONFIG_SENSORS_ATK0110=m CONFIG_THERMAL=y CONFIG_THERMAL_HWMON=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_GOV_FAIR_SHARE is not set CONFIG_THERMAL_GOV_STEP_WISE=y # CONFIG_THERMAL_GOV_BANG_BANG is not set # CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_EMULATION is not set CONFIG_INTEL_POWERCLAMP=m +CONFIG_INTEL_SOC_DTS_IOSF_CORE=m CONFIG_INTEL_SOC_DTS_THERMAL=m # CONFIG_INT340X_THERMAL is not set - -# -# Texas Instruments thermal drivers -# +# CONFIG_INTEL_PCH_THERMAL is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -2294,6 +2372,7 @@ CONFIG_MFD_CORE=y # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_DA9052_I2C is not set # CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set @@ -2302,7 +2381,8 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set # CONFIG_LPC_ICH is not set CONFIG_LPC_SCH=y -# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_MFD_INTEL_LPSS_ACPI is not set +# CONFIG_MFD_INTEL_LPSS_PCI is not set # CONFIG_MFD_JANZ_CMODIO is not set # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set @@ -2527,17 +2607,18 @@ CONFIG_MEDIA_PCI_SUPPORT=y # # Media capture support # +# CONFIG_VIDEO_SOLO6X10 is not set +# CONFIG_VIDEO_TW68 is not set +# CONFIG_VIDEO_ZORAN is not set # # Media capture/analog TV support # # CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_ZORAN is not set # CONFIG_VIDEO_HEXIUM_GEMINI is not set # CONFIG_VIDEO_HEXIUM_ORION is not set # CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_SOLO6X10 is not set -# CONFIG_VIDEO_TW68 is not set +# CONFIG_VIDEO_DT3155 is not set # # Media capture/analog/hybrid TV support @@ -2586,6 +2667,7 @@ CONFIG_DVB_SMIPCIE=m # CONFIG_V4L_PLATFORM_DRIVERS is not set # CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set # # Supported MMC/SDIO adapters @@ -2608,10 +2690,6 @@ CONFIG_CYPRESS_FIRMWARE=m CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_VIDEO_SAA7146=m CONFIG_VIDEO_SAA7146_VV=m -CONFIG_SAA716X_SUPPORT=y -CONFIG_SAA716X_CORE=m -CONFIG_DVB_SAA716X_BUDGET=m -CONFIG_DVB_SAA716X_HYBRID=m CONFIG_SMS_SIANO_MDTV=m CONFIG_SMS_SIANO_RC=y # CONFIG_SMS_SIANO_DEBUGFS is not set @@ -2709,7 +2787,6 @@ CONFIG_MEDIA_TUNER_R820T=m # # Multistandard (satellite) frontends # -CONFIG_DVB_CX24120=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m @@ -2722,9 +2799,6 @@ CONFIG_DVB_M88DS3103=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_SI2165=m -CONFIG_DVB_STV0367DD=m -CONFIG_DVB_TDA18212DD=m -CONFIG_DVB_CXD2843=m # # DVB-S (satellite) frontends @@ -2749,6 +2823,7 @@ CONFIG_DVB_TDA826X=m CONFIG_DVB_TUA6100=m CONFIG_DVB_CX24116=m CONFIG_DVB_CX24117=m +CONFIG_DVB_CX24120=m CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m CONFIG_DVB_DS3000=m @@ -2846,15 +2921,63 @@ CONFIG_DVB_AF9033=m # # Graphics support # -# CONFIG_AGP is not set +CONFIG_AGP=y +# CONFIG_AGP_AMD64 is not set +CONFIG_AGP_INTEL=y +# CONFIG_AGP_SIS is not set +CONFIG_AGP_VIA=y +CONFIG_INTEL_GTT=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=16 -# CONFIG_VGA_SWITCHEROO is not set +CONFIG_VGA_SWITCHEROO=y +CONFIG_DRM=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_TTM=y # -# Direct Rendering Manager +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=y +# CONFIG_DRM_RADEON_USERPTR is not set +# CONFIG_DRM_RADEON_UMS is not set +# CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_I810 is not set +CONFIG_DRM_I915=y +# CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT is not set +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VMWGFX is not set +# CONFIG_DRM_GMA500 is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_QXL is not set +# CONFIG_DRM_BOCHS is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +CONFIG_DRM_BRIDGE=y + +# +# Display Interface Bridges # -# CONFIG_DRM is not set # # Frame buffer Devices @@ -2868,11 +2991,11 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_SYS_FOPS=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -2924,11 +3047,13 @@ CONFIG_FB_EFI=y # CONFIG_FB_BROADSHEET is not set # CONFIG_FB_AUO_K190X is not set # CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SM712 is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_PM8941_WLED is not set # CONFIG_BACKLIGHT_SAHARA is not set # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set @@ -2936,6 +3061,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_VGASTATE is not set +CONFIG_HDMI=y # # Console display driver support @@ -2965,11 +3091,11 @@ CONFIG_SND_HRTIMER=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_MAX_CARDS=32 # CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y -CONFIG_SND_KCTL_JACK=y CONFIG_SND_DMA_SGBUF=y # CONFIG_SND_RAWMIDI_SEQ is not set # CONFIG_SND_OPL3_LIB_SEQ is not set @@ -3052,13 +3178,10 @@ CONFIG_SND_VIRTUOSO=m # CONFIG_SND_HDA=m CONFIG_SND_HDA_INTEL=m -CONFIG_SND_HDA_DSP_LOADER=y -CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_HDA_HWDEP=y CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=1 -CONFIG_SND_HDA_INPUT_JACK=y CONFIG_SND_HDA_PATCH_LOADER=y CONFIG_SND_HDA_CODEC_REALTEK=m CONFIG_SND_HDA_CODEC_ANALOG=m @@ -3075,6 +3198,9 @@ CONFIG_SND_HDA_CODEC_SI3054=m CONFIG_SND_HDA_GENERIC=m CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 CONFIG_SND_HDA_CORE=m +CONFIG_SND_HDA_DSP_LOADER=y +CONFIG_SND_HDA_I915=y +CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m @@ -3130,6 +3256,7 @@ CONFIG_DRAGONRISE_FF=y # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_GEMBIRD is not set # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set @@ -3214,6 +3341,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set # CONFIG_USB_MON is not set # CONFIG_USB_WUSB_CBAF is not set @@ -3223,6 +3351,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_C67X00_HCD is not set CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y +# CONFIG_USB_XHCI_PLATFORM is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y @@ -3411,6 +3540,7 @@ CONFIG_MMC_SDHCI_ACPI=y CONFIG_MMC_REALTEK_PCI=m CONFIG_MMC_REALTEK_USB=m CONFIG_MMC_TOSHIBA_PCI=m +# CONFIG_MMC_MTK is not set CONFIG_MEMSTICK=m # CONFIG_MEMSTICK_DEBUG is not set @@ -3451,13 +3581,13 @@ CONFIG_LEDS_CLASS_FLASH=y # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_INTEL_SS4200 is not set # CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set # CONFIG_LEDS_LM355x is not set # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set -# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -3477,12 +3607,15 @@ CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_CAMERA is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y # CONFIG_EDAC is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_SYSTOHC=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" # CONFIG_RTC_DEBUG is not set # @@ -3549,7 +3682,6 @@ CONFIG_RTC_DRV_CMOS=y # # on-CPU RTC drivers # -# CONFIG_RTC_DRV_XGENE is not set # # HID Sensor RTC drivers @@ -3565,6 +3697,7 @@ CONFIG_UIO=y # CONFIG_UIO_SERCOS3 is not set # CONFIG_UIO_PCI_GENERIC is not set # CONFIG_UIO_NETX is not set +# CONFIG_UIO_PRUSS is not set # CONFIG_UIO_MF624 is not set # CONFIG_VIRT_DRIVERS is not set @@ -3588,7 +3721,6 @@ CONFIG_R8712U=m CONFIG_RTS5208=y # CONFIG_VT6655 is not set CONFIG_VT6656=m -# CONFIG_FB_SM7XX is not set # CONFIG_FB_SM750 is not set # CONFIG_FB_XGI is not set # CONFIG_FT1000 is not set @@ -3600,7 +3732,6 @@ CONFIG_VT6656=m # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set CONFIG_STAGING_MEDIA=y CONFIG_DVB_CXD2099=m -# CONFIG_VIDEO_DT3155 is not set CONFIG_DVB_MN88472=m CONFIG_DVB_MN88473=m CONFIG_LIRC_STAGING=y @@ -3616,7 +3747,6 @@ CONFIG_LIRC_XBOX=m # # Android # -# CONFIG_USB_WPAN_HCD is not set # CONFIG_WIMAX_GDM72XX is not set # CONFIG_LTE_GDM724X is not set # CONFIG_FIREWIRE_SERIAL is not set @@ -3626,7 +3756,7 @@ CONFIG_LIRC_XBOX=m # CONFIG_GS_FPGABOOT is not set # CONFIG_CRYPTO_SKEIN is not set # CONFIG_UNISYSSPAR is not set -# CONFIG_I2O is not set +# CONFIG_MOST is not set # CONFIG_X86_PLATFORM_DEVICES is not set # CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y @@ -3669,6 +3799,7 @@ CONFIG_CLKBLD_I8253=y # # SOC (System On Chip) specific Drivers # +# CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set # CONFIG_EXTCON is not set @@ -3685,10 +3816,16 @@ CONFIG_CLKBLD_I8253=y # PHY Subsystem # # CONFIG_GENERIC_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_BCM_KONA_USB2_PHY is not set CONFIG_POWERCAP=y CONFIG_INTEL_RAPL=m # CONFIG_MCB is not set + +# +# Performance monitor support +# CONFIG_RAS=y CONFIG_THUNDERBOLT=m @@ -3696,6 +3833,8 @@ CONFIG_THUNDERBOLT=m # Android # # CONFIG_ANDROID is not set +# CONFIG_LIBNVDIMM is not set +# CONFIG_NVMEM is not set # # Firmware Drivers @@ -3715,6 +3854,7 @@ CONFIG_ISCSI_IBFT=y # EFI (Extensible Firmware Interface) Support # CONFIG_EFI_VARS=y +CONFIG_EFI_ESRT=y CONFIG_EFI_RUNTIME_WRAPPERS=y # @@ -3724,9 +3864,9 @@ CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y # CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y @@ -3772,7 +3912,7 @@ CONFIG_FANOTIFY=y CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=m # CONFIG_CUSE is not set -# CONFIG_OVERLAY_FS is not set +CONFIG_OVERLAY_FS=m # # Caches @@ -3805,6 +3945,7 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -3996,7 +4137,6 @@ CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_ARCH_KMEMCHECK=y CONFIG_HAVE_ARCH_KASAN=y # CONFIG_KASAN is not set -CONFIG_KASAN_SHADOW_OFFSET=0xdffffc0000000000 # CONFIG_DEBUG_SHIRQ is not set # @@ -4016,6 +4156,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHED_INFO is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set @@ -4051,8 +4192,8 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_CPU_STALL_INFO is not set # CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set @@ -4094,6 +4235,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set # CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -4122,8 +4264,11 @@ CONFIG_DEFAULT_IO_DELAY_TYPE=0 # CONFIG_DEBUG_BOOT_PARAMS is not set # CONFIG_CPA_DEBUG is not set CONFIG_OPTIMIZE_INLINING=y +# CONFIG_DEBUG_ENTRY is not set # CONFIG_DEBUG_NMI_SELFTEST is not set # CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set +CONFIG_X86_DEBUG_FPU=y +# CONFIG_PUNIT_ATOM_DEBUG is not set # # Security options @@ -4153,13 +4298,17 @@ CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +# CONFIG_CRYPTO_RSA is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_NULL2=y # CONFIG_CRYPTO_PCRYPT is not set CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set @@ -4172,7 +4321,9 @@ CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m # # Block modes @@ -4202,6 +4353,8 @@ CONFIG_CRYPTO_CRC32C=y # CONFIG_CRYPTO_CRC32_PCLMUL is not set # CONFIG_CRYPTO_CRCT10DIF is not set CONFIG_CRYPTO_GHASH=m +# CONFIG_CRYPTO_POLY1305 is not set +# CONFIG_CRYPTO_POLY1305_X86_64 is not set CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m @@ -4244,6 +4397,8 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set # CONFIG_CRYPTO_SALSA20_X86_64 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_CHACHA20_X86_64 is not set # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set @@ -4261,6 +4416,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set @@ -4268,12 +4424,23 @@ CONFIG_CRYPTO_DES=y # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_DRBG_MENU is not set +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m # CONFIG_CRYPTO_USER_API_HASH is not set # CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set # CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set CONFIG_HAVE_KVM=y CONFIG_KVM_COMPAT=y # CONFIG_VIRTUALIZATION is not set @@ -4325,6 +4492,7 @@ CONFIG_XZ_DEC=y # CONFIG_XZ_DEC_BCJ is not set # CONFIG_XZ_DEC_TEST is not set CONFIG_DECOMPRESS_GZIP=y +CONFIG_INTERVAL_TREE=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y @@ -4336,7 +4504,6 @@ CONFIG_GLOB=y # CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_AVERAGE=y # CONFIG_CORDIC is not set # CONFIG_DDR is not set CONFIG_OID_REGISTRY=y @@ -4345,4 +4512,7 @@ CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_ARCH_HAS_MMIO_FLUSH=y diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index 3f1487f701..9b22db98ca 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.1.8 Kernel Configuration +# Linux/arm 4.3.0 Kernel Configuration # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -10,6 +10,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_NEED_DMA_MAP_STATE=y @@ -93,11 +94,11 @@ CONFIG_TICK_CPU_ACCOUNTING=y # RCU Subsystem # CONFIG_TINY_RCU=y +# CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y # CONFIG_TASKS_RCU is not set # CONFIG_RCU_STALL_COMMON is not set # CONFIG_TREE_RCU_TRACE is not set -CONFIG_RCU_KTHREAD_PRIO=0 # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m @@ -107,6 +108,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set # CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_PIDS is not set # CONFIG_CGROUP_DEVICE is not set # CONFIG_CPUSETS is not set # CONFIG_CGROUP_CPUACCT is not set @@ -154,6 +156,8 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y # CONFIG_AIO is not set CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_MEMBARRIER=y CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y @@ -168,11 +172,12 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_DATA_VERIFICATION is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set # CONFIG_UPROBES is not set # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -201,6 +206,7 @@ CONFIG_CC_STACKPROTECTOR_NONE=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_MODULES_USE_ELF_REL=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_CLONE_BACKWARDS=y @@ -346,6 +352,7 @@ CONFIG_KUSER_HELPERS=y CONFIG_ARM_L1_CACHE_SHIFT=5 CONFIG_ARM_DMA_MEM_BUFFERABLE=y # CONFIG_ARM_KERNMEM_PERMS is not set +CONFIG_MULTI_IRQ_HANDLER=y CONFIG_ARM_ERRATA_326103=y CONFIG_ARM_ERRATA_411920=y CONFIG_ARM_ERRATA_364296=y @@ -383,7 +390,9 @@ CONFIG_AEABI=y # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set CONFIG_HAVE_ARCH_PFN_VALID=y # CONFIG_HIGHMEM is not set +# CONFIG_CPU_SW_DOMAIN_PAN is not set CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_MEMBLOCK=y @@ -409,6 +418,8 @@ CONFIG_CMA_AREAS=7 # CONFIG_ZPOOL is not set # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_ALIGNMENT_TRAP=y CONFIG_UACCESS_WITH_MEMCPY=y @@ -533,7 +544,6 @@ CONFIG_IP_MROUTE=y # CONFIG_NET_UDP_TUNNEL is not set # CONFIG_NET_FOU is not set # CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_GENEVE is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set @@ -555,6 +565,7 @@ CONFIG_IPV6=y # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set # CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set @@ -579,6 +590,7 @@ CONFIG_NETFILTER_ADVANCED=y # # Core Netfilter Configuration # +# CONFIG_NETFILTER_INGRESS is not set CONFIG_NETFILTER_NETLINK=m # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set @@ -695,6 +707,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m # CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_DUP_IPV4 is not set # CONFIG_NF_LOG_ARP is not set # CONFIG_NF_LOG_IPV4 is not set CONFIG_NF_REJECT_IPV4=m @@ -722,6 +735,7 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m # CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_NF_DUP_IPV6 is not set CONFIG_NF_REJECT_IPV6=m # CONFIG_NF_LOG_IPV6 is not set CONFIG_NF_NAT_IPV6=m @@ -798,6 +812,7 @@ CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y # CONFIG_BT_BNEP is not set CONFIG_BT_HIDP=m +CONFIG_BT_HS=y CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set # CONFIG_BT_DEBUGFS is not set @@ -807,8 +822,10 @@ CONFIG_BT_LE=y # CONFIG_BT_INTEL=m CONFIG_BT_BCM=m +CONFIG_BT_RTL=m CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set CONFIG_BT_HCIBCM203X=m @@ -845,12 +862,14 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set CONFIG_HAVE_BPF_JIT=y # @@ -904,10 +923,6 @@ CONFIG_CMA_ALIGNMENT=8 # CONFIG_MTD is not set CONFIG_DTC=y CONFIG_OF=y - -# -# Device Tree and Open Firmware support -# # CONFIG_OF_UNITTEST is not set CONFIG_OF_FLATTREE=y CONFIG_OF_EARLY_FLATTREE=y @@ -930,7 +945,6 @@ CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MG_DISK is not set @@ -989,6 +1003,10 @@ CONFIG_BCM2708_VCHIQ=y # Intel MIC Bus Driver # +# +# SCIF Bus Driver +# + # # Intel MIC Host Driver # @@ -996,8 +1014,14 @@ CONFIG_BCM2708_VCHIQ=y # # Intel MIC Card Driver # + +# +# SCIF Driver +# # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set # # SCSI device support @@ -1057,6 +1081,7 @@ CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y CONFIG_TUN=y +# CONFIG_TUN_VNET_CROSS_LE is not set # CONFIG_VETH is not set # CONFIG_NLMON is not set @@ -1075,6 +1100,7 @@ CONFIG_PHYLIB=y # # MII PHY device drivers # +# CONFIG_AQUANTIA_PHY is not set # CONFIG_AT803X_PHY is not set # CONFIG_AMD_PHY is not set # CONFIG_MARVELL_PHY is not set @@ -1083,6 +1109,7 @@ CONFIG_PHYLIB=y # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_BCM7XXX_PHY is not set @@ -1093,6 +1120,9 @@ CONFIG_PHYLIB=y # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set # CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set # CONFIG_MDIO_BUS_MUX_GPIO is not set @@ -1116,6 +1146,7 @@ CONFIG_USB_NET_DRIVERS=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set CONFIG_USB_RTL8152=m +# CONFIG_USB_LAN78XX is not set CONFIG_USB_USBNET=y CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_AX88179_178A=m @@ -1143,6 +1174,7 @@ CONFIG_USB_NET_RNDIS_HOST=m # CONFIG_USB_IPHETH is not set # CONFIG_USB_SIERRA_NET is not set # CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set CONFIG_WLAN=y # CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_AT76C50X_USB is not set @@ -1246,6 +1278,7 @@ CONFIG_ZD1211RW=m # Input device support # CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_SPARSEKMAP is not set @@ -1295,7 +1328,7 @@ CONFIG_JOYSTICK_XPAD_LEDS=y # CONFIG_JOYSTICK_RPISENSE is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_OF_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_TOUCHSCREEN_ADS7846=m # CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879 is not set @@ -1323,6 +1356,7 @@ CONFIG_TOUCHSCREEN_EGALAX=m # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set @@ -1331,6 +1365,7 @@ CONFIG_TOUCHSCREEN_RPI_FT5406=m # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set # CONFIG_TOUCHSCREEN_WM97XX is not set CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_TOUCHSCREEN_USB_EGALAX=y @@ -1383,6 +1418,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set # @@ -1394,6 +1430,13 @@ CONFIG_INPUT_UINPUT=y # # Character devices # +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM_VC_CMA=y +CONFIG_BCM2708_VCMEM=y +CONFIG_BCM_VCIO=y +CONFIG_BCM_VC_SM=y +CONFIG_BCM2835_DEVGPIOMEM=m +CONFIG_BCM2835_SMI_DEV=m CONFIG_TTY=y CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y @@ -1424,6 +1467,7 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_SCCNXP is not set @@ -1437,6 +1481,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_FSL_LPUART is not set # CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set # CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_STM32 is not set # CONFIG_TTY_PRINTK is not set # CONFIG_HVC_DCC is not set # CONFIG_IPMI_HANDLER is not set @@ -1447,13 +1492,6 @@ CONFIG_HW_RANDOM_BCM2708=m # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BCM_VC_CMA=y -CONFIG_BCM2708_VCMEM=y -CONFIG_BCM_VCIO=y -CONFIG_BCM_VC_SM=y -CONFIG_BCM2835_DEVGPIOMEM=m -CONFIG_BCM2835_SMI_DEV=m # CONFIG_XILLYBUS is not set # @@ -1473,6 +1511,7 @@ CONFIG_I2C_MUX=m # CONFIG_I2C_MUX_PCA9541 is not set # CONFIG_I2C_MUX_PCA954x is not set # CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=y @@ -1488,6 +1527,7 @@ CONFIG_I2C_BCM2708_BAUDRATE=100000 # CONFIG_I2C_BCM2835 is not set # CONFIG_I2C_CBUS_GPIO is not set # CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_EMEV2 is not set CONFIG_I2C_GPIO=y # CONFIG_I2C_NOMADIK is not set # CONFIG_I2C_OCORES is not set @@ -1535,6 +1575,7 @@ CONFIG_SPI_BCM2708=m # CONFIG_SPI_SC18IS602 is not set # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set # CONFIG_SPI_DESIGNWARE is not set # @@ -1617,6 +1658,7 @@ CONFIG_GPIO_ARIZONA=m # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_ZX is not set # # USB GPIO expanders @@ -1663,9 +1705,12 @@ CONFIG_POWER_SUPPLY=y # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_BQ2415X is not set # CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set # CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set # CONFIG_POWER_RESET is not set # CONFIG_POWER_AVS is not set CONFIG_HWMON=y @@ -1772,6 +1817,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set # CONFIG_SENSORS_TMP103 is not set @@ -1790,20 +1836,19 @@ CONFIG_HWMON=y CONFIG_THERMAL=y CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_GOV_FAIR_SHARE is not set CONFIG_THERMAL_GOV_STEP_WISE=y # CONFIG_THERMAL_GOV_BANG_BANG is not set # CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set # CONFIG_CPU_THERMAL is not set # CONFIG_THERMAL_EMULATION is not set CONFIG_THERMAL_BCM2835=y - -# -# Texas Instruments thermal drivers -# CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -1868,6 +1913,7 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_DA9052_I2C is not set # CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set @@ -1942,6 +1988,7 @@ CONFIG_MFD_ARIZONA_SPI=m CONFIG_MFD_WM5102=y # CONFIG_MFD_WM5110 is not set # CONFIG_MFD_WM8997 is not set +# CONFIG_MFD_WM8998 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X_I2C is not set # CONFIG_MFD_WM831X_SPI is not set @@ -2107,6 +2154,7 @@ CONFIG_VIDEO_EM28XX_RC=m # CONFIG_V4L_PLATFORM_DRIVERS is not set # CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set # # Supported MMC/SDIO adapters @@ -2216,7 +2264,6 @@ CONFIG_MEDIA_TUNER_R820T=m # # Multistandard (satellite) frontends # -CONFIG_DVB_CX24120=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m @@ -2247,6 +2294,7 @@ CONFIG_DVB_TUNER_ITD1000=m CONFIG_DVB_TUNER_CX24113=m CONFIG_DVB_TDA826X=m CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m CONFIG_DVB_DS3000=m @@ -2334,10 +2382,6 @@ CONFIG_DVB_AF9033=m # # Graphics support # - -# -# Direct Rendering Manager -# # CONFIG_DRM is not set # @@ -2407,6 +2451,7 @@ CONFIG_SND_HRTIMER=m CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_MAX_CARDS=32 # CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -2422,6 +2467,7 @@ CONFIG_SND_AC97_CODEC=m # # HD-Audio # +CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_ARM=y # CONFIG_SND_ARMAACI is not set CONFIG_SND_BCM2835=m @@ -2442,6 +2488,7 @@ CONFIG_SND_USB_VARIAX=m CONFIG_SND_SOC=m CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m @@ -2466,13 +2513,13 @@ CONFIG_SND_BCM2708_SOC_RASPIDAC3=m # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set -# CONFIG_SND_SOC_QCOM is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # +# CONFIG_SND_SOC_AC97_CODEC is not set # CONFIG_SND_SOC_ADAU1701 is not set # CONFIG_SND_SOC_AK4104 is not set # CONFIG_SND_SOC_AK4554 is not set @@ -2489,8 +2536,10 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_CS4271_I2C is not set # CONFIG_SND_SOC_CS4271_SPI is not set # CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_HDMI_CODEC is not set # CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_GTM601 is not set # CONFIG_SND_SOC_PCM1681 is not set # CONFIG_SND_SOC_PCM1792A is not set CONFIG_SND_SOC_PCM512x=m @@ -2508,8 +2557,10 @@ CONFIG_SND_SOC_PCM5102A=m # CONFIG_SND_SOC_SSM4567 is not set CONFIG_SND_SOC_STA32X=m # CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set # CONFIG_SND_SOC_TAS2552 is not set # CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set # CONFIG_SND_SOC_TFA9879 is not set CONFIG_SND_SOC_TAS5713=m # CONFIG_SND_SOC_TLV320AIC23_I2C is not set @@ -2570,6 +2621,7 @@ CONFIG_DRAGONRISE_FF=y # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_GEMBIRD is not set # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set @@ -2653,6 +2705,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set CONFIG_USB_MON=m # CONFIG_USB_WUSB_CBAF is not set @@ -2838,6 +2891,7 @@ CONFIG_MMC_BCM2835_SDHOST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set # CONFIG_MMC_SDHCI_F_SDH30 is not set # CONFIG_MMC_SPI is not set # CONFIG_MMC_DW is not set @@ -2845,6 +2899,7 @@ CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set CONFIG_MMC_REALTEK_USB=m +# CONFIG_MMC_MTK is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -2853,6 +2908,9 @@ CONFIG_LEDS_CLASS_FLASH=y # # LED drivers # +# CONFIG_LEDS_AAT1290 is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set # CONFIG_LEDS_LM3530 is not set # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_PCA9532 is not set @@ -2869,13 +2927,14 @@ CONFIG_LEDS_GPIO=y # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set # CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set # CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_KTD2692 is not set # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set -# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -2896,12 +2955,14 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_LEDS_TRIGGER_CAMERA is not set CONFIG_LEDS_TRIGGER_INPUT=y # CONFIG_ACCESSIBILITY is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y # CONFIG_EDAC is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set CONFIG_RTC_SYSTOHC=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" # CONFIG_RTC_DEBUG is not set # @@ -2978,6 +3039,7 @@ CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set # # on-CPU RTC drivers @@ -2985,7 +3047,6 @@ CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_PL030 is not set # CONFIG_RTC_DRV_PL031 is not set # CONFIG_RTC_DRV_SNVS is not set -# CONFIG_RTC_DRV_XGENE is not set # # HID Sensor RTC drivers @@ -2997,16 +3058,17 @@ CONFIG_DMADEVICES=y # # DMA Devices # -# CONFIG_AMBA_PL08X is not set -# CONFIG_DW_DMAC is not set -# CONFIG_PL330_DMA is not set -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2708_LEGACY=y -# CONFIG_FSL_EDMA is not set -# CONFIG_NBPFAXI_DMA is not set CONFIG_DMA_ENGINE=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +# CONFIG_PL330_DMA is not set +CONFIG_DMA_BCM2708=y +CONFIG_DMA_BCM2708_LEGACY=y +# CONFIG_DW_DMAC is not set # # DMA Clients @@ -3054,7 +3116,7 @@ CONFIG_LIRC_XBOX=m # # Android # -# CONFIG_USB_WPAN_HCD is not set +# CONFIG_STAGING_BOARD is not set # CONFIG_WIMAX_GDM72XX is not set # CONFIG_LTE_GDM724X is not set # CONFIG_LUSTRE_FS is not set @@ -3062,6 +3124,7 @@ CONFIG_LIRC_XBOX=m # CONFIG_GS_FPGABOOT is not set # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set # CONFIG_FB_TFT is not set +# CONFIG_MOST is not set # CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y @@ -3072,6 +3135,7 @@ CONFIG_COMMON_CLK=y # # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_CLK_QORIQ is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set @@ -3083,6 +3147,9 @@ CONFIG_COMMON_CLK=y # # Clock Source drivers # +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_MMIO=y +# CONFIG_ARM_TIMER_SP804 is not set # CONFIG_ATMEL_PIT is not set # CONFIG_SH_TIMER_CMT is not set # CONFIG_SH_TIMER_MTU2 is not set @@ -3107,6 +3174,7 @@ CONFIG_BCM2835_MBOX=y # # SOC (System On Chip) specific Drivers # +# CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set CONFIG_EXTCON=m @@ -3131,14 +3199,22 @@ CONFIG_IRQCHIP=y # PHY Subsystem # # CONFIG_GENERIC_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_POWERCAP is not set # CONFIG_MCB is not set +# +# Performance monitor support +# +# CONFIG_RAS is not set + # # Android # # CONFIG_ANDROID is not set +# CONFIG_NVMEM is not set # # Firmware Drivers @@ -3153,7 +3229,7 @@ CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set # CONFIG_EXT4_ENCRYPTION is not set @@ -3232,6 +3308,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -3425,6 +3502,7 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHED_INFO is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set @@ -3460,6 +3538,7 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set @@ -3494,6 +3573,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set # CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -3538,13 +3618,17 @@ CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +# CONFIG_CRYPTO_RSA is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_MCRYPTD is not set @@ -3556,7 +3640,9 @@ CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m # # Block modes @@ -3584,6 +3670,7 @@ CONFIG_CRYPTO_CRC32C=y # CONFIG_CRYPTO_CRC32 is not set # CONFIG_CRYPTO_CRCT10DIF is not set CONFIG_CRYPTO_GHASH=m +# CONFIG_CRYPTO_POLY1305 is not set CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -3611,6 +3698,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_TEA is not set @@ -3622,6 +3710,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set @@ -3629,15 +3718,27 @@ CONFIG_CRYPTO_LZO=m # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_DRBG_MENU is not set +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m # CONFIG_CRYPTO_USER_API_HASH is not set # CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set # CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set CONFIG_ARM_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM=m CONFIG_CRYPTO_SHA256_ARM=m +# CONFIG_CRYPTO_SHA512_ARM is not set CONFIG_CRYPTO_AES_ARM=m # CONFIG_BINARY_PRINTF is not set @@ -3692,7 +3793,6 @@ CONFIG_DQL=y CONFIG_NLATTR=y CONFIG_GENERIC_ATOMIC64=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_AVERAGE=y # CONFIG_CORDIC is not set # CONFIG_DDR is not set CONFIG_LIBFDT=y @@ -3701,5 +3801,6 @@ CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set # CONFIG_ARCH_HAS_SG_CHAIN is not set # CONFIG_VIRTUALIZATION is not set diff --git a/projects/RPi/patches/linux/linux-01-RPi_support.patch b/projects/RPi/patches/linux/linux-01-RPi_support.patch index 32cf12da6a..af2d4b60b2 100644 --- a/projects/RPi/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,724 @@ -From 5e9c268f96c85ea7722958b1f6f73c8d13a822dc Mon Sep 17 00:00:00 2001 +From 1ac297ca77f1fbe846e51e484f1c3ba490154fe4 Mon Sep 17 00:00:00 2001 +From: Steve Glendinning +Date: Thu, 19 Feb 2015 18:47:12 +0000 +Subject: [PATCH 001/113] smsx95xx: fix crimes against truesize + +smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. + +This patch stops smsc95xx from changing truesize. + +Signed-off-by: Steve Glendinning +--- + drivers/net/usb/smsc95xx.c | 2 -- + 1 file changed, 2 deletions(-) + mode change 100644 => 100755 drivers/net/usb/smsc95xx.c + +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +old mode 100644 +new mode 100755 +index 26423ad..fbc72ec6 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -1785,7 +1785,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + if (dev->net->features & NETIF_F_RXCSUM) + smsc95xx_rx_csum_offload(skb); + skb_trim(skb, skb->len - 4); /* remove fcs */ +- skb->truesize = size + sizeof(struct sk_buff); + + return 1; + } +@@ -1803,7 +1802,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + if (dev->net->features & NETIF_F_RXCSUM) + smsc95xx_rx_csum_offload(ax_skb); + skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ +- ax_skb->truesize = size + sizeof(struct sk_buff); + + usbnet_skb_return(dev, ax_skb); + } + +From 977a6619f5303a58bd4e2b34229638d530ff1d39 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 Apr 2015 16:58:45 +0100 +Subject: [PATCH 002/113] smsc95xx: Disable turbo mode by default + +--- + drivers/net/usb/smsc95xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index fbc72ec6..477b9c7 100755 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -70,7 +70,7 @@ struct smsc95xx_priv { + u8 suspend_flags; + }; + +-static bool turbo_mode = true; ++static bool turbo_mode = false; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + + +From 0d5dbc68901771e0bdd60bb79c8a6c0a101abb95 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 18 Jun 2014 13:42:01 +0100 +Subject: [PATCH 003/113] vmstat: Workaround for issue where dirty page count + goes negative + +See: +https://github.com/raspberrypi/linux/issues/617 +http://www.spinics.net/lists/linux-mm/msg72236.html +--- + include/linux/vmstat.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h +index 82e7db7..f87d16d 100644 +--- a/include/linux/vmstat.h ++++ b/include/linux/vmstat.h +@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + { + atomic_long_dec(&zone->vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) ++ atomic_long_set(&zone->vm_stat[item], 0); + atomic_long_dec(&vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) ++ atomic_long_set(&vm_stat[item], 0); + } + + static inline void __inc_zone_page_state(struct page *page, + +From 15c41e58ff73c75b44d6f916e87f5586a5ab4f19 Mon Sep 17 00:00:00 2001 +From: Robert Tiemann +Date: Mon, 20 Jul 2015 11:01:25 +0200 +Subject: [PATCH 004/113] BCM2835_DT: Fix I2S register map + +--- + Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- + Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 4 ++-- + arch/arm/boot/dts/bcm2835.dtsi | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt +index 1396078..2db8294 100644 +--- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt ++++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt +@@ -48,8 +48,8 @@ Example: + + bcm2835_i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; +- reg = < 0x7e203000 0x20>, +- < 0x7e101098 0x02>; ++ reg = < 0x7e203000 0x24>, ++ < 0x7e101098 0x08>; + + dmas = <&dma 2>, + <&dma 3>; +diff --git a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt +index 65783de..a89fe42 100644 +--- a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt ++++ b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt +@@ -16,8 +16,8 @@ Example: + + bcm2835_i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x20>, +- <0x7e101098 0x02>; ++ reg = <0x7e203000 0x24>, ++ <0x7e101098 0x08>; + + dmas = <&dma 2>, + <&dma 3>; +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index 301c73f..440717c 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -102,8 +102,8 @@ + + i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x20>, +- <0x7e101098 0x02>; ++ reg = <0x7e203000 0x24>, ++ <0x7e101098 0x08>; + + dmas = <&dma 2>, + <&dma 3>; + +From 1123fea13563a412b29a0e71e173130307c84b16 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 4 Jun 2015 13:11:46 -0700 +Subject: [PATCH 005/113] ARM: bcm2835: Add the Raspberry Pi firmware driver + +This gives us a function for making mailbox property channel requests +of the firmware, which is most notable in that it will let us get and +set clock rates. + +Signed-off-by: Eric Anholt +--- + drivers/firmware/Kconfig | 7 + + drivers/firmware/Makefile | 1 + + drivers/firmware/raspberrypi.c | 260 +++++++++++++++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 115 +++++++++++++ + 4 files changed, 383 insertions(+) + create mode 100644 drivers/firmware/raspberrypi.c + create mode 100644 include/soc/bcm2835/raspberrypi-firmware.h + +diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig +index 665efca..7181126 100644 +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -147,6 +147,13 @@ config QCOM_SCM_64 + def_bool y + depends on QCOM_SCM && ARM64 + ++config RASPBERRYPI_FIRMWARE ++ tristate "Raspberry Pi Firmware Driver" ++ depends on BCM2835_MBOX ++ help ++ This option enables support for communicating with the firmware on the ++ Raspberry Pi. ++ + source "drivers/firmware/broadcom/Kconfig" + source "drivers/firmware/google/Kconfig" + source "drivers/firmware/efi/Kconfig" +diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile +index 2ee8347..8f9049d 100644 +--- a/drivers/firmware/Makefile ++++ b/drivers/firmware/Makefile +@@ -16,6 +16,7 @@ obj-$(CONFIG_QCOM_SCM) += qcom_scm.o + obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o + obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o + CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) ++obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o + + obj-y += broadcom/ + obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ +diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c +new file mode 100644 +index 0000000..dd506cd3 +--- /dev/null ++++ b/drivers/firmware/raspberrypi.c +@@ -0,0 +1,260 @@ ++/* ++ * Defines interfaces for interacting wtih the Raspberry Pi firmware's ++ * property channel. ++ * ++ * Copyright © 2015 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) ++#define MBOX_CHAN(msg) ((msg) & 0xf) ++#define MBOX_DATA28(msg) ((msg) & ~0xf) ++#define MBOX_CHAN_PROPERTY 8 ++ ++struct rpi_firmware { ++ struct mbox_client cl; ++ struct mbox_chan *chan; /* The property channel. */ ++ struct completion c; ++ u32 enabled; ++}; ++ ++static DEFINE_MUTEX(transaction_lock); ++ ++static void response_callback(struct mbox_client *cl, void *msg) ++{ ++ struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); ++ complete(&fw->c); ++} ++ ++/* ++ * Sends a request to the firmware through the BCM2835 mailbox driver, ++ * and synchronously waits for the reply. ++ */ ++static int ++rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) ++{ ++ u32 message = MBOX_MSG(chan, data); ++ int ret; ++ ++ WARN_ON(data & 0xf); ++ ++ mutex_lock(&transaction_lock); ++ reinit_completion(&fw->c); ++ ret = mbox_send_message(fw->chan, &message); ++ if (ret >= 0) { ++ wait_for_completion(&fw->c); ++ ret = 0; ++ } else { ++ dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); ++ } ++ mutex_unlock(&transaction_lock); ++ ++ return ret; ++} ++ ++/** ++ * rpi_firmware_property_list - Submit firmware property list ++ * @fw: Pointer to firmware structure from rpi_firmware_get(). ++ * @data: Buffer holding tags. ++ * @tag_size: Size of tags buffer. ++ * ++ * Submits a set of concatenated tags to the VPU firmware through the ++ * mailbox property interface. ++ * ++ * The buffer header and the ending tag are added by this function and ++ * don't need to be supplied, just the actual tags for your operation. ++ * See struct rpi_firmware_property_tag_header for the per-tag ++ * structure. ++ */ ++int rpi_firmware_property_list(struct rpi_firmware *fw, ++ void *data, size_t tag_size) ++{ ++ size_t size = tag_size + 12; ++ u32 *buf; ++ dma_addr_t bus_addr; ++ int ret; ++ ++ /* Packets are processed a dword at a time. */ ++ if (size & 3) ++ return -EINVAL; ++ ++ buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, ++ GFP_ATOMIC); ++ if (!buf) ++ return -ENOMEM; ++ ++ /* The firmware will error out without parsing in this case. */ ++ WARN_ON(size >= 1024 * 1024); ++ ++ buf[0] = size; ++ buf[1] = RPI_FIRMWARE_STATUS_REQUEST; ++ memcpy(&buf[2], data, tag_size); ++ buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END; ++ wmb(); ++ ++ ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr); ++ ++ rmb(); ++ memcpy(data, &buf[2], tag_size); ++ if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) { ++ /* ++ * The tag name here might not be the one causing the ++ * error, if there were multiple tags in the request. ++ * But single-tag is the most common, so go with it. ++ */ ++ dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", ++ buf[2], buf[1]); ++ ret = -EINVAL; ++ } ++ ++ dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(rpi_firmware_property_list); ++ ++/** ++ * rpi_firmware_property - Submit single firmware property ++ * @fw: Pointer to firmware structure from rpi_firmware_get(). ++ * @tag: One of enum_mbox_property_tag. ++ * @tag_data: Tag data buffer. ++ * @buf_size: Buffer size. ++ * ++ * Submits a single tag to the VPU firmware through the mailbox ++ * property interface. ++ * ++ * This is a convenience wrapper around ++ * rpi_firmware_property_list() to avoid some of the ++ * boilerplate in property calls. ++ */ ++int rpi_firmware_property(struct rpi_firmware *fw, ++ u32 tag, void *tag_data, size_t buf_size) ++{ ++ /* Single tags are very small (generally 8 bytes), so the ++ * stack should be safe. ++ */ ++ u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)]; ++ struct rpi_firmware_property_tag_header *header = ++ (struct rpi_firmware_property_tag_header *)data; ++ int ret; ++ ++ header->tag = tag; ++ header->buf_size = buf_size; ++ header->req_resp_size = 0; ++ memcpy(data + sizeof(struct rpi_firmware_property_tag_header), ++ tag_data, buf_size); ++ ++ ret = rpi_firmware_property_list(fw, &data, sizeof(data)); ++ memcpy(tag_data, ++ data + sizeof(struct rpi_firmware_property_tag_header), ++ buf_size); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(rpi_firmware_property); ++ ++static void ++rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) ++{ ++ u32 packet; ++ int ret = rpi_firmware_property(fw, ++ RPI_FIRMWARE_GET_FIRMWARE_REVISION, ++ &packet, sizeof(packet)); ++ ++ if (ret == 0) { ++ struct tm tm; ++ ++ time_to_tm(packet, 0, &tm); ++ ++ dev_info(fw->cl.dev, ++ "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min); ++ } ++} ++ ++static int rpi_firmware_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rpi_firmware *fw; ++ ++ fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); ++ if (!fw) ++ return -ENOMEM; ++ ++ fw->cl.dev = dev; ++ fw->cl.rx_callback = response_callback; ++ fw->cl.tx_block = true; ++ ++ fw->chan = mbox_request_channel(&fw->cl, 0); ++ if (IS_ERR(fw->chan)) { ++ int ret = PTR_ERR(fw->chan); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get mbox channel: %d\n", ret); ++ return ret; ++ } ++ ++ init_completion(&fw->c); ++ ++ platform_set_drvdata(pdev, fw); ++ ++ rpi_firmware_print_firmware_revision(fw); ++ ++ return 0; ++} ++ ++static int rpi_firmware_remove(struct platform_device *pdev) ++{ ++ struct rpi_firmware *fw = platform_get_drvdata(pdev); ++ ++ mbox_free_channel(fw->chan); ++ ++ return 0; ++} ++ ++/** ++ * rpi_firmware_get - Get pointer to rpi_firmware structure. ++ * @firmware_node: Pointer to the firmware Device Tree node. ++ * ++ * Returns NULL is the firmware device is not ready. ++ */ ++struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) ++{ ++ struct platform_device *pdev = of_find_device_by_node(firmware_node); ++ ++ if (!pdev) ++ return NULL; ++ ++ return platform_get_drvdata(pdev); ++} ++EXPORT_SYMBOL_GPL(rpi_firmware_get); ++ ++static const struct of_device_id rpi_firmware_of_match[] = { ++ { .compatible = "raspberrypi,bcm2835-firmware", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rpi_firmware_of_match); ++ ++static struct platform_driver rpi_firmware_driver = { ++ .driver = { ++ .name = "raspberrypi-firmware", ++ .of_match_table = rpi_firmware_of_match, ++ }, ++ .probe = rpi_firmware_probe, ++ .remove = rpi_firmware_remove, ++}; ++module_platform_driver(rpi_firmware_driver); ++ ++MODULE_AUTHOR("Eric Anholt "); ++MODULE_DESCRIPTION("Raspberry Pi firmware driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +new file mode 100644 +index 0000000..9d9efb7 +--- /dev/null ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -0,0 +1,115 @@ ++/* ++ * Copyright © 2015 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++struct rpi_firmware; ++ ++enum rpi_firmware_property_status { ++ RPI_FIRMWARE_STATUS_REQUEST = 0, ++ RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000, ++ RPI_FIRMWARE_STATUS_ERROR = 0x80000001, ++}; ++ ++/** ++ * struct rpi_firmware_property_tag_header - Firmware property tag header ++ * @tag: One of enum_mbox_property_tag. ++ * @buf_size: The number of bytes in the value buffer following this ++ * struct. ++ * @req_resp_size: On submit, the length of the request (though it doesn't ++ * appear to be currently used by the firmware). On return, ++ * the length of the response (always 4 byte aligned), with ++ * the low bit set. ++ */ ++struct rpi_firmware_property_tag_header { ++ u32 tag; ++ u32 buf_size; ++ u32 req_resp_size; ++}; ++ ++enum rpi_firmware_property_tag { ++ RPI_FIRMWARE_PROPERTY_END = 0, ++ RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, ++ ++ RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, ++ RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, ++ ++ RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, ++ RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, ++ RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, ++ RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, ++ RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, ++ RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, ++ RPI_FIRMWARE_GET_CLOCKS = 0x00010007, ++ RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, ++ RPI_FIRMWARE_GET_TIMING = 0x00020002, ++ RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, ++ RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, ++ RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, ++ RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, ++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, ++ RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, ++ RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, ++ RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, ++ RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, ++ RPI_FIRMWARE_GET_TURBO = 0x00030009, ++ RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, ++ RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, ++ RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, ++ RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, ++ RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, ++ RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, ++ RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, ++ RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, ++ RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, ++ RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, ++ RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, ++ RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, ++ RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, ++ RPI_FIRMWARE_SET_TURBO = 0x00038009, ++ ++ /* Dispmanx TAGS */ ++ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, ++ RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, ++ RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, ++ ++ RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, ++ RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, ++}; ++ ++int rpi_firmware_property(struct rpi_firmware *fw, ++ u32 tag, void *data, size_t len); ++int rpi_firmware_property_list(struct rpi_firmware *fw, ++ void *data, size_t tag_size); ++struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); + +From c03abc094d43ff82ec7e9516858003c2544b5b5a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 12 Jun 2015 19:01:05 +0200 +Subject: [PATCH 006/113] irqchip: bcm2835: Add FIQ support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a duplicate irq range with an offset on the hwirq's so the +driver can detect that enable_fiq() is used. +Tested with downstream dwc_otg USB controller driver. + +Signed-off-by: Noralf Trønnes +Reviewed-by: Eric Anholt +Acked-by: Stephen Warren +--- + arch/arm/mach-bcm/Kconfig | 1 + + drivers/irqchip/irq-bcm2835.c | 51 ++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 47 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig +index 1319c3c..edbe6fe 100644 +--- a/arch/arm/mach-bcm/Kconfig ++++ b/arch/arm/mach-bcm/Kconfig +@@ -114,6 +114,7 @@ config ARCH_BCM2835 + select ARM_ERRATA_411920 + select ARM_TIMER_SP804 + select CLKSRC_OF ++ select FIQ + select PINCTRL + select PINCTRL_BCM2835 + help +diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c +index bf9cc5f..3f601f9 100644 +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -55,7 +55,7 @@ + #include + + /* Put the bank and irq (32 bits) into the hwirq */ +-#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) ++#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) + #define HWIRQ_BANK(i) (i >> 5) + #define HWIRQ_BIT(i) BIT(i & 0x1f) + +@@ -71,9 +71,13 @@ + | SHORTCUT1_MASK | SHORTCUT2_MASK) + + #define REG_FIQ_CONTROL 0x0c ++#define REG_FIQ_ENABLE 0x80 ++#define REG_FIQ_DISABLE 0 + + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 ++#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) ++#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) + + static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; + static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; +@@ -98,14 +102,38 @@ static void __exception_irq_entry bcm2835_handle_irq( + struct pt_regs *regs); + static void bcm2836_chained_handle_irq(struct irq_desc *desc); + ++static inline unsigned int hwirq_to_fiq(unsigned long hwirq) ++{ ++ hwirq -= NUMBER_IRQS; ++ /* ++ * The hwirq numbering used in this driver is: ++ * BASE (0-7) GPU1 (32-63) GPU2 (64-95). ++ * This differ from the one used in the FIQ register: ++ * GPU1 (0-31) GPU2 (32-63) BASE (64-71) ++ */ ++ if (hwirq >= 32) ++ return hwirq - 32; ++ ++ return hwirq + 64; ++} ++ + static void armctrl_mask_irq(struct irq_data *d) + { +- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); ++ if (d->hwirq >= NUMBER_IRQS) ++ writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); ++ else ++ writel_relaxed(HWIRQ_BIT(d->hwirq), ++ intc.disable[HWIRQ_BANK(d->hwirq)]); + } + + static void armctrl_unmask_irq(struct irq_data *d) + { +- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); ++ if (d->hwirq >= NUMBER_IRQS) ++ writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), ++ intc.base + REG_FIQ_CONTROL); ++ else ++ writel_relaxed(HWIRQ_BIT(d->hwirq), ++ intc.enable[HWIRQ_BANK(d->hwirq)]); + } + + static struct irq_chip armctrl_chip = { +@@ -151,8 +179,9 @@ static int __init armctrl_of_init(struct device_node *node, + panic("%s: unable to map IC registers\n", + node->full_name); + +- intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), +- &armctrl_ops, NULL); ++ intc.base = base; ++ intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2, ++ &armctrl_ops, NULL); + if (!intc.domain) + panic("%s: unable to create IRQ domain\n", node->full_name); + +@@ -182,6 +211,18 @@ static int __init armctrl_of_init(struct device_node *node, + set_handle_irq(bcm2835_handle_irq); + } + ++ /* Make a duplicate irq range which is used to enable FIQ */ ++ for (b = 0; b < NR_BANKS; b++) { ++ for (i = 0; i < bank_irqs[b]; i++) { ++ irq = irq_create_mapping(intc.domain, ++ MAKE_HWIRQ(b, i) + NUMBER_IRQS); ++ BUG_ON(irq <= 0); ++ irq_set_chip(irq, &armctrl_chip); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ } ++ } ++ init_FIQ(FIQ_START); ++ + return 0; + } + + +From e88007fc84bba1fdc4e11139bcdbd33f0543fa02 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 001/204] Main bcm2708/bcm2709 linux port +Subject: [PATCH 007/113] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -19,7 +736,7 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2708/Makefile.boot | 3 + arch/arm/mach-bcm2708/armctrl.c | 304 +++++++++ arch/arm/mach-bcm2708/armctrl.h | 27 + - arch/arm/mach-bcm2708/bcm2708.c | 622 ++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 607 +++++++++++++++++ arch/arm/mach-bcm2708/bcm2708.h | 49 ++ arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++ arch/arm/mach-bcm2708/include/mach/clkdev.h | 7 + @@ -71,7 +788,7 @@ Signed-off-by: Noralf Trønnes drivers/clocksource/arm_arch_timer.c | 36 + drivers/tty/serial/amba-pl011.c | 2 +- include/linux/mmc/host.h | 1 + - 62 files changed, 6436 insertions(+), 5 deletions(-) + 62 files changed, 6421 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile create mode 100644 arch/arm/mach-bcm2708/Makefile.boot @@ -124,10 +841,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 arch/arm/mach-bcm2709/vc_support.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 19f4cc6..3ec1319 100644 +index 72ad724..afbcf9d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -314,6 +314,42 @@ choice +@@ -315,6 +315,42 @@ choice default ARCH_VERSATILE if !MMU default ARCH_MULTIPLATFORM if MMU @@ -170,7 +887,7 @@ index 19f4cc6..3ec1319 100644 config ARCH_MULTIPLATFORM bool "Allow multiple platforms to be selected" depends on MMU -@@ -824,6 +860,9 @@ config ARCH_VIRT +@@ -827,6 +863,9 @@ config ARCH_VIRT # Kconfigs may be included either alphabetically (according to the # plat- suffix) or along side the corresponding mach-* source. # @@ -181,10 +898,10 @@ index 19f4cc6..3ec1319 100644 source "arch/arm/mach-alpine/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index 0c12ffb..18db6c4 100644 +index 0cfd7f9..87c5451 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug -@@ -1197,6 +1197,14 @@ choice +@@ -1247,6 +1247,14 @@ choice options; the platform specific options are deprecated and will be soon removed. @@ -200,10 +917,10 @@ index 0c12ffb..18db6c4 100644 config DEBUG_AT91_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 47f10e7..afd559d 100644 +index 2c2b28e..a2e7cf7 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -150,6 +150,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +@@ -154,6 +154,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -213,10 +930,10 @@ index 47f10e7..afd559d 100644 machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AXXIA) += axxia diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S -index 3637973..380430a 100644 +index 04286fd..ed82628 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S -@@ -680,6 +680,14 @@ ARM_BE8(rev16 ip, ip) +@@ -700,6 +700,14 @@ ARM_BE8(rev16 ip, ip) ldrcc r7, [r4], #4 @ use branch for delay slot bcc 1b ret lr @@ -232,12 +949,12 @@ index 3637973..380430a 100644 ENDPROC(__fixup_a_pv_table) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index f192a2a..f638dae 100644 +index 7a7c4ce..7dd2e4c 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c -@@ -98,6 +98,16 @@ void arch_cpu_idle_dead(void) +@@ -91,6 +91,16 @@ void arch_cpu_idle_exit(void) + ledtrig_cpu(CPU_LED_IDLE_END); } - #endif +char bcm2708_reboot_mode = 'h'; + @@ -310,7 +1027,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c new file mode 100644 -index 0000000..4868cd37 +index 0000000..95f272b --- /dev/null +++ b/arch/arm/mach-bcm2708/armctrl.c @@ -0,0 +1,304 @@ @@ -611,7 +1328,7 @@ index 0000000..4868cd37 + irq_set_chip(irq, &armctrl_chip); + irq_set_chip_data(irq, (void *)data); + irq_set_handler(irq, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); + } + + armctrl_pm_register(base, irq_start, resume_sources); @@ -653,10 +1370,10 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c new file mode 100644 -index 0000000..a209c58 +index 0000000..d67ee24 --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -0,0 +1,622 @@ +@@ -0,0 +1,607 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708.c + * @@ -1106,24 +1823,9 @@ index 0000000..a209c58 + system_serial_low = serial; +} + -+static void timer_set_mode(enum clock_event_mode mode, -+ struct clock_event_device *clk) ++static int timer_set_oneshot(struct clock_event_device *unused) +{ -+ switch (mode) { -+ case CLOCK_EVT_MODE_ONESHOT: /* Leave the timer disabled, .set_next_event will enable it */ -+ case CLOCK_EVT_MODE_SHUTDOWN: -+ break; -+ case CLOCK_EVT_MODE_PERIODIC: -+ -+ case CLOCK_EVT_MODE_UNUSED: -+ case CLOCK_EVT_MODE_RESUME: -+ -+ default: -+ printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n", -+ (int)mode); -+ break; -+ } -+ ++ return 0; +} + +static int timer_set_next_event(unsigned long cycles, @@ -1144,7 +1846,7 @@ index 0000000..a209c58 + .name = "timer0", + .shift = 32, + .features = CLOCK_EVT_FEAT_ONESHOT, -+ .set_mode = timer_set_mode, ++ .set_state_oneshot = timer_set_oneshot, + .set_next_event = timer_set_next_event, +}; + @@ -2745,7 +3447,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c new file mode 100644 -index 0000000..2fcfab9 +index 0000000..813008a --- /dev/null +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -0,0 +1,361 @@ @@ -3097,10 +3799,10 @@ index 0000000..2fcfab9 + if (irq >= IRQ_ARM_LOCAL_CNTPSIRQ && irq <= IRQ_ARM_LOCAL_TIMER) { + irq_set_percpu_devid(irq); + irq_set_chip_and_handler(irq, &armctrl_chip, handle_percpu_devid_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); ++ irq_set_status_flags(irq, IRQ_NOAUTOEN); + } else { + irq_set_chip_and_handler(irq, &armctrl_chip, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); + } + irq_set_chip_data(irq, (void *)data); + } @@ -3577,7 +4279,7 @@ index 0000000..e33265d +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c new file mode 100644 -index 0000000..d135620 +index 0000000..8c3f518 --- /dev/null +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -0,0 +1,801 @@ @@ -4295,7 +4997,7 @@ index 0000000..d135620 +/* + * for linux/arch/arm/kernel/smp.c:secondary_start_kernel(void) + */ -+void __cpuinit bcm2709_secondary_init(unsigned int cpu) ++void __init bcm2709_secondary_init(unsigned int cpu) +{ + printk("[%s] enter cpu:%d\n", __FUNCTION__, cpu); + //gic_secondary_init(0); @@ -4304,7 +5006,7 @@ index 0000000..d135620 +/* + * for linux/arch/arm/kernel/smp.c:__cpu_up(..) + */ -+int __cpuinit bcm2709_boot_secondary(unsigned int cpu, struct task_struct *idle) ++int __init bcm2709_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + void secondary_startup(void); + void *mbox_set = __io_address(ARM_LOCAL_MAILBOX3_SET0 + 0x10 * MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0)); @@ -6868,7 +7570,7 @@ index 0000000..c4dc7d6 + } +} diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index b4f92b9..bb263d8 100644 +index df7537f..29352cc 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -358,7 +358,7 @@ config CPU_PJ4B @@ -6908,10 +7610,10 @@ index 06d890a..30d96e8 100644 ENTRY(cpu_v6_dcache_clean_area) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S -index 7911f14..dc287c0 100644 +index de2b246..3a3aec8 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S -@@ -460,6 +460,7 @@ __v7_setup_cont: +@@ -480,6 +480,7 @@ __errata_finish: orr r0, r0, r6 @ set them THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions ret lr @ return to head.S:__ret @@ -6933,10 +7635,10 @@ index 2ed1b8a..b52d949 100644 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index 0aa135d..89dbcb9 100644 +index d6e3e49..7482c15 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c -@@ -882,3 +882,39 @@ void __init acpi_generic_timer_init(void) +@@ -874,3 +874,39 @@ void __init acpi_generic_timer_init(void) acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init); } #endif @@ -6977,10 +7679,10 @@ index 0aa135d..89dbcb9 100644 + return 0; +} diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 0cc622a..2585cd8 100644 +index fd27e98..3c37758 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c -@@ -85,7 +85,7 @@ struct vendor_data { +@@ -87,7 +87,7 @@ struct vendor_data { static unsigned int get_fifosize_arm(struct amba_device *dev) { @@ -6990,22 +7692,505 @@ index 0cc622a..2585cd8 100644 static struct vendor_data vendor_arm = { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index b5bedae..b0258e8 100644 +index 83b81fd..17bec60 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h -@@ -285,6 +285,7 @@ struct mmc_host { - MMC_CAP2_HS400_1_2V) +@@ -289,6 +289,7 @@ struct mmc_host { #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) + #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ +#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ mmc_pm_flag_t pm_caps; /* supported pm features */ -From 7408b83b52329a004068c5749e1733d8cb9028cb Mon Sep 17 00:00:00 2001 +From a86c3cf38e4069cfa9c59a09b1b08c6bed22717f Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 19 Aug 2015 08:49:11 +0100 +Subject: [PATCH 008/113] BCM2708: Use upstream interrupt driver on all Pi1's + +Although the aim is to delete the old armctrl driver, that can't happen +while non-DT configurations are still supported. This commit enables +use of the new FIQ-enabled upstream irqchip driver when DT is enabled +on all BCM2835-based RPi platforms (Models A, B, A+, B+ & CM). + +BCM2836-based platforms (Pi 2) will get the same treatment at a later +date, unless non-DT support has already been withdrawn. +--- + arch/arm/Kconfig | 1 + + arch/arm/mach-bcm2708/armctrl.c | 68 +++++++++++++++++++++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 6 +++- + drivers/irqchip/Makefile | 1 + + 4 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index afbcf9d..354789d 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -327,6 +327,7 @@ config ARCH_BCM2708 + select GENERIC_CLOCKEVENTS + select ARM_ERRATA_411920 + select MACH_BCM2708 ++ select MULTI_IRQ_HANDLER + select VC4 + select FIQ + help +diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c +index 95f272b..85ec395 100644 +--- a/arch/arm/mach-bcm2708/armctrl.c ++++ b/arch/arm/mach-bcm2708/armctrl.c +@@ -26,10 +26,22 @@ + #include + #include + ++#include + #include + #include + #include "armctrl.h" + ++/* Mask out shortcut interrupts where they also appear in the regular bank */ ++#define BANK0_HWIRQ 0x001ffcff ++#define BANK1_HWIRQ BIT(8) ++#define BANK2_HWIRQ BIT(9) ++#define BANK0_VALID_MASK \ ++ (BANK0_HWIRQ + BANK1_HWIRQ + BANK2_HWIRQ) ++#define BANK1_VALID_MASK \ ++ (~(BIT(7) | BIT(9) | BIT(10) | BIT(18) | BIT(19))) ++#define BANK2_VALID_MASK \ ++ (~(BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25) | BIT(30))) ++ + /* For support of kernels >= 3.0 assume only one VIC for now*/ + static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { + INTERRUPT_VC_JPEG, +@@ -275,6 +287,59 @@ static struct irq_chip armctrl_chip = { + .irq_set_wake = armctrl_set_wake, + }; + ++#ifdef CONFIG_MULTI_IRQ_HANDLER ++ ++static void __exception_irq_entry armctrl_handle_irq( ++ struct pt_regs *regs) ++{ ++ u32 stat; ++ ++ while ((stat = readl_relaxed(__io_address(ARM_IRQ_PEND0)) & ++ BANK0_VALID_MASK)) { ++ u32 stat2; ++ u32 irq; ++ ++ if (stat & BANK0_HWIRQ) { ++ irq = ARM_IRQ0_BASE + ffs(stat & BANK0_HWIRQ) - 1; ++ } else if (stat & BANK1_HWIRQ) { ++ stat2 = readl_relaxed(__io_address(ARM_IRQ_PEND1)) & ++ BANK1_VALID_MASK; ++ if (stat2) ++ irq = ARM_IRQ1_BASE + ++ ffs(stat2 & BANK1_VALID_MASK) - 1; ++ else ++ continue; ++ } else if (stat & BANK2_HWIRQ) { ++ stat2 = readl_relaxed(__io_address(ARM_IRQ_PEND2)) & ++ BANK2_VALID_MASK; ++ if (stat2) ++ irq = ARM_IRQ2_BASE + ++ ffs(stat2 & BANK2_VALID_MASK) - 1; ++ else ++ continue; ++ } else { ++ BUG(); ++ } ++ ++ handle_IRQ(irq, regs); ++ } ++} ++ ++/* This function forces the interrupt numbers to be allocated sequentially, ++ * instead of with gaps due to the sparse BANK0, to make the offset from ++ * IRQs and FIQs constant (and equal to FIQ_START). ++ */ ++unsigned int arch_dynirq_lower_bound(unsigned int from) ++{ ++ if (from < 24) ++ return from + 24; ++ else if (from >= 104) ++ return from - 24; ++ return from; ++} ++ ++#endif ++ + /** + * armctrl_init - initialise a vectored interrupt controller + * @base: iomem base address +@@ -298,6 +363,9 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + irq_set_probe(irq); + } + ++#ifdef CONFIG_MULTI_IRQ_HANDLER ++ set_handle_irq(armctrl_handle_irq); ++#endif + armctrl_pm_register(base, irq_start, resume_sources); + armctrl_dt_init(); + return 0; +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index d67ee24..54af8e8 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -89,7 +90,10 @@ static void __init bcm2708_init_led(void); + + void __init bcm2708_init_irq(void) + { +- armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0); ++ if (of_have_populated_dt()) ++ irqchip_init(); ++ else ++ armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0); + } + + static struct map_desc bcm2708_io_desc[] __initdata = { +diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile +index bb3048f..e360137 100644 +--- a/drivers/irqchip/Makefile ++++ b/drivers/irqchip/Makefile +@@ -2,6 +2,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o + + obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o + obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o ++obj-$(CONFIG_ARCH_BCM2708) += irq-bcm2835.o + obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o + obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o + obj-$(CONFIG_ARCH_MMP) += irq-mmp.o + +From 09ff19e8d75f7fdaf7d2b3788070bb8a9f2134cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:37:19 +0200 +Subject: [PATCH 009/113] BCM270x: Switch to firmware driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +defconfig: enable BCM2835_MBOX, RASPBERRYPI_FIRMWARE and BCM_VCIO. +Add firmware node and change mailbox node in Device Tree. +Add/update platform file for firmware and mailbox. +Strip bcm2708-vcio of everything except the legacy API and hook it +up with the firmware driver. + +Signed-off-by: Noralf Trønnes +--- + arch/arm/mach-bcm2708/bcm2708.c | 27 ++++++--------------------- + arch/arm/mach-bcm2709/bcm2709.c | 27 ++++++--------------------- + 2 files changed, 12 insertions(+), 42 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 54af8e8..769e6a4 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -277,29 +277,14 @@ static struct platform_device bcm2708_usb_device = { + }, + }; + +-static struct resource bcm2708_vcio_resources[] = { +- { +- .start = ARMCTRL_0_MAIL0_BASE, +- .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ARM_MAILBOX, +- .end = IRQ_ARM_MAILBOX, +- .flags = IORESOURCE_IRQ, +- }, +-}; +- +-static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +-static struct platform_device bcm2708_vcio_device = { +- .name = "bcm2708_vcio", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vcio_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++static struct platform_device bcm2708_rpifw_device = { ++ .name = "raspberrypi-firmware", + .dev = { +- .dma_mask = &vcio_dmamask, ++ .dma_mask = &rpifw_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ }, + }; + + int __init bcm_register_device(struct platform_device *pdev) +@@ -431,7 +416,7 @@ void __init bcm2708_init(void) + bcm2708_init_clocks(); + bcm2708_dt_init(); + +- bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_rpifw_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 8c3f518..e7e553e 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -304,29 +304,14 @@ static struct platform_device bcm2708_usb_device = { + }, + }; + +-static struct resource bcm2708_vcio_resources[] = { +- { +- .start = ARMCTRL_0_MAIL0_BASE, +- .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ARM_MAILBOX, +- .end = IRQ_ARM_MAILBOX, +- .flags = IORESOURCE_IRQ, +- }, +-}; +- +-static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +-static struct platform_device bcm2708_vcio_device = { +- .name = "bcm2708_vcio", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vcio_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++static struct platform_device bcm2708_rpifw_device = { ++ .name = "raspberrypi-firmware", + .dev = { +- .dma_mask = &vcio_dmamask, ++ .dma_mask = &rpifw_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ }, + }; + + int __init bcm_register_device(struct platform_device *pdev) +@@ -458,7 +443,7 @@ void __init bcm2709_init(void) + bcm2709_init_clocks(); + bcm2709_dt_init(); + +- bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_rpifw_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif + +From d65f19aaa17d12336e2414c1cfb095b250ea3ca1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Thu, 13 Aug 2015 19:17:47 +0200 +Subject: [PATCH 010/113] BCM2708: Use brcm,bcm2835-system-timer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When booting with Device Tree use drivers/clocksource/bcm2835_timer.c + +Signed-off-by: Noralf Trønnes +--- + arch/arm/Kconfig | 2 ++ + arch/arm/mach-bcm2708/bcm2708.c | 7 ++++++- + arch/arm/mach-bcm2708/include/mach/platform.h | 1 - + drivers/clocksource/Makefile | 2 +- + 4 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 354789d..f40e621 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -319,6 +319,8 @@ config ARCH_BCM2708 + bool "Broadcom BCM2708 family" + select CPU_V6 + select ARM_AMBA ++ select CLKSRC_MMIO ++ select CLKSRC_OF if OF + select HAVE_SCHED_CLOCK + select NEED_MACH_GPIO_H + select NEED_MACH_MEMORY_H +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 769e6a4..be963e4 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -390,7 +390,6 @@ static void __init bcm2708_dt_init(void) + { + int ret; + +- of_clk_init(NULL); + ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (ret) { + pr_err("of_platform_populate failed: %d\n", ret); +@@ -494,6 +493,12 @@ static struct delay_timer bcm2708_delay_timer = { + + static void __init bcm2708_timer_init(void) + { ++ if (of_have_populated_dt()) { ++ of_clk_init(NULL); ++ clocksource_of_init(); ++ return; ++ } ++ + /* init high res timer */ + bcm2708_clocksource_init(); + +diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h +index 2e7e1bb..a132502 100644 +--- a/arch/arm/mach-bcm2708/include/mach/platform.h ++++ b/arch/arm/mach-bcm2708/include/mach/platform.h +@@ -181,7 +181,6 @@ + #define MAXIRQNUM (32 + 32 + 20) + #define MAXFIQNUM (32 + 32 + 20) + +-#define MAX_TIMER 2 + #define MAX_PERIOD 699050 + #define TICKS_PER_uSEC 1 + +diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile +index 5c00863..2efed52 100644 +--- a/drivers/clocksource/Makefile ++++ b/drivers/clocksource/Makefile +@@ -19,7 +19,7 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o + obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o + obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o + obj-$(CONFIG_ORION_TIMER) += time-orion.o +-obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o ++obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708) += bcm2835_timer.o + obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o + obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o + obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o + +From f98a40301ec3de0e9308b1edea7014c9e3e5fb47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:19:30 +0200 +Subject: [PATCH 011/113] mailbox: bcm2835: Support ARCH_BCM270x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Make it possible to use bcm2835-mailbox without Device Tree. +Load driver early because of lacking support for deferred probing +in many drivers. + +Signed-off-by: Noralf Trønnes +--- + drivers/mailbox/Kconfig | 2 +- + drivers/mailbox/bcm2835-mailbox.c | 18 ++++++++++++++++-- + drivers/mailbox/mailbox.c | 13 ++++++++++++- + 3 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig +index bbec500..737db54 100644 +--- a/drivers/mailbox/Kconfig ++++ b/drivers/mailbox/Kconfig +@@ -65,7 +65,7 @@ config ALTERA_MBOX + + config BCM2835_MBOX + tristate "BCM2835 Mailbox" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + help + An implementation of the BCM2385 Mailbox. It is used to invoke + the services of the Videocore. Say Y here if you want to use the +diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c +index cfb4b44..d9c6c21 100644 +--- a/drivers/mailbox/bcm2835-mailbox.c ++++ b/drivers/mailbox/bcm2835-mailbox.c +@@ -51,12 +51,15 @@ + #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) + #define MAIL1_STA (ARM_0_MAIL1 + 0x18) + ++/* On ARCH_BCM270x these come through (arm_control.h ) */ ++#ifndef ARM_MS_FULL + /* Status register: FIFO state. */ + #define ARM_MS_FULL BIT(31) + #define ARM_MS_EMPTY BIT(30) + + /* Configuration register: Enable interrupts. */ + #define ARM_MC_IHAVEDATAIRQEN BIT(0) ++#endif + + struct bcm2835_mbox { + void __iomem *regs; +@@ -151,7 +154,7 @@ static int bcm2835_mbox_probe(struct platform_device *pdev) + return -ENOMEM; + spin_lock_init(&mbox->lock); + +- ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), ++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), + bcm2835_mbox_irq, 0, dev_name(dev), mbox); + if (ret) { + dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", +@@ -209,7 +212,18 @@ static struct platform_driver bcm2835_mbox_driver = { + .probe = bcm2835_mbox_probe, + .remove = bcm2835_mbox_remove, + }; +-module_platform_driver(bcm2835_mbox_driver); ++ ++static int __init bcm2835_mbox_init(void) ++{ ++ return platform_driver_register(&bcm2835_mbox_driver); ++} ++arch_initcall(bcm2835_mbox_init); ++ ++static void __init bcm2835_mbox_exit(void) ++{ ++ platform_driver_unregister(&bcm2835_mbox_driver); ++} ++module_exit(bcm2835_mbox_exit); + + MODULE_AUTHOR("Lubomir Rintel "); + MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index 6a4811f..3bb7e87 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -307,13 +307,23 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) + unsigned long flags; + int ret; + +- if (!dev || !dev->of_node) { ++ if (!dev) { + pr_debug("%s: No owner device node\n", __func__); + return ERR_PTR(-ENODEV); + } + + mutex_lock(&con_mutex); + ++ if (!dev->of_node) { ++ chan = ERR_PTR(-EPROBE_DEFER); ++ /* pick the first controller in the list */ ++ list_for_each_entry(mbox, &mbox_cons, node) { ++ chan = &mbox->chans[0]; ++ break; ++ } ++ goto skip_dt; ++ } ++ + if (of_parse_phandle_with_args(dev->of_node, "mboxes", + "#mbox-cells", index, &spec)) { + dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__); +@@ -330,6 +340,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) + + of_node_put(spec.np); + ++skip_dt: + if (IS_ERR(chan)) { + mutex_unlock(&con_mutex); + return chan; + +From d3a7bb9cb866466f6c6c8c01c77b7e52747294bb Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 Oct 2014 18:50:05 +0100 -Subject: [PATCH 002/204] Add bcm2708_gpio driver +Subject: [PATCH 012/113] Add bcm2708_gpio driver Signed-off-by: popcornmix @@ -7041,11 +8226,12 @@ Issue: linux #760 arch/arm/mach-bcm2708/Kconfig | 8 + arch/arm/mach-bcm2708/Makefile | 1 + arch/arm/mach-bcm2708/bcm2708.c | 25 ++ - arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708_gpio.c | 425 ++++++++++++++++++++++++++++++ arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++ + arch/arm/mach-bcm2709/bcm2708_gpio.c | 1 - arch/arm/mach-bcm2709/bcm2709.c | 25 ++ include/linux/platform_data/bcm2708.h | 23 ++ - 7 files changed, 525 insertions(+) + 8 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h create mode 100644 include/linux/platform_data/bcm2708.h @@ -7079,11 +8265,11 @@ index e7d5a29..5120994 100644 obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o +obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a209c58..6c1c616 100644 +index be963e4..3654967 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -298,6 +298,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -287,6 +287,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +#ifdef CONFIG_BCM2708_GPIO @@ -7116,10 +8302,10 @@ index a209c58..6c1c616 100644 int ret; diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c new file mode 100644 -index 0000000..e33265d +index 0000000..ef817fe --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -0,0 +1,426 @@ +@@ -0,0 +1,425 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708_gpio.c + * @@ -7442,7 +8628,6 @@ index 0000000..e33265d + irq_set_chip_data(irq, ucb); + irq_set_chip_and_handler(irq, &bcm2708_irqchip, + handle_simple_irq); -+ set_irq_flags(irq, IRQF_VALID); + } + + bcm2708_gpio_irq.dev_id = ucb; @@ -7569,12 +8754,24 @@ index 0000000..7965a97 +#define irq_to_gpio(x) ((x) - GPIO_IRQ_START) + +#endif +diff --git a/arch/arm/mach-bcm2709/bcm2708_gpio.c b/arch/arm/mach-bcm2709/bcm2708_gpio.c +index e33265d..ef817fe 100644 +--- a/arch/arm/mach-bcm2709/bcm2708_gpio.c ++++ b/arch/arm/mach-bcm2709/bcm2708_gpio.c +@@ -320,7 +320,6 @@ static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb) + irq_set_chip_data(irq, ucb); + irq_set_chip_and_handler(irq, &bcm2708_irqchip, + handle_simple_irq); +- set_irq_flags(irq, IRQF_VALID); + } + + bcm2708_gpio_irq.dev_id = ucb; diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index d135620..b173422 100644 +index e7e553e..5fcd153 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -329,6 +329,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -314,6 +314,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +#ifdef CONFIG_BCM2708_GPIO @@ -7635,644 +8832,10 @@ index 0000000..fb69624 + +#endif -From d86df54c296ad49447cb90e8c9ea1d2c8bd2b82b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 19:11:03 +0200 -Subject: [PATCH 003/204] mailbox: bcm2708: Add bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: popcornmix - -Copy the arch vcio.c driver to drivers/mailbox. -This is done to make it available on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes - -mailbox: bcm2708-vcio: Allocation does not need to be atomic - -No need to do atomic allocation in a context that can sleep. - -Signed-off-by: Noralf Trønnes - -mailbox: bcm2708-vcio: Check the correct status register before writing - -With the VC reader blocked and the ARM writing, MAIL0_STA reads -empty permanently while MAIL1_STA goes from empty (0x40000000) -to non-empty (0x00000001-0x00000007) to full (0x80000008). - -Suggested-by: Phil Elwell -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 6 + - drivers/mailbox/Makefile | 2 + - drivers/mailbox/bcm2708-vcio.c | 427 ++++++++++++++++++++++++++ - include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++ - 4 files changed, 561 insertions(+) - create mode 100644 drivers/mailbox/bcm2708-vcio.c - create mode 100644 include/linux/platform_data/mailbox-bcm2708.h - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 84b0a2d..7f19cb4 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -7,6 +7,12 @@ menuconfig MAILBOX - - if MAILBOX - -+config BCM2708_MBOX -+ bool "Broadcom BCM2708 Mailbox (vcio)" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ help -+ Broadcom BCM2708 Mailbox (vcio) -+ - config ARM_MHU - tristate "ARM MHU Mailbox" - depends on ARM_AMBA -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index b18201e..cecfad3 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -2,6 +2,8 @@ - - obj-$(CONFIG_MAILBOX) += mailbox.o - -+obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o -+ - obj-$(CONFIG_ARM_MHU) += arm_mhu.o - - obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -new file mode 100644 -index 0000000..d91672b ---- /dev/null -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -0,0 +1,427 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_vcio" -+#define DEVICE_FILE_NAME "vcio" -+ -+/* offsets from a mail box base address */ -+#define MAIL0_RD 0x00 /* read - and next 4 words */ -+#define MAIL0_POL 0x10 /* read without popping the fifo */ -+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL0_STA 0x18 /* status */ -+#define MAIL0_CNF 0x1C /* configuration */ -+#define MAIL1_WRT 0x20 /* write - and next 4 words */ -+#define MAIL1_STA 0x38 /* status */ -+ -+/* On MACH_BCM270x these come through (arm_control.h ) */ -+#ifndef ARM_MS_EMPTY -+#define ARM_MS_EMPTY BIT(30) -+#define ARM_MS_FULL BIT(31) -+ -+#define ARM_MC_IHAVEDATAIRQEN BIT(0) -+#endif -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+#define MAJOR_NUM 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+ -+static struct class *vcio_class; -+ -+struct vc_mailbox { -+ void __iomem *regs; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out) -+{ -+ int i; -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -+ -+ return 0; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ -+ return 0; -+} -+ -+static irqreturn_t mbox_irq_handler(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -+ int status = readl(mbox->regs + MAIL0_STA); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->regs + MAIL0_RD); -+ int chan = MBOX_CHAN(msg); -+ -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ pr_err(DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ pr_err(DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->regs + MAIL0_STA); -+ } -+ return ret; -+} -+ -+/* Mailbox Methods */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_write(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_read(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)src < TASK_SIZE) -+ return copy_from_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)dst < TASK_SIZE) -+ return copy_to_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -+ GFP_KERNEL); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* Platform Device for Mailbox */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static bool device_is_open; -+ -+/* This is called whenever a process attempts to open the device file */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* We don't want to talk to two processes at the same time */ -+ if (device_is_open) -+ return -EBUSY; -+ -+ device_is_open = true; -+ try_module_get(THIS_MODULE); -+ -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* We're now ready for our next caller */ -+ device_is_open = false; -+ -+ module_put(THIS_MODULE); -+ -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ default: -+ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+const struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device *vdev; -+ struct vc_mailbox *mailbox; -+ struct resource *res; -+ int irq, ret; -+ -+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -+ if (!mailbox) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mailbox->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mailbox->regs)) -+ return PTR_ERR(mailbox->regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, irq, mbox_irq_handler, -+ IRQF_IRQPOLL, -+ dev_name(dev), mailbox); -+ if (ret) { -+ dev_err(dev, "Interrupt request failed %d\n", ret); -+ return ret; -+ } -+ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ if (ret < 0) { -+ pr_err("Character device registration failed %d\n", ret); -+ return ret; -+ } -+ -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ pr_err("Class creation failed %d\n", ret); -+ goto err_class; -+ } -+ -+ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); -+ if (IS_ERR(vdev)) { -+ ret = PTR_ERR(vdev); -+ pr_err("Device creation failed %d\n", ret); -+ goto err_dev; -+ } -+ -+ mbox_init(mailbox); -+ platform_set_drvdata(pdev, mailbox); -+ mbox_dev = dev; -+ -+ dev_info(dev, "mailbox at %p\n", mailbox->regs); -+ -+ return 0; -+ -+err_dev: -+ class_destroy(vcio_class); -+err_class: -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ mbox_dev = NULL; -+ platform_set_drvdata(pdev, NULL); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm_vcio_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-vcio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm_vcio_of_match_table, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ return platform_driver_register(&bcm_mbox_driver); -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -new file mode 100644 -index 0000000..cc284ed ---- /dev/null -+++ b/include/linux/platform_data/mailbox-bcm2708.h -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef _PLAT_MAILBOX_BCM2708_H -+#define _PLAT_MAILBOX_BCM2708_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+ -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+ -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+int bcm_mailbox_read(unsigned chan, uint32_t *data28); -+int bcm_mailbox_write(unsigned chan, uint32_t data28); -+int bcm_mailbox_property(void *data, int size); -+ -+#endif - -From a01bebe2f26586b5b8021847cc12f83f9fd0a27f Mon Sep 17 00:00:00 2001 +From 69cf08e3b513c929a540214cd0b7f4a433aa6be6 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 004/204] Add dwc_otg driver +Subject: [PATCH 013/113] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -8712,6 +9275,20 @@ comment pointing to a possible: 'usb storage / SCSI bug'. Signed-off-by: Noralf Trønnes dwc_otg: Fix crash when fiq_enable=0 + +dwc_otg: fiq_fsm: Make high-speed isochronous strided transfers work properly + +Certain low-bandwidth high-speed USB devices (specialist audio devices, +compressed-frame webcams) have packet intervals > 1 microframe. + +Stride these transfers in the FIQ by using the start-of-frame interrupt +to restart the channel at the right time. + +dwc_otg: Force host mode to fix incorrect compute module boards + +dwc_otg: Add ARCH_BCM2835 support + +Signed-off-by: Noralf Trønnes --- arch/arm/include/asm/irqflags.h | 16 +- arch/arm/kernel/fiqasm.S | 4 + @@ -8735,7 +9312,7 @@ dwc_otg: Fix crash when fiq_enable=0 drivers/usb/host/dwc_common_port/dwc_cc.c | 532 ++ drivers/usb/host/dwc_common_port/dwc_cc.h | 224 + drivers/usb/host/dwc_common_port/dwc_common_fbsd.c | 1308 ++++ - .../usb/host/dwc_common_port/dwc_common_linux.c | 1434 ++++ + .../usb/host/dwc_common_port/dwc_common_linux.c | 1433 ++++ drivers/usb/host/dwc_common_port/dwc_common_nbsd.c | 1275 ++++ drivers/usb/host/dwc_common_port/dwc_crypto.c | 308 + drivers/usb/host/dwc_common_port/dwc_crypto.h | 111 + @@ -8764,17 +9341,17 @@ dwc_otg: Fix crash when fiq_enable=0 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 1594 +++++ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 705 ++ drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 117 + - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1756 +++++ + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1757 +++++ drivers/usb/host/dwc_otg/dwc_otg_driver.h | 86 + - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 1346 ++++ - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 367 + + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 1355 ++++ + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 370 + drivers/usb/host/dwc_otg/dwc_otg_fiq_stub.S | 80 + - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4252 ++++++++++++ + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4257 ++++++++++++ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 862 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 1132 ++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 417 ++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2713 ++++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 995 +++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2714 ++++++++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 1004 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 957 +++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 188 + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2712 ++++++++ @@ -8787,7 +9364,7 @@ dwc_otg: Fix crash when fiq_enable=0 drivers/usb/host/dwc_otg/test/dwc_otg_test.pm | 337 + drivers/usb/host/dwc_otg/test/test_mod_param.pl | 133 + drivers/usb/host/dwc_otg/test/test_sysfs.pl | 193 + - 74 files changed, 60032 insertions(+), 96 deletions(-) + 74 files changed, 60059 insertions(+), 96 deletions(-) create mode 100644 drivers/usb/gadget/file_storage.c create mode 100644 drivers/usb/host/dwc_common_port/Makefile create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd @@ -8851,16 +9428,17 @@ dwc_otg: Fix crash when fiq_enable=0 create mode 100644 drivers/usb/host/dwc_otg/test/test_sysfs.pl diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h -index 3b763d6..5770408 100644 +index 4390814..2b5c1b7 100644 --- a/arch/arm/include/asm/irqflags.h +++ b/arch/arm/include/asm/irqflags.h -@@ -145,12 +145,22 @@ static inline unsigned long arch_local_save_flags(void) +@@ -152,13 +152,23 @@ static inline unsigned long arch_local_save_flags(void) } /* - * restore saved IRQ & FIQ state + * restore saved IRQ state */ + #define arch_local_irq_restore arch_local_irq_restore static inline void arch_local_irq_restore(unsigned long flags) { - asm volatile( @@ -8893,10 +9471,10 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index 4868cd37..0429225 100644 +index 85ec395..f9c59d8 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -54,8 +54,12 @@ static void armctrl_mask_irq(struct irq_data *d) +@@ -66,8 +66,12 @@ static void armctrl_mask_irq(struct irq_data *d) 0 }; @@ -8911,7 +9489,7 @@ index 4868cd37..0429225 100644 } static void armctrl_unmask_irq(struct irq_data *d) -@@ -67,8 +71,14 @@ static void armctrl_unmask_irq(struct irq_data *d) +@@ -79,8 +83,14 @@ static void armctrl_unmask_irq(struct irq_data *d) 0 }; @@ -8928,19 +9506,19 @@ index 4868cd37..0429225 100644 } #ifdef CONFIG_OF -@@ -299,6 +309,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, - } - +@@ -367,6 +377,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + set_handle_irq(armctrl_handle_irq); + #endif armctrl_pm_register(base, irq_start, resume_sources); + init_FIQ(FIQ_START); armctrl_dt_init(); return 0; } diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6c1c616..1735b72 100644 +index 3654967..354dbf6 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -254,12 +254,23 @@ static struct resource bcm2708_usb_resources[] = { +@@ -258,12 +258,23 @@ static struct resource bcm2708_usb_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { @@ -9135,7 +9713,7 @@ index 3a88a1a..45152ed 100644 #define SPARE_ALLOC_IRQS 64 #define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c -index 2fcfab9..a366275 100644 +index 813008a..c6f68b4 100644 --- a/arch/arm/mach-bcm2709/armctrl.c +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -91,7 +91,15 @@ static void armctrl_unmask_irq(struct irq_data *d) @@ -9180,10 +9758,10 @@ index 358ca8d..abaac7c 100644 return i; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 1e9a8c9..7e9f79f 100644 +index 431839b..56824cfe 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -4906,7 +4906,7 @@ static void port_event(struct usb_hub *hub, int port1) +@@ -4916,7 +4916,7 @@ static void port_event(struct usb_hub *hub, int port1) if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; @@ -9283,11 +9861,11 @@ index f368d20..2f6e3fe 100644 /* Now that the interfaces are installed, re-enable LPM. */ usb_unlocked_enable_lpm(dev); diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h -index a6315ab..165dd53 100644 +index a95b0c9..17b605f 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h @@ -19,33 +19,82 @@ - static struct usb_device_id whitelist_table [] = { + static struct usb_device_id whitelist_table[] = { /* hubs are optional in OTG, but very handy ... */ +#define CERT_WITHOUT_HUBS @@ -13122,10 +13700,10 @@ index 0000000..a896d73 +} +module_exit(fsg_cleanup); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 197a6a3..5496cd0 100644 +index 079991e..050eb41 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig -@@ -738,6 +738,19 @@ config USB_HWA_HCD +@@ -745,6 +745,19 @@ config USB_HWA_HCD To compile this driver a module, choose M here: the module will be called "hwa-hc". @@ -13146,10 +13724,10 @@ index 197a6a3..5496cd0 100644 tristate "i.MX21 HCD support" depends on ARM && ARCH_MXC diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile -index 65b0b6a..49399f2 100644 +index 754efaa..8bb3310 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile -@@ -68,6 +68,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o +@@ -70,6 +70,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o @@ -13157,7 +13735,7 @@ index 65b0b6a..49399f2 100644 +obj-$(CONFIG_USB_DWCOTG) += dwc_otg/ dwc_common_port/ obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o - obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o + obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile new file mode 100644 index 0000000..f10d466 @@ -15840,10 +16418,10 @@ index 0000000..6dd04b5 +} diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c new file mode 100644 -index 0000000..b802042 +index 0000000..4664684 --- /dev/null +++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c -@@ -0,0 +1,1434 @@ +@@ -0,0 +1,1433 @@ +#include +#include +#include @@ -16617,7 +17195,6 @@ index 0000000..b802042 + } + + t->scheduled = 0; -+ t->t->base = &boot_tvec_bases; + t->t->expires = jiffies; + setup_timer(t->t, timer_callback, (unsigned long)t); + @@ -30133,7 +30710,7 @@ index 0000000..55fd337 +#endif /* (__DWC_OTG_CFI_H__) */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c new file mode 100644 -index 0000000..e40060f +index 0000000..beaa8b3 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c @@ -0,0 +1,7141 @@ @@ -30331,7 +30908,7 @@ index 0000000..e40060f + core_if->hptxfsiz.d32 = + DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); + gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); -+ gusbcfg.b.force_host_mode = 0; ++ gusbcfg.b.force_host_mode = 1; + DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); + dwc_mdelay(100); + } @@ -41184,10 +41761,10 @@ index 0000000..ccc24e0 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c new file mode 100644 -index 0000000..53307f0 +index 0000000..95edadf --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -0,0 +1,1756 @@ +@@ -0,0 +1,1757 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $ + * $Revision: #92 $ @@ -41913,6 +42490,7 @@ index 0000000..53307f0 + + memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); + dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF; ++ dwc_otg_device->os_dep.platformdev = _dev; + + /* + * Map the DWC_otg Core memory into virtual address space. @@ -43038,10 +43616,10 @@ index 0000000..6a8be63 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c new file mode 100644 -index 0000000..7e0c726 +index 0000000..85d82f3 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -0,0 +1,1346 @@ +@@ -0,0 +1,1355 @@ +/* + * dwc_otg_fiq_fsm.c - The finite state machine FIQ + * @@ -43659,8 +44237,11 @@ index 0000000..7e0c726 + break; + + case FIQ_HS_ISOC_SLEEPING: -+ state->channel[n].fsm = FIQ_HS_ISOC_TURBO; -+ fiq_fsm_restart_channel(state, n, 0); ++ /* Is it time to wake this channel yet? */ ++ if (--state->channel[n].uframe_sleeps == 0) { ++ state->channel[n].fsm = FIQ_HS_ISOC_TURBO; ++ fiq_fsm_restart_channel(state, n, 0); ++ } + break; + + case FIQ_PER_SSPLIT_QUEUED: @@ -43668,7 +44249,7 @@ index 0000000..7e0c726 + break; + if(!fiq_fsm_tt_in_use(state, num_channels, n)) { + if (!fiq_fsm_too_late(state, n)) { -+ fiq_print(FIQDBG_INT, st, "SOF GO %01d", n); ++ fiq_print(FIQDBG_INT, state, "SOF GO %01d", n); + fiq_fsm_restart_channel(state, n, 0); + state->channel[n].fsm = FIQ_PER_SSPLIT_STARTED; + } else { @@ -44113,8 +44694,14 @@ index 0000000..7e0c726 + if (fiq_fsm_update_hs_isoc(state, n, hcint)) { + /* more transactions to come */ + handled = 1; -+ restart = 1; + fiq_print(FIQDBG_INT, state, "HSISO M "); ++ /* For strided transfers, put ourselves to sleep */ ++ if (st->hs_isoc_info.stride > 1) { ++ st->uframe_sleeps = st->hs_isoc_info.stride - 1; ++ st->fsm = FIQ_HS_ISOC_SLEEPING; ++ } else { ++ restart = 1; ++ } + } else { + st->fsm = FIQ_HS_ISOC_DONE; + fiq_print(FIQDBG_INT, state, "HSISO F "); @@ -44390,10 +44977,10 @@ index 0000000..7e0c726 +} diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h new file mode 100644 -index 0000000..8455324 +index 0000000..f9fddfb --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -0,0 +1,367 @@ +@@ -0,0 +1,370 @@ +/* + * dwc_otg_fiq_fsm.h - Finite state machine FIQ header definitions + * @@ -44656,12 +45243,13 @@ index 0000000..8455324 + * @iso_frame: Pointer to the array of OTG URB iso_frame_descs. + * @nrframes: Total length of iso_frame_desc array + * @index: Current index (FIQ-maintained) -+ * ++ * @stride: Interval in uframes between HS isoc transactions + */ +struct fiq_hs_isoc_info { + struct dwc_otg_hcd_iso_packet_desc *iso_desc; + unsigned int nrframes; + unsigned int index; ++ unsigned int stride; +}; + +/** @@ -44692,6 +45280,8 @@ index 0000000..8455324 + /* Hardware bug workaround: sometimes channel halt interrupts are + * delayed until the next SOF. Keep track of when we expected to get interrupted. */ + unsigned int expected_uframe; ++ /* number of uframes remaining (for interval > 1 HS isoc transfers) before next transfer */ ++ unsigned int uframe_sleeps; + /* in/out for communicating number of dma buffers used, or number of ISOC to do */ + unsigned int nrpackets; + struct fiq_dma_info dma_info; @@ -44849,10 +45439,10 @@ index 0000000..ffa8d21 +END(_dwc_otg_fiq_stub) diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c new file mode 100644 -index 0000000..4d7c7bb +index 0000000..135b611 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -0,0 +1,4252 @@ +@@ -0,0 +1,4257 @@ + +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $ @@ -46533,6 +47123,9 @@ index 0000000..4d7c7bb + } + } + ++ st->hs_isoc_info.stride = qh->interval; ++ st->uframe_sleeps = 0; ++ + fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d ", hc->hc_num); + fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hcchar_copy.d32); + fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hctsiz_copy.d32); @@ -46547,9 +47140,11 @@ index 0000000..4d7c7bb + DWC_WRITE_REG32(&hc_regs->hcintmsk, st->hcintmsk_copy.d32); + if (hfnum.b.frrem < PERIODIC_FRREM_BACKOFF) { + /* Prevent queueing near EOF1. Bad things happen if a periodic -+ * split transaction is queued very close to EOF. ++ * split transaction is queued very close to EOF. SOF interrupt handler ++ * will wake this channel at the next interrupt. + */ + st->fsm = FIQ_HS_ISOC_SLEEPING; ++ st->uframe_sleeps = 1; + } else { + st->fsm = FIQ_HS_ISOC_TURBO; + st->hcchar_copy.b.chen = 1; @@ -51536,10 +52131,10 @@ index 0000000..fb57db0 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c new file mode 100644 -index 0000000..8a31562 +index 0000000..8db3dfc --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -0,0 +1,2713 @@ +@@ -0,0 +1,2714 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $ + * $Revision: #89 $ @@ -51578,7 +52173,6 @@ index 0000000..8a31562 +#include "dwc_otg_regs.h" + +#include -+#include +#include + + @@ -53840,10 +54434,10 @@ index 0000000..8a31562 + dwc_urb->error_count++; + } + } ++ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval * (nr_frames - 1)); ++ + //printk_ratelimited(KERN_INFO "%s: HS isochronous of %d/%d frames with %d errors complete\n", + // __FUNCTION__, i, dwc_urb->packet_count, dwc_urb->error_count); -+ hcd->fops->complete(hcd, dwc_urb->priv, dwc_urb, 0); -+ release_channel(hcd, qh->channel, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); +} + +/** @@ -54086,6 +54680,8 @@ index 0000000..8a31562 + * fail. + */ + dwc_otg_fiq_unmangle_isoc(hcd, qh, qtd, num); ++ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); ++ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); + break; + + case FIQ_PER_SPLIT_LS_ABORTED: @@ -54255,10 +54851,10 @@ index 0000000..8a31562 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c new file mode 100644 -index 0000000..0f4ebcd +index 0000000..a331720 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -0,0 +1,995 @@ +@@ -0,0 +1,1004 @@ + +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $ @@ -54706,7 +55302,16 @@ index 0000000..0f4ebcd + DWC_WARN("MPHI periph has NOT been enabled"); +#endif + // Enable FIQ interrupt from USB peripheral -+ enable_fiq(INTERRUPT_VC_USB); ++#ifdef CONFIG_ARCH_BCM2835 ++ enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1)); ++#else ++#ifdef CONFIG_MULTI_IRQ_HANDLER ++ if (otg_dev->os_dep.platformdev->dev.of_node) ++ enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1)); ++ else ++#endif ++ enable_fiq(INTERRUPT_VC_USB); ++#endif + local_fiq_enable(); +} + @@ -69546,10 +70151,10 @@ index 0000000..cdc9963 +test_main(); +0; -From a7a65674af3af5dcc29121afaae50c0cf6b2e13b Mon Sep 17 00:00:00 2001 +From 2012bcba9accf8b797c2d418707ddd76c40f9a1c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:54:32 +0100 -Subject: [PATCH 005/204] bcm2708 watchdog driver +Subject: [PATCH 014/113] bcm2708 watchdog driver Signed-off-by: popcornmix --- @@ -69560,10 +70165,10 @@ Signed-off-by: popcornmix create mode 100644 drivers/watchdog/bcm2708_wdog.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index e5e7c55..b9c1ed5 100644 +index 79e1aa1..ee7eebf 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -451,6 +451,12 @@ config RETU_WATCHDOG +@@ -482,6 +482,12 @@ config RETU_WATCHDOG To compile this driver as a module, choose M here: the module will be called retu_wdt. @@ -69576,7 +70181,7 @@ index e5e7c55..b9c1ed5 100644 config MOXART_WDT tristate "MOXART watchdog" depends on ARCH_MOXART -@@ -1216,7 +1222,7 @@ config BCM63XX_WDT +@@ -1282,7 +1288,7 @@ config BCM63XX_WDT config BCM2835_WDT tristate "Broadcom BCM2835 hardware watchdog" @@ -69586,10 +70191,10 @@ index e5e7c55..b9c1ed5 100644 help Watchdog driver for the built in watchdog hardware in Broadcom diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile -index 5c19294..aac60bd 100644 +index 0c616e3..3afbeed 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile -@@ -56,6 +56,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o +@@ -57,6 +57,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o @@ -69986,10 +70591,10 @@ index 0000000..8a27d68 +MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_LICENSE("GPL"); -From d2d531d448b63465a680fb3e15c0e843267ff50f Mon Sep 17 00:00:00 2001 +From 1434672b2776aeb98cb206c6b002fdc138628079 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 006/204] bcm2708 framebuffer driver +Subject: [PATCH 015/113] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -70065,13 +70670,13 @@ Signed-off-by: Noralf Trønnes --- drivers/video/fbdev/Kconfig | 14 + drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/bcm2708_fb.c | 824 ++++++++++ + drivers/video/fbdev/bcm2708_fb.c | 847 ++++++++++ drivers/video/logo/logo_linux_clut224.ppm | 2483 ++++++++++------------------- - 4 files changed, 1720 insertions(+), 1602 deletions(-) + 4 files changed, 1743 insertions(+), 1602 deletions(-) create mode 100644 drivers/video/fbdev/bcm2708_fb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index d1e1e17..15098c5 100644 +index 8b1d371..f1b031e 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -224,6 +224,20 @@ config FB_TILEBLITTING @@ -70080,7 +70685,7 @@ index d1e1e17..15098c5 100644 +config FB_BCM2708 + tristate "BCM2708 framebuffer support" -+ depends on FB && ARM && BCM2708_MBOX ++ depends on FB && RASPBERRYPI_FIRMWARE + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT @@ -70096,7 +70701,7 @@ index d1e1e17..15098c5 100644 tristate "Aeroflex Gaisler framebuffer support" depends on FB && SPARC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 1979aff..57181ad 100644 +index 50ed1b4..9b086ac 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_FB_MACMODES) += macmodes.o @@ -70109,10 +70714,10 @@ index 1979aff..57181ad 100644 obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c new file mode 100644 -index 0000000..f6ac7da +index 0000000..0f62d76 --- /dev/null +++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -0,0 +1,824 @@ +@@ -0,0 +1,847 @@ +/* + * linux/drivers/video/bcm2708_fb.c + * @@ -70140,7 +70745,6 @@ index 0000000..f6ac7da +#include +#include +#include -+#include +#include +#include +#include @@ -70149,6 +70753,7 @@ index 0000000..f6ac7da +#include +#include +#include ++#include + +//#define BCM2708_FB_DEBUG +#define MODULE_NAME "bcm2708_fb" @@ -70173,15 +70778,19 @@ index 0000000..f6ac7da +module_param(dma_busy_wait_threshold, int, 0644); +MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); + -+/* this data structure describes each frame buffer device we find */ -+ -+struct fbinfo_s { -+ u32 xres, yres, xres_virtual, yres_virtual; -+ u32 pitch, bpp; ++struct fb_alloc_tags { ++ struct rpi_firmware_property_tag_header tag1; ++ u32 xres, yres; ++ struct rpi_firmware_property_tag_header tag2; ++ u32 xres_virtual, yres_virtual; ++ struct rpi_firmware_property_tag_header tag3; ++ u32 bpp; ++ struct rpi_firmware_property_tag_header tag4; + u32 xoffset, yoffset; -+ u32 base; -+ u32 screen_size; -+ u16 cmap[256]; ++ struct rpi_firmware_property_tag_header tag5; ++ u32 base, screen_size; ++ struct rpi_firmware_property_tag_header tag6; ++ u32 pitch; +}; + +struct bcm2708_fb_stats { @@ -70193,9 +70802,9 @@ index 0000000..f6ac7da +struct bcm2708_fb { + struct fb_info fb; + struct platform_device *dev; -+ struct fbinfo_s *info; -+ dma_addr_t dma; ++ struct rpi_firmware *fw; + u32 cmap[16]; ++ u32 gpu_cmap[256]; + int dma_chan; + int dma_irq; + void __iomem *dma_chan_base; @@ -70374,80 +70983,76 @@ index 0000000..f6ac7da + if (var->yoffset > var->yres_virtual - var->yres) + var->yoffset = var->yres_virtual - var->yres - 1; + -+ yres = var->yres; -+ if (var->vmode & FB_VMODE_DOUBLE) -+ yres *= 2; -+ else if (var->vmode & FB_VMODE_INTERLACED) -+ yres = (yres + 1) / 2; -+ + return 0; +} + +static int bcm2708_fb_set_par(struct fb_info *info) +{ -+ uint32_t val = 0; + struct bcm2708_fb *fb = to_bcm2708(info); -+ volatile struct fbinfo_s *fbinfo = fb->info; -+ fbinfo->xres = info->var.xres; -+ fbinfo->yres = info->var.yres; -+ fbinfo->xres_virtual = info->var.xres_virtual; -+ fbinfo->yres_virtual = info->var.yres_virtual; -+ fbinfo->bpp = info->var.bits_per_pixel; -+ fbinfo->xoffset = info->var.xoffset; -+ fbinfo->yoffset = info->var.yoffset; -+ fbinfo->base = 0; /* filled in by VC */ -+ fbinfo->pitch = 0; /* filled in by VC */ ++ struct fb_alloc_tags fbinfo = { ++ .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ .xres = info->var.xres, ++ .yres = info->var.yres, ++ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ .xres_virtual = info->var.xres_virtual, ++ .yres_virtual = info->var.yres_virtual, ++ .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, ++ .bpp = info->var.bits_per_pixel, ++ .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, ++ .xoffset = info->var.xoffset, ++ .yoffset = info->var.yoffset, ++ .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, ++ .base = 0, ++ .screen_size = 0, ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, ++ .pitch = 0, ++ }; ++ int ret; + + print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, + info->var.bits_per_pixel); + -+ /* ensure last write to fbinfo is visible to GPU */ -+ wmb(); -+ -+ /* inform vc about new framebuffer */ -+ bcm_mailbox_write(MBOX_CHAN_FB, fb->dma); -+ -+ /* TODO: replace fb driver with vchiq version */ -+ /* wait for response */ -+ bcm_mailbox_read(MBOX_CHAN_FB, &val); -+ -+ /* ensure GPU writes are visible to us */ -+ rmb(); -+ -+ if (val == 0) { -+ fb->fb.fix.line_length = fbinfo->pitch; -+ -+ if (info->var.bits_per_pixel <= 8) -+ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ else -+ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; -+ -+ fb->fb_bus_address = fbinfo->base; -+ fbinfo->base &= ~0xc0000000; -+ fb->fb.fix.smem_start = fbinfo->base; -+ fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; -+ fb->fb.screen_size = fbinfo->screen_size; -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ fb->fb.screen_base = -+ (void *)ioremap_wc(fbinfo->base, fb->fb.screen_size); -+ if (!fb->fb.screen_base) { -+ /* the console may currently be locked */ -+ console_trylock(); -+ console_unlock(); -+ pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); -+ return -EIO; -+ } ++ ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); ++ if (ret) { ++ dev_err(info->device, ++ "Failed to allocate GPU framebuffer (%d)\n", ret); ++ return ret; + } -+ print_debug -+ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", -+ (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, -+ fbinfo->xres, fbinfo->yres, fbinfo->bpp, -+ fbinfo->pitch, (int)fb->fb.screen_size, val); + -+ return val; ++ if (info->var.bits_per_pixel <= 8) ++ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else ++ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; ++ ++ fb->fb.fix.line_length = fbinfo.pitch; ++ fbinfo.base |= 0x40000000; ++ fb->fb_bus_address = fbinfo.base; ++ fbinfo.base &= ~0xc0000000; ++ fb->fb.fix.smem_start = fbinfo.base; ++ fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; ++ fb->fb.screen_size = fbinfo.screen_size; ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); ++ if (!fb->fb.screen_base) { ++ /* the console may currently be locked */ ++ console_trylock(); ++ console_unlock(); ++ dev_err(info->device, "Failed to set screen_base\n"); ++ return -ENOMEM; ++ } ++ ++ print_debug ++ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", ++ (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, ++ fbinfo.xres, fbinfo.yres, fbinfo.bpp, ++ fbinfo.pitch, (int)fb->fb.screen_size); ++ ++ return 0; +} + +static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) @@ -70467,15 +71072,34 @@ index 0000000..f6ac7da + /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ + if (fb->fb.var.bits_per_pixel <= 8) { + if (regno < 256) { -+ /* blue [0:4], green [5:10], red [11:15] */ -+ fb->info->cmap[regno] = ((red >> (16-5)) & 0x1f) << 11 | -+ ((green >> (16-6)) & 0x3f) << 5 | -+ ((blue >> (16-5)) & 0x1f) << 0; ++ /* blue [23:16], green [15:8], red [7:0] */ ++ fb->gpu_cmap[regno] = ((red >> 8) & 0xff) << 0 | ++ ((green >> 8) & 0xff) << 8 | ++ ((blue >> 8) & 0xff) << 16; + } + /* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */ + /* So just call it for what looks like the last colour in a list for now. */ -+ if (regno == 15 || regno == 255) -+ bcm2708_fb_set_par(info); ++ if (regno == 15 || regno == 255) { ++ struct packet { ++ u32 offset; ++ u32 length; ++ u32 cmap[256]; ++ } *packet; ++ int ret; ++ ++ packet = kmalloc(sizeof(*packet), GFP_KERNEL); ++ if (!packet) ++ return -ENOMEM; ++ packet->offset = 0; ++ packet->length = regno + 1; ++ memcpy(packet->cmap, fb->gpu_cmap, sizeof(packet->cmap)); ++ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, ++ packet, (2 + packet->length) * sizeof(u32)); ++ if (ret || packet->offset) ++ dev_err(info->device, "Failed to set palette (%d,%u)\n", ++ ret, packet->offset); ++ kfree(packet); ++ } + } else if (regno < 16) { + fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | + convert_bitfield(blue, &fb->fb.var.blue) | @@ -70487,32 +71111,36 @@ index 0000000..f6ac7da + +static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) +{ -+ s32 result = -1; -+ u32 p[7]; -+ if ( (blank_mode == FB_BLANK_NORMAL) || -+ (blank_mode == FB_BLANK_UNBLANK)) { ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ u32 value; ++ int ret; + -+ p[0] = 28; // size = sizeof u32 * length of p -+ p[1] = VCMSG_PROCESS_REQUEST; // process request -+ p[2] = VCMSG_SET_BLANK_SCREEN; // (the tag id) -+ p[3] = 4; // (size of the response buffer) -+ p[4] = 4; // (size of the request data) -+ p[5] = blank_mode; -+ p[6] = VCMSG_PROPERTY_END; // end tag -+ -+ bcm_mailbox_property(&p, p[0]); -+ -+ if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -+ result = 0; -+ else -+ pr_err("bcm2708_fb_blank(%d) returns=%d p[1]=0x%x\n", blank_mode, p[5], p[1]); ++ switch (blank_mode) { ++ case FB_BLANK_UNBLANK: ++ value = 0; ++ break; ++ case FB_BLANK_NORMAL: ++ case FB_BLANK_VSYNC_SUSPEND: ++ case FB_BLANK_HSYNC_SUSPEND: ++ case FB_BLANK_POWERDOWN: ++ value = 1; ++ break; ++ default: ++ return -EINVAL; + } -+ return result; ++ ++ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, ++ &value, sizeof(value)); ++ if (ret) ++ dev_err(info->device, "bcm2708_fb_blank(%d) failed: %d\n", ++ blank_mode, ret); ++ ++ return ret; +} + +static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ -+ s32 result = -1; ++ s32 result; + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + result = bcm2708_fb_set_par(info); @@ -70523,25 +71151,25 @@ index 0000000..f6ac7da + +static int bcm2708_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +{ -+ s32 result = -1; -+ u32 p[7]; -+ if (cmd == FBIO_WAITFORVSYNC) { -+ p[0] = 28; // size = sizeof u32 * length of p -+ p[1] = VCMSG_PROCESS_REQUEST; // process request -+ p[2] = VCMSG_SET_VSYNC; // (the tag id) -+ p[3] = 4; // (size of the response buffer) -+ p[4] = 4; // (size of the request data) -+ p[5] = 0; // dummy -+ p[6] = VCMSG_PROPERTY_END; // end tag ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ u32 dummy = 0; ++ int ret; + -+ bcm_mailbox_property(&p, p[0]); -+ -+ if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -+ result = 0; -+ else -+ pr_err("bcm2708_fb_ioctl %x,%lx returns=%d p[1]=0x%x\n", cmd, arg, p[5], p[1]); ++ switch (cmd) { ++ case FBIO_WAITFORVSYNC: ++ ret = rpi_firmware_property(fb->fw, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC, ++ &dummy, sizeof(dummy)); ++ break; ++ default: ++ dev_err(info->device, "Unknown ioctl 0x%x\n", cmd); ++ return -EINVAL; + } -+ return result; ++ ++ if (ret) ++ dev_err(info->device, "ioctl 0x%x failed (%d)\n", cmd, ret); ++ ++ return ret; +} +static void bcm2708_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) @@ -70736,20 +71364,7 @@ index 0000000..f6ac7da +static int bcm2708_fb_register(struct bcm2708_fb *fb) +{ + int ret; -+ dma_addr_t dma; -+ void *mem; + -+ mem = -+ dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, -+ GFP_KERNEL); -+ -+ if (NULL == mem) { -+ pr_err(": unable to allocate fbinfo buffer\n"); -+ ret = -ENOMEM; -+ } else { -+ fb->info = (struct fbinfo_s *)mem; -+ fb->dma = dma; -+ } + fb->fb.fbops = &bcm2708_fb_ops; + fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA; + fb->fb.pseudo_palette = fb->cmap; @@ -70808,9 +71423,22 @@ index 0000000..f6ac7da + +static int bcm2708_fb_probe(struct platform_device *dev) +{ ++ struct device_node *fw_np; ++ struct rpi_firmware *fw; + struct bcm2708_fb *fb; + int ret; + ++ fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0); ++/* Remove comment when booting without Device Tree is no longer supported ++ if (!fw_np) { ++ dev_err(&dev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++*/ ++ fw = rpi_firmware_get(fw_np); ++ if (!fw) ++ return -EPROBE_DEFER; ++ + fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); + if (!fb) { + dev_err(&dev->dev, @@ -70819,6 +71447,7 @@ index 0000000..f6ac7da + goto free_region; + } + ++ fb->fw = fw; + bcm2708_fb_debugfs_init(fb); + + fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, @@ -70852,6 +71481,7 @@ index 0000000..f6ac7da + fb->dma_chan, fb->dma_chan_base); + + fb->dev = dev; ++ fb->fb.device = &dev->dev; + + ret = bcm2708_fb_register(fb); + if (ret == 0) { @@ -70884,8 +71514,6 @@ index 0000000..f6ac7da + dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); + bcm_dma_chan_free(fb->dma_chan); + -+ dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, -+ fb->dma); + bcm2708_fb_debugfs_deinit(fb); + + free_irq(fb->dma_irq, fb); @@ -73428,10 +74056,10 @@ index 3c14e43..7626beb6a 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From 7b98bf652df7771dd8eb79528dd7e276f2038585 Mon Sep 17 00:00:00 2001 +From 99dd78ca9d2537b3d348f2cc0f6d29c11b94c7e8 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 007/204] dmaengine: Add support for BCM2708 +Subject: [PATCH 016/113] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -73535,22 +74163,43 @@ bcm2708-dmaengine supports residue reporting at burst level but didn't report this via the residue_granularity field. Without this field set properly we get playback issues with I2S cards. + +dmaengine: bcm2708-dmaengine: Fix memory leak when stopping a running transfer + +bcm2708-dmaengine: Use more DMA channels (but not 12) + +1) Only the bcm2708_fb drivers uses the legacy DMA API, and +it requires a BULK-capable channel, so all other types +(FAST, NORMAL and LITE) can be made available to the regular +DMA API. + +2) DMA channels 11-14 share an interrupt. The driver can't +handle this, so don't use channels 12-14 (12 was used, probably +because it appears to have an interrupt, but in reality that +interrupt is for activity on ANY channel). This may explain +a lockup encountered when running out of DMA channels. + +The combined effect of this patch is to leave 7 DMA channels +available + channel 0 for bcm2708_fb via the legacy API. + +See: https://github.com/raspberrypi/linux/issues/1110 + https://github.com/raspberrypi/linux/issues/1108 --- arch/arm/mach-bcm2708/bcm2708.c | 68 ++ arch/arm/mach-bcm2709/bcm2709.c | 68 ++ - drivers/dma/Kconfig | 13 +- + drivers/dma/Kconfig | 11 + drivers/dma/Makefile | 1 + - drivers/dma/bcm2708-dmaengine.c | 1298 +++++++++++++++++++++++++++++ + drivers/dma/bcm2708-dmaengine.c | 1314 +++++++++++++++++++++++++++++ include/linux/platform_data/dma-bcm2708.h | 127 +++ - 6 files changed, 1574 insertions(+), 1 deletion(-) + 6 files changed, 1589 insertions(+) create mode 100644 drivers/dma/bcm2708-dmaengine.c create mode 100644 include/linux/platform_data/dma-bcm2708.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 1735b72..1622300 100644 +index 354dbf6..5624964 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -234,6 +234,73 @@ static struct amba_device *amba_devs[] __initdata = { +@@ -238,6 +238,73 @@ static struct amba_device *amba_devs[] __initdata = { &uart0_device, }; @@ -73624,16 +74273,16 @@ index 1735b72..1622300 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -463,6 +530,7 @@ void __init bcm2708_init(void) +@@ -451,6 +518,7 @@ void __init bcm2708_init(void) bcm2708_init_clocks(); bcm2708_dt_init(); + bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index b173422..fee17e2 100644 +index 5fcd153..ebb6cbc 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -244,6 +244,73 @@ static struct amba_device *amba_devs[] __initdata = { @@ -73710,21 +74359,21 @@ index b173422..fee17e2 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -483,6 +550,7 @@ void __init bcm2709_init(void) +@@ -468,6 +535,7 @@ void __init bcm2709_init(void) bcm2709_init_clocks(); bcm2709_dt_init(); + bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index bda2cb0..21e781f 100644 +index b458475..b0f042c 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig -@@ -337,6 +337,17 @@ config DMA_BCM2835 - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS +@@ -470,6 +470,17 @@ config TIMB_DMA + help + Enable support for the Timberdale FPGA DMA engine. +config DMA_BCM2708 + tristate "BCM2708 DMA engine support" @@ -73740,33 +74389,24 @@ index bda2cb0..21e781f 100644 config TI_CPPI41 tristate "AM33xx CPPI41 DMA support" depends on ARCH_OMAP -@@ -385,7 +396,7 @@ config MOXART_DMA - select DMA_VIRTUAL_CHANNELS - help - Enable support for the MOXA ART SoC DMA controller. -- -+ - config FSL_EDMA - tristate "Freescale eDMA engine support" - depends on OF diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile -index 69f77d5..678e162 100644 +index 7711a71..7308bd3 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o - obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o - obj-$(CONFIG_DMA_OMAP) += omap-dma.o - obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o +@@ -18,6 +18,7 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o + obj-$(CONFIG_AT_XDMAC) += at_xdmac.o + obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o + obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o +obj-$(CONFIG_DMA_BCM2708) += bcm2708-dmaengine.o - obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o + obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c new file mode 100644 -index 0000000..987ed53 +index 0000000..85ce18b --- /dev/null +++ b/drivers/dma/bcm2708-dmaengine.c -@@ -0,0 +1,1298 @@ +@@ -0,0 +1,1314 @@ +/* + * BCM2835 DMA engine support + * @@ -73953,7 +74593,7 @@ index 0000000..987ed53 +} + +static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) ++ unsigned required_feature_set) +{ + u32 chans; + int chan = 0; @@ -73962,10 +74602,8 @@ index 0000000..987ed53 + chans = dmaman->chan_available; + for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) + /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) ++ features */ ++ if (required_feature_set & (1 << feature)) + chans &= dmaman->has_feature[feature]; + + if (!chans) @@ -73997,7 +74635,7 @@ index 0000000..987ed53 + +/* DMA Manager Monitor */ + -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++extern int bcm_dma_chan_alloc(unsigned required_feature_set, + void __iomem **out_dma_base, int *out_dma_irq) +{ + struct vc_dmaman *dmaman = g_dmaman; @@ -74009,7 +74647,7 @@ index 0000000..987ed53 + return -ENODEV; + + mutex_lock(&dmaman->lock); -+ chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); ++ chan = vc_dmaman_chan_alloc(dmaman, required_feature_set); + if (chan < 0) + goto out; + @@ -74211,6 +74849,7 @@ index 0000000..987ed53 + return container_of(t, struct bcm2835_desc, vd.tx); +} + ++#if 0 +static void dma_dumpregs(struct bcm2835_chan *c) +{ + pr_debug("-------------DMA DUMPREGS-------------\n"); @@ -74226,6 +74865,7 @@ index 0000000..987ed53 + readl(c->chan_base + BCM2835_DMA_NEXTCB)); + pr_debug("--------------------------------------\n"); +} ++#endif + +static void bcm2835_dma_desc_free(struct virt_dma_desc *vd) +{ @@ -74631,6 +75271,7 @@ index 0000000..987ed53 + uint32_t len = sg_dma_len(sgent); + + for (j = 0; j < len; j += max_size) { ++ u32 waits; + struct bcm2835_dma_cb *control_block = + &d->control_block_base[i+splitct]; + @@ -74648,7 +75289,7 @@ index 0000000..987ed53 + } + + /* Common part */ -+ u32 waits = SDHCI_BCM_DMA_WAITS; ++ waits = SDHCI_BCM_DMA_WAITS; + if ((dma_debug >> 0) & 0x1f) + waits = (dma_debug >> 0) & 0x1f; + control_block->info |= BCM2835_DMA_WAITS(waits); @@ -74733,6 +75374,7 @@ index 0000000..987ed53 + * c->desc is NULL and exit.) + */ + if (c->desc) { ++ bcm2835_dma_desc_free(&c->desc->vd); + c->desc = NULL; + bcm2835_dma_abort(c->chan_base); + @@ -74842,6 +75484,14 @@ index 0000000..987ed53 + int rc; + int i; + int irq; ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++ static const u32 wanted_features[] = { ++ BCM_DMA_FEATURE_FAST, ++ BCM_DMA_FEATURE_NORMAL, ++ BCM_DMA_FEATURE_LITE ++ }; ++ int j; ++#endif + + + if (!pdev->dev.dma_mask) @@ -74888,20 +75538,24 @@ index 0000000..987ed53 + + platform_set_drvdata(pdev, od); + -+ for (i = 0; i < 5; i++) { ++ for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) { ++ + void __iomem *chan_base; + int chan_id; + -+ chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE, -+ &chan_base, -+ &irq); ++ chan_id = bcm_dma_chan_alloc(wanted_features[j], ++ &chan_base, ++ &irq); + -+ if (chan_id < 0) -+ break; ++ if (chan_id < 0) { ++ j++; ++ continue; ++ } + + rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq); + if (rc) + goto err_no_dma; ++ i++; + } + + if (pdev->dev.of_node) { @@ -74914,6 +75568,8 @@ index 0000000..987ed53 + } + } + ++ dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i); ++ +#else + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) @@ -75199,10 +75855,96 @@ index 0000000..2310e34 + +#endif /* _PLAT_BCM2708_DMA_H */ -From 44cbf9ce5089b224b53fa45eade2bfb7111bc2db Mon Sep 17 00:00:00 2001 +From dcdbec87712932f319e3772806c9cd2c538cefd3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 17 Apr 2015 19:30:22 +0100 +Subject: [PATCH 017/113] Add blk_pos parameter to mmc multi_io_quirk callback + +--- + drivers/mmc/card/block.c | 1 + + drivers/mmc/host/omap_hsmmc.c | 4 +++- + drivers/mmc/host/sh_mobile_sdhi.c | 4 +++- + drivers/mmc/host/tmio_mmc_pio.c | 4 +++- + include/linux/mmc/host.h | 4 +++- + 5 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index c742cfd..566fca5 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1428,6 +1428,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, + brq->data.blocks = card->host->ops->multi_io_quirk(card, + (rq_data_dir(req) == READ) ? + MMC_DATA_READ : MMC_DATA_WRITE, ++ blk_rq_pos(req), + brq->data.blocks); + } + +diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c +index 7fb0753..708d0fa 100644 +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -1832,7 +1832,9 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) + } + + static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, +- unsigned int direction, int blk_size) ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size) + { + /* This controller can't do multiblock reads due to hw bugs */ + if (direction == MMC_DATA_READ) +diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c +index 354f4f3..4f1ccf3 100644 +--- a/drivers/mmc/host/sh_mobile_sdhi.c ++++ b/drivers/mmc/host/sh_mobile_sdhi.c +@@ -170,7 +170,9 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) + } + + static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card, +- unsigned int direction, int blk_size) ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size) + { + /* + * In Renesas controllers, when performing a +diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c +index a10fde4..7b730d8 100644 +--- a/drivers/mmc/host/tmio_mmc_pio.c ++++ b/drivers/mmc/host/tmio_mmc_pio.c +@@ -1003,7 +1003,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) + } + + static int tmio_multi_io_quirk(struct mmc_card *card, +- unsigned int direction, int blk_size) ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size) + { + struct tmio_mmc_host *host = mmc_priv(card->host); + +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +index 17bec60..9597d4e 100644 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -143,7 +143,9 @@ struct mmc_host_ops { + * I/O. Returns the number of supported blocks for the request. + */ + int (*multi_io_quirk)(struct mmc_card *card, +- unsigned int direction, int blk_size); ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size); + }; + + struct mmc_card; + +From b180a5655934b26f809e588018cab2b2f9c3c937 Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 008/204] MMC: added alternative MMC driver +Subject: [PATCH 018/113] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -75266,21 +76008,23 @@ Add Device Tree entry for bcm2835-mmc. In non-DT mode, don't add the device in the board file. Signed-off-by: Noralf Trønnes + +bcm2835-mmc: Don't overwrite MMC capabilities from DT --- arch/arm/mach-bcm2708/bcm2708.c | 31 + arch/arm/mach-bcm2709/bcm2709.c | 35 +- drivers/mmc/core/quirks.c | 6 + drivers/mmc/host/Kconfig | 29 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1558 +++++++++++++++++++++++++++++++++++++++ - 6 files changed, 1658 insertions(+), 2 deletions(-) + drivers/mmc/host/bcm2835-mmc.c | 1559 +++++++++++++++++++++++++++++++++++++++ + 6 files changed, 1659 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 1622300..6257407 100644 +index 5624964..4ea857c 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -401,6 +401,34 @@ static struct platform_device bcm2708_gpio_device = { +@@ -390,6 +390,34 @@ static struct platform_device bcm2708_gpio_device = { }; #endif @@ -75315,7 +76059,7 @@ index 1622300..6257407 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -538,6 +566,9 @@ void __init bcm2708_init(void) +@@ -526,6 +554,9 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); @@ -75326,10 +76070,10 @@ index 1622300..6257407 100644 bcm2708_init_uart1(); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index fee17e2..07750ed 100644 +index ebb6cbc..b762819 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -421,6 +421,34 @@ static struct platform_device bcm2708_gpio_device = { +@@ -406,6 +406,34 @@ static struct platform_device bcm2708_gpio_device = { }; #endif @@ -75364,7 +76108,7 @@ index fee17e2..07750ed 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -558,8 +586,11 @@ void __init bcm2709_init(void) +@@ -543,8 +571,11 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); @@ -75402,7 +76146,7 @@ index dd1d1e0..bc3bbad 100644 } EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index b1f837e..0ef7417 100644 +index 8a1e349..6d5b8bb 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -4,6 +4,35 @@ @@ -75442,7 +76186,7 @@ index b1f837e..0ef7417 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index e3ab5b9..f1ee1f7 100644 +index 4f3452a..68e64ab 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -75452,13 +76196,13 @@ index e3ab5b9..f1ee1f7 100644 +obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o - obj-$(CONFIG_MMC_OMAP) += omap.o + obj-$(CONFIG_MMC_MTK) += mtk-sd.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..b7c4883 +index 0000000..164bfad --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1558 @@ +@@ -0,0 +1,1559 @@ +/* + * BCM2835 MMC host driver. + * @@ -76788,8 +77532,9 @@ index 0000000..b7c4883 + mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; +#endif + /* host controller capabilities */ -+ mmc->caps = MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ | -+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; ++ mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | ++ MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | ++ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; + + host->flags = SDHCI_AUTO_CMD23; + @@ -77018,10 +77763,10 @@ index 0000000..b7c4883 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From b0a083aa54f21ac74e866d9c016653d247e6d2b7 Mon Sep 17 00:00:00 2001 +From 03dd4d58692aa393fe68b09e0f1f4a58583afa27 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 009/204] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 019/113] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. @@ -77042,15 +77787,61 @@ Use at your own risk. bcm2835-sdhost: Round up the overclock, so 62 works for 62.5Mhz Also only warn once for each overclock setting. + +bcm2835-sdhost: Improve error handling and recovery + +1) Expose the hw_reset method to the MMC framework, removing many + internal calls by the driver. + +2) Reduce overclock setting on error. + +3) Increase timeout to cope with high capacity cards. + +4) Add properties and parameters to control pio_limit and debug. + +5) Reduce messages at probe time. + +bcm2835-sdhost: Further improve overclock back-off + +bcm2835-sdhost: Clear HBLC for PIO mode + +Also update pio_limit default in overlay README. + +bcm2835-sdhost: Add the ERASE capability + +See: https://github.com/raspberrypi/linux/issues/1076 + +bcm2835-sdhost: Ignore CRC7 for MMC CMD1 + +It seems that the sdhost interface returns CRC7 errors for CMD1, +which is the MMC-specific SEND_OP_COND. Returning these errors to +the MMC layer causes a downward spiral, but ignoring them seems +to be harmless. + +bcm2835-mmc/sdhost: Remove ARCH_BCM2835 differences + +The bcm2835-mmc driver (and -sdhost driver that copied from it) +contains code to handle SDIO interrupts in a threaded interrupt +handler rather than waking the MMC framework thread. The change +follows a patch from Russell King that adds the facility as the +preferred way of working. + +However, the new code path is only present in ARCH_BCM2835 +builds, which I have taken to be a way of testing the waters +rather than making the change across the board; I can't see +any technical reason why it wouldn't be enabled for MACH_BCM270X +builds. So this patch standardises on the ARCH_BCM2835 code, +removing the old code paths. --- drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 1702 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 1713 insertions(+) + drivers/mmc/host/bcm2835-mmc.c | 28 +- + drivers/mmc/host/bcm2835-sdhost.c | 1912 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 1927 insertions(+), 24 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-sdhost.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 0ef7417..1af139a 100644 +index 6d5b8bb..3b9febc 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER @@ -77071,7 +77862,7 @@ index 0ef7417..1af139a 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index f1ee1f7..8c656a5 100644 +index 68e64ab..edf2855 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -77082,12 +77873,111 @@ index f1ee1f7..8c656a5 100644 obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c +index 164bfad..0f89e57 100644 +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -684,12 +684,10 @@ void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd + } + + timeout = jiffies; +-#ifdef CONFIG_ARCH_BCM2835 + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else +-#endif +- timeout += 10 * HZ; ++ timeout += 10 * HZ; + mod_timer(&host->timer, timeout); + + host->cmd = cmd; +@@ -984,9 +982,6 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + struct bcm2835_host *host = dev_id; + u32 intmask, mask, unexpected = 0; + int max_loops = 16; +-#ifndef CONFIG_ARCH_BCM2835 +- int cardint = 0; +-#endif + + spin_lock(&host->lock); + +@@ -1015,13 +1010,9 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + mmc_hostname(host->mmc)); + + if (intmask & SDHCI_INT_CARD_INT) { +-#ifndef CONFIG_ARCH_BCM2835 +- cardint = 1; +-#else + bcm2835_mmc_enable_sdio_irq_nolock(host, false); + host->thread_isr |= SDHCI_INT_CARD_INT; + result = IRQ_WAKE_THREAD; +-#endif + } + + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | +@@ -1048,15 +1039,9 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + bcm2835_mmc_dumpregs(host); + } + +-#ifndef CONFIG_ARCH_BCM2835 +- if (cardint) +- mmc_signal_sdio_irq(host->mmc); +-#endif +- + return result; + } + +-#ifdef CONFIG_ARCH_BCM2835 + static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) + { + struct bcm2835_host *host = dev_id; +@@ -1079,7 +1064,6 @@ static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) + + return isr ? IRQ_HANDLED : IRQ_NONE; + } +-#endif + + + +@@ -1323,14 +1307,15 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) + + /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ + host->timeout_clk = mmc->f_max / 1000; +-#ifdef CONFIG_ARCH_BCM2835 + mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; +-#endif ++ + /* host controller capabilities */ + mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | + MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; + ++ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; ++ + host->flags = SDHCI_AUTO_CMD23; + + dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); +@@ -1378,14 +1363,9 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) + init_waitqueue_head(&host->buf_ready_int); + + bcm2835_mmc_init(host, 0); +-#ifndef CONFIG_ARCH_BCM2835 +- ret = devm_request_irq(dev, host->irq, bcm2835_mmc_irq, 0, +- mmc_hostname(mmc), host); +-#else + ret = devm_request_threaded_irq(dev, host->irq, bcm2835_mmc_irq, + bcm2835_mmc_thread_irq, IRQF_SHARED, + mmc_hostname(mmc), host); +-#endif + if (ret) { + dev_err(dev, "Failed to request IRQ %d: %d\n", host->irq, ret); + goto untasklet; diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c new file mode 100644 -index 0000000..eef8a24 +index 0000000..0623392 --- /dev/null +++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -0,0 +1,1702 @@ +@@ -0,0 +1,1912 @@ +/* + * BCM2835 SD host driver. + * @@ -77180,9 +78070,8 @@ index 0000000..eef8a24 +/* Reserved */ +#define SDHSTS_DATA_FLAG 0x01 + -+#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) ++#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) +#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) -+/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ + +#define SDHCFG_BUSY_IRPT_EN (1<<10) +#define SDHCFG_BLOCK_IRPT_EN (1<<8) @@ -77201,16 +78090,7 @@ index 0000000..eef8a24 +#define SDEDM_READ_THRESHOLD_SHIFT 14 +#define SDEDM_THRESHOLD_MASK 0x1f + -+/* the inclusive limit in bytes under which PIO will be used instead of DMA */ -+#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#else -+#define PIO_DMA_BARRIER 0 -+#endif -+ -+#define MIN_FREQ 400000 -+#define TIMEOUT_VAL 0xE -+#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) ++#define MHZ 1000000 + +#ifndef BCM2708_PERI_BASE + #define BCM2708_PERI_BASE 0x20000000 @@ -77228,19 +78108,20 @@ index 0000000..eef8a24 + + struct mmc_host *mmc; + -+ u32 timeout; ++ u32 pio_timeout; /* In jiffies */ + + int clock; /* Current clock speed */ + + bool slow_card; /* Force 11-bit divisor */ + + unsigned int max_clk; /* Max possible freq */ -+ unsigned int timeout_clk; /* Timeout freq (KHz) */ + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + + struct timer_list timer; /* Timer for timeouts */ + ++ struct timer_list pio_timer; /* PIO error detection timer */ ++ + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + @@ -77260,6 +78141,8 @@ index 0000000..eef8a24 + + unsigned int use_busy:1; /* Wait for busy interrupt */ + ++ unsigned int debug:1; /* Enable debug output */ ++ + u32 thread_isr; + + /*DMA part*/ @@ -77275,7 +78158,8 @@ index 0000000..eef8a24 + struct timeval stop_time; /* when the last stop was issued */ + u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ + u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -+ u32 max_overclock; /* Highest reported */ ++ u32 overclock; /* Current frequency if overclocked, else zero */ ++ u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ +}; + + @@ -77294,41 +78178,79 @@ index 0000000..eef8a24 + return readl_relaxed(host->ioaddr + reg); +} + ++static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, ++ struct mmc_command *cmd, ++ const char *label) ++{ ++ if (cmd) ++ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", ++ mmc_hostname(host->mmc), ++ (cmd == host->cmd) ? '>' : ' ', ++ label, cmd->opcode, cmd->arg, cmd->flags, ++ cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], ++ cmd->error); ++} ++ +static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) +{ -+ pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", ++ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); ++ if (host->mrq->data) ++ pr_err("%s: data blocks %x blksz %x - err %d\n", ++ mmc_hostname(host->mmc), ++ host->mrq->data->blocks, ++ host->mrq->data->blksz, ++ host->mrq->data->error); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); ++ ++ pr_info("%s: =========== REGISTER DUMP ===========\n", + mmc_hostname(host->mmc)); + -+ pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", ++ pr_info("%s: SDCMD 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCMD)); -+ pr_info(DRIVER_NAME ": SDARG 0x%08x\n", ++ pr_info("%s: SDARG 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDARG)); -+ pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", ++ pr_info("%s: SDTOUT 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDTOUT)); -+ pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", ++ pr_info("%s: SDCDIV 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCDIV)); -+ pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", ++ pr_info("%s: SDRSP0 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP0)); -+ pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", ++ pr_info("%s: SDRSP1 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP1)); -+ pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", ++ pr_info("%s: SDRSP2 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP2)); -+ pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", ++ pr_info("%s: SDRSP3 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP3)); -+ pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", ++ pr_info("%s: SDHSTS 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHSTS)); -+ pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", ++ pr_info("%s: SDVDD 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDVDD)); -+ pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", ++ pr_info("%s: SDEDM 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDEDM)); -+ pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", ++ pr_info("%s: SDHCFG 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHCFG)); -+ pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", ++ pr_info("%s: SDHBCT 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBCT)); -+ pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", ++ pr_info("%s: SDHBLC 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBLC)); + -+ pr_debug(DRIVER_NAME ": ===========================================\n"); ++ pr_info("%s: ===========================================\n", ++ mmc_hostname(host->mmc)); +} + + @@ -77338,12 +78260,10 @@ index 0000000..eef8a24 +} + + -+static void bcm2835_sdhost_reset(struct bcm2835_host *host) ++static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) +{ + u32 temp; + -+ pr_debug("bcm2835_sdhost_reset\n"); -+ + bcm2835_sdhost_set_power(host, false); + + bcm2835_sdhost_write(host, 0, SDCMD); @@ -77371,6 +78291,20 @@ index 0000000..eef8a24 + mmiowb(); +} + ++ ++static void bcm2835_sdhost_reset(struct mmc_host *mmc) ++{ ++ struct bcm2835_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ if (host->debug) ++ pr_info("%s: reset\n", mmc_hostname(mmc)); ++ spin_lock_irqsave(&host->lock, flags); ++ ++ bcm2835_sdhost_reset_internal(host); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ +static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + +static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) @@ -77380,7 +78314,7 @@ index 0000000..eef8a24 + /* Set interrupt enables */ + host->hcfg = SDHCFG_BUSY_IRPT_EN; + -+ bcm2835_sdhost_reset(host); ++ bcm2835_sdhost_reset_internal(host); + + if (soft) { + /* force clock reconfiguration */ @@ -77510,6 +78444,29 @@ index 0000000..eef8a24 + spin_unlock_irqrestore(&host->lock, flags); +} + ++static bool data_transfer_wait(struct bcm2835_host *host) ++{ ++ unsigned long timeout = 1000000; ++ while (timeout) ++ { ++ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (sdhsts & SDHSTS_DATA_FLAG) { ++ bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); ++ break; ++ } ++ timeout--; ++ } ++ if (timeout == 0) { ++ pr_err("%s: Data %s timeout\n", ++ mmc_hostname(host->mmc), ++ (host->data->flags & MMC_DATA_READ) ? "read" : "write"); ++ bcm2835_sdhost_dumpregs(host); ++ host->data->error = -ETIMEDOUT; ++ return false; ++ } ++ return true; ++} ++ +static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; @@ -77533,35 +78490,15 @@ index 0000000..eef8a24 + buf = (u32 *)host->sg_miter.addr; + + while (len) { -+ while (1) { -+ u32 hsts; -+ hsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (hsts & SDHSTS_DATA_FLAG) -+ break; -+ -+ if (hsts & SDHSTS_ERROR_MASK) { -+ pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", -+ mmc_hostname(host->mmc), -+ hsts, -+ bcm2835_sdhost_read(host, SDHBCT), -+ blksize + len); -+ if (hsts & SDHSTS_REW_TIME_OUT) -+ host->data->error = -ETIMEDOUT; -+ else if (hsts & (SDHSTS_CRC16_ERROR || -+ SDHSTS_CRC7_ERROR)) -+ host->data->error = -EILSEQ; -+ else { -+ pr_err("%s: unexpected data error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ } -+ } -+ } ++ if (!data_transfer_wait(host)) ++ break; + + *(buf++) = bcm2835_sdhost_read(host, SDDATA); + len -= 4; + } ++ ++ if (host->data->error) ++ break; + } + + sg_miter_stop(&host->sg_miter); @@ -77592,11 +78529,15 @@ index 0000000..eef8a24 + buf = host->sg_miter.addr; + + while (len) { -+ while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) -+ continue; ++ if (!data_transfer_wait(host)) ++ break; ++ + bcm2835_sdhost_write(host, *(buf++), SDDATA); + len -= 4; + } ++ ++ if (host->data->error) ++ break; + } + + sg_miter_stop(&host->sg_miter); @@ -77607,12 +78548,37 @@ index 0000000..eef8a24 + +static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) +{ ++ u32 sdhsts; ++ bool is_read; + BUG_ON(!host->data); + -+ if (host->data->flags & MMC_DATA_READ) ++ is_read = (host->data->flags & MMC_DATA_READ) != 0; ++ if (is_read) + bcm2835_sdhost_read_block_pio(host); + else + bcm2835_sdhost_write_block_pio(host); ++ ++ sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (sdhsts & (SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | ++ SDHSTS_FIFO_ERROR)) { ++ pr_err("%s: %s transfer error - HSTS %x\n", ++ mmc_hostname(host->mmc), ++ is_read ? "read" : "write", ++ sdhsts); ++ host->data->error = -EILSEQ; ++ } else if ((sdhsts & (SDHSTS_CMD_TIME_OUT | ++ SDHSTS_REW_TIME_OUT))) { ++ pr_err("%s: %s timeout error - HSTS %x\n", ++ mmc_hostname(host->mmc), ++ is_read ? "read" : "write", ++ sdhsts); ++ host->data->error = -ETIMEDOUT; ++ } else if (!is_read && !host->data->error) { ++ /* Start a timer in case a transfer error occurs because ++ there is no error interrupt */ ++ mod_timer(&host->pio_timer, jiffies + host->pio_timeout); ++ } +} + + @@ -77697,6 +78663,7 @@ index 0000000..eef8a24 + host->flush_fifo = 0; + host->data->bytes_xfered = 0; + ++ host->use_dma = host->have_dma && (data->blocks > host->pio_limit); + if (!host->use_dma) { + int flags; + @@ -77709,13 +78676,10 @@ index 0000000..eef8a24 + host->blocks = data->blocks; + } + -+ host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; -+ + bcm2835_sdhost_set_transfer_irqs(host); + + bcm2835_sdhost_write(host, data->blksz, SDHBCT); -+ if (host->use_dma) -+ bcm2835_sdhost_write(host, data->blocks, SDHBLC); ++ bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); + + BUG_ON(!host->data); +} @@ -77723,27 +78687,31 @@ index 0000000..eef8a24 + +void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) +{ -+ u32 sdcmd; ++ u32 sdcmd, sdhsts; + unsigned long timeout; ++ int delay; + + WARN_ON(host->cmd); + -+ if (1) { -+ pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", -+ cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); -+ if (cmd->data) -+ pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ } ++ if (cmd->data) ++ pr_debug("%s: send_command %d 0x%x " ++ "(flags 0x%x) - %s %d*%d\n", ++ mmc_hostname(host->mmc), ++ cmd->opcode, cmd->arg, cmd->flags, ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ else ++ pr_debug("%s: send_command %d 0x%x (flags 0x%x)\n", ++ mmc_hostname(host->mmc), ++ cmd->opcode, cmd->arg, cmd->flags); + -+ /* Wait max 10 ms */ -+ timeout = 1000; ++ /* Wait max 100 ms */ ++ timeout = 10000; + + while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { + if (timeout == 0) { -+ pr_err("%s: Previous command never completed.\n", ++ pr_err("%s: previous command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + cmd->error = -EIO; @@ -77754,28 +78722,34 @@ index 0000000..eef8a24 + udelay(10); + } + -+ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { -+ host->max_delay = (1000-timeout)/100; -+ pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); ++ delay = (10000 - timeout)/100; ++ if (delay > host->max_delay) { ++ host->max_delay = delay; ++ pr_warning("%s: controller hung for %d ms\n", ++ mmc_hostname(host->mmc), ++ host->max_delay); + } + + timeout = jiffies; -+#ifdef CONFIG_ARCH_BCM2835 + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else -+#endif -+ timeout += 10 * HZ; ++ timeout += 10 * HZ; + mod_timer(&host->timer, timeout); + + host->cmd = cmd; + ++ /* Clear any error flags */ ++ sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (sdhsts & SDHSTS_ERROR_MASK) ++ bcm2835_sdhost_write(host, sdhsts, SDHSTS); ++ + bcm2835_sdhost_prepare_data(host, cmd); + + bcm2835_sdhost_write(host, cmd->arg, SDARG); + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { -+ pr_err("%s: Unsupported response type!\n", ++ pr_err("%s: unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); @@ -77873,13 +78847,6 @@ index 0000000..eef8a24 + pr_debug("transfer_complete(error %d, stop %d)\n", + data->error, data->stop ? 1 : 0); + -+ if (data->error) -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ bcm2835_sdhost_reset(host); -+ + /* + * Need to send CMD12 if - + * a) open-ended multiblock transfer (no CMD23) @@ -77902,7 +78869,7 @@ index 0000000..eef8a24 +static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) +{ + u32 sdcmd; -+ int timeout = 1000; ++ unsigned long timeout; +#ifdef DEBUG + struct timeval before, after; + int timediff = 0; @@ -77915,6 +78882,8 @@ index 0000000..eef8a24 +#ifdef DEBUG + do_gettimeofday(&before); +#endif ++ /* Wait max 100 ms */ ++ timeout = 10000; + for (sdcmd = bcm2835_sdhost_read(host, SDCMD); + (sdcmd & SDCMD_NEW_FLAG) && timeout; + timeout--) { @@ -77935,7 +78904,7 @@ index 0000000..eef8a24 +#endif + + if (timeout == 0) { -+ pr_err("%s: Command never completed.\n", ++ pr_err("%s: command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + host->cmd->error = -EIO; @@ -77965,21 +78934,37 @@ index 0000000..eef8a24 + { + u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); + -+ pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -+ mmc_hostname(host->mmc), sdcmd, sdhsts, -+ bcm2835_sdhost_read(host, SDEDM)); ++ if (host->debug) ++ pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", ++ mmc_hostname(host->mmc), sdcmd, sdhsts, ++ bcm2835_sdhost_read(host, SDEDM)); + -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ { -+ pr_err("%s: unexpected command error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; ++ if ((sdhsts & SDHSTS_CRC7_ERROR) && ++ (host->cmd->opcode == 1)) { ++ if (host->debug) ++ pr_info("%s: ignoring CRC7 error for CMD1\n", ++ mmc_hostname(host->mmc)); ++ } else { ++ if (sdhsts & SDHSTS_CMD_TIME_OUT) { ++ switch (host->cmd->opcode) { ++ case 5: case 52: case 53: ++ /* Don't warn about SDIO commands */ ++ break; ++ default: ++ pr_err("%s: command timeout\n", ++ mmc_hostname(host->mmc)); ++ break; ++ } ++ host->cmd->error = -ETIMEDOUT; ++ } else { ++ pr_err("%s: unexpected command error\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ } ++ tasklet_schedule(&host->finish_tasklet); ++ return; + } -+ tasklet_schedule(&host->finish_tasklet); -+ return; + } + + if (host->cmd->flags & MMC_RSP_PRESENT) { @@ -77987,11 +78972,13 @@ index 0000000..eef8a24 + int i; + for (i = 0; i < 4; i++) + host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); -+ pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", ++ pr_debug("%s: finish_command %08x %08x %08x %08x\n", ++ mmc_hostname(host->mmc), + host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); + } else { + host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); -+ pr_debug("bcm2835_sdhost_finish_command: %08x\n", ++ pr_debug("%s: finish_command %08x\n", ++ mmc_hostname(host->mmc), + host->cmd->resp[0]); + } + } @@ -78022,7 +79009,7 @@ index 0000000..eef8a24 + } +} + -+static void bcm2835_sdhost_timeout_timer(unsigned long data) ++static void bcm2835_sdhost_timeout(unsigned long data) +{ + struct bcm2835_host *host; + unsigned long flags; @@ -78032,7 +79019,7 @@ index 0000000..eef8a24 + spin_lock_irqsave(&host->lock, flags); + + if (host->mrq) { -+ pr_err("%s: Timeout waiting for hardware interrupt.\n", ++ pr_err("%s: timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + @@ -78054,6 +79041,41 @@ index 0000000..eef8a24 + spin_unlock_irqrestore(&host->lock, flags); +} + ++static void bcm2835_sdhost_pio_timeout(unsigned long data) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ host = (struct bcm2835_host *)data; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host->data) { ++ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ ++ if (sdhsts & SDHSTS_REW_TIME_OUT) { ++ pr_err("%s: transfer timeout\n", ++ mmc_hostname(host->mmc)); ++ if (host->debug) ++ bcm2835_sdhost_dumpregs(host); ++ } else { ++ pr_err("%s: unexpected transfer timeout\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ } ++ ++ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, ++ SDHSTS); ++ ++ host->data->error = -ETIMEDOUT; ++ ++ bcm2835_sdhost_finish_data(host); ++ } ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ +static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) +{ + if (enable) @@ -78069,7 +79091,7 @@ index 0000000..eef8a24 + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + -+ pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); ++ pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); + spin_lock_irqsave(&host->lock, flags); + bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); + spin_unlock_irqrestore(&host->lock, flags); @@ -78077,11 +79099,12 @@ index 0000000..eef8a24 + +static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) +{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | ++ SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | ++ SDHSTS_FIFO_ERROR); + + if (!host->cmd) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " ++ pr_err("%s: got command busy interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); @@ -78089,7 +79112,7 @@ index 0000000..eef8a24 + } + + if (!host->use_busy) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " ++ pr_err("%s: got command busy interrupt 0x%08x even " + "though not expecting one.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); @@ -78097,14 +79120,28 @@ index 0000000..eef8a24 + } + host->use_busy = 0; + -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->cmd->error = -EILSEQ; ++ if (intmask & SDHSTS_ERROR_MASK) ++ { ++ pr_err("sdhost_busy_irq: intmask %x, data %p\n", intmask, host->mrq->data); ++ if (intmask & SDHSTS_CRC7_ERROR) ++ host->cmd->error = -EILSEQ; ++ else if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR)) { ++ if (host->mrq->data) ++ host->mrq->data->error = -EILSEQ; ++ else ++ host->cmd->error = -EILSEQ; ++ } else if (intmask & SDHSTS_REW_TIME_OUT) { ++ if (host->mrq->data) ++ host->mrq->data->error = -ETIMEDOUT; ++ else ++ host->cmd->error = -ETIMEDOUT; ++ } else if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; + -+ if (host->cmd->error) ++ bcm2835_sdhost_dumpregs(host); + tasklet_schedule(&host->finish_tasklet); ++ } + else + bcm2835_sdhost_finish_command(host); + @@ -78113,8 +79150,9 @@ index 0000000..eef8a24 + +static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) +{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ const u32 handled = (SDHSTS_REW_TIME_OUT | ++ SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR); + + /* There are no dedicated data/space available interrupt + status bits, so it is necessary to use the single shared @@ -78124,13 +79162,19 @@ index 0000000..eef8a24 + if (!host->data) + return 0; + -+ // XXX FIFO_ERROR -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR | ++ SDHSTS_REW_TIME_OUT)) { ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR)) ++ host->data->error = -EILSEQ; ++ else ++ host->data->error = -ETIMEDOUT; ++ ++ bcm2835_sdhost_dumpregs(host); ++ tasklet_schedule(&host->finish_tasklet); ++ return handled; ++ } + + /* Use the block interrupt for writes after the first block */ + if (host->data->flags & MMC_DATA_WRITE) { @@ -78157,31 +79201,48 @@ index 0000000..eef8a24 +{ + struct dma_chan *dma_chan; + u32 dir_data; -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ const u32 handled = (SDHSTS_REW_TIME_OUT | ++ SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR); + + if (!host->data) { -+ pr_err("%s: Got block interrupt 0x%08x even " ++ pr_err("%s: got block interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); + return handled; + } + -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR | ++ SDHSTS_REW_TIME_OUT)) { ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR)) ++ host->data->error = -EILSEQ; ++ else ++ host->data->error = -ETIMEDOUT; ++ ++ if (host->debug) ++ bcm2835_sdhost_dumpregs(host); ++ tasklet_schedule(&host->finish_tasklet); ++ return handled; ++ } + + if (!host->use_dma) { + BUG_ON(!host->blocks); + host->blocks--; -+ if ((host->blocks == 0) || host->data->error) ++ if ((host->blocks == 0) || host->data->error) { ++ /* Cancel the timer */ ++ del_timer(&host->pio_timer); ++ + bcm2835_sdhost_finish_data(host); -+ else ++ } else { + bcm2835_sdhost_transfer_pio(host); ++ ++ /* Reset the timer */ ++ mod_timer(&host->pio_timer, ++ jiffies + host->pio_timeout); ++ } + } else if (host->data->flags & MMC_DATA_WRITE) { + dma_chan = host->dma_chan_tx; + dir_data = DMA_TO_DEVICE; @@ -78202,9 +79263,7 @@ index 0000000..eef8a24 + struct bcm2835_host *host = dev_id; + u32 unexpected = 0, early = 0; + int loops = 0; -+#ifndef CONFIG_ARCH_BCM2835 -+ int cardint = 0; -+#endif ++ + spin_lock(&host->lock); + + for (loops = 0; loops < 1; loops++) { @@ -78215,7 +79274,7 @@ index 0000000..eef8a24 + SDHSTS_BLOCK_IRPT | + SDHSTS_SDIO_IRPT | + SDHSTS_DATA_FLAG); -+ if ((handled == SDHSTS_DATA_FLAG) && // XXX ++ if ((handled == SDHSTS_DATA_FLAG) && + (loops == 0) && !host->data) { + pr_err("%s: sdhost_irq data interrupt 0x%08x even " + "though no data operation was in progress.\n", @@ -78250,13 +79309,9 @@ index 0000000..eef8a24 + handled |= bcm2835_sdhost_block_irq(host, intmask); + + if (intmask & SDHSTS_SDIO_IRPT) { -+#ifndef CONFIG_ARCH_BCM2835 -+ cardint = 1; -+#else + bcm2835_sdhost_enable_sdio_irq_nolock(host, false); + host->thread_isr |= SDHSTS_SDIO_IRPT; + result = IRQ_WAKE_THREAD; -+#endif + } + + unexpected |= (intmask & ~handled); @@ -78267,23 +79322,18 @@ index 0000000..eef8a24 + spin_unlock(&host->lock); + + if (early) -+ pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); ++ pr_debug("%s: early %x (loops %d)\n", ++ mmc_hostname(host->mmc), early, loops); + + if (unexpected) { -+ pr_err("%s: Unexpected interrupt 0x%08x.\n", ++ pr_err("%s: unexpected interrupt 0x%08x.\n", + mmc_hostname(host->mmc), unexpected); + bcm2835_sdhost_dumpregs(host); + } + -+#ifndef CONFIG_ARCH_BCM2835 -+ if (cardint) -+ mmc_signal_sdio_irq(host->mmc); -+#endif -+ + return result; +} + -+#ifdef CONFIG_ARCH_BCM2835 +static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) +{ + struct bcm2835_host *host = dev_id; @@ -78308,7 +79358,6 @@ index 0000000..eef8a24 + + return isr ? IRQ_HANDLED : IRQ_NONE; +} -+#endif + + + @@ -78317,8 +79366,13 @@ index 0000000..eef8a24 + int div = 0; /* Initialized for compiler warning */ + unsigned int input_clock = clock; + -+ if (host->overclock_50 && (clock == 50000000)) -+ clock = host->overclock_50 * 1000000 + 999999; ++ if (host->debug) ++ pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); ++ ++ if ((host->overclock_50 > 50) && ++ (clock == 50*MHZ)) { ++ clock = host->overclock_50 * MHZ + (MHZ - 1); ++ } + + /* The SDCDIV register has 11 bits, and holds (div - 2). + But in data mode the max is 50MHz wihout a minimum, and only the @@ -78365,17 +79419,35 @@ index 0000000..eef8a24 + clock = host->max_clk / (div + 2); + host->mmc->actual_clock = clock; + -+ if ((clock > input_clock) && (clock > host->max_overclock)) { -+ pr_warn("%s: Overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); -+ host->max_overclock = clock; ++ if (clock > input_clock) { ++ /* Save the closest value, to make it easier ++ to reduce in the event of error */ ++ host->overclock_50 = (clock/MHZ); ++ ++ if (clock != host->overclock) { ++ pr_warn("%s: overclocking to %dHz\n", ++ mmc_hostname(host->mmc), clock); ++ host->overclock = clock; ++ } ++ } ++ else if (host->overclock) ++ { ++ host->overclock = 0; ++ if (clock == 50 * MHZ) ++ pr_warn("%s: cancelling overclock\n", ++ mmc_hostname(host->mmc)); + } + + host->cdiv = div; + bcm2835_sdhost_write(host, host->cdiv, SDCDIV); + -+ pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); ++ /* Set the timeout to 500ms */ ++ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); ++ ++ if (host->debug) ++ pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", ++ mmc_hostname(host->mmc), input_clock, ++ host->max_clk, host->cdiv, host->mmc->actual_clock); +} + +static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) @@ -78383,29 +79455,40 @@ index 0000000..eef8a24 + struct bcm2835_host *host; + unsigned long flags; + -+ if (1) { ++ host = mmc_priv(mmc); ++ ++ if (host->debug) { + struct mmc_command *cmd = mrq->cmd; -+ const char *src = "cmd"; + BUG_ON(!cmd); -+ pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", -+ src, cmd->opcode, cmd->arg, cmd->flags); + if (cmd->data) -+ pr_debug("bcm2835_sdhost_request: %s %d*%d\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); ++ pr_info("%s: cmd %d 0x%x (flags 0x%x) - %s %d*%d\n", ++ mmc_hostname(mmc), ++ cmd->opcode, cmd->arg, cmd->flags, ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ else ++ pr_info("%s: cmd %d 0x%x (flags 0x%x)\n", ++ mmc_hostname(mmc), ++ cmd->opcode, cmd->arg, cmd->flags); + } + ++ /* Reset the error statuses in case this is a retry */ ++ if (mrq->cmd) ++ mrq->cmd->error = 0; ++ if (mrq->data) ++ mrq->data->error = 0; ++ if (mrq->stop) ++ mrq->stop->error = 0; ++ + if (mrq->data && !is_power_of_2(mrq->data->blksz)) { -+ pr_err("%s: Unsupported block size (%d bytes)\n", ++ pr_err("%s: unsupported block size (%d bytes)\n", + mmc_hostname(mmc), mrq->data->blksz); + mrq->cmd->error = -EINVAL; + mmc_request_done(mmc, mrq); + return; + } + -+ host = mmc_priv(mmc); -+ + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); @@ -78435,9 +79518,12 @@ index 0000000..eef8a24 + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + -+ pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); ++ if (host->debug) ++ pr_info("%s: ios clock %d, pwr %d, bus_width %d, " ++ "timing %d, vdd %d, drv_type %d\n", ++ mmc_hostname(mmc), ++ ios->clock, ios->power_mode, ios->bus_width, ++ ios->timing, ios->signal_voltage, ios->drv_type); + + spin_lock_irqsave(&host->lock, flags); + @@ -78486,6 +79572,7 @@ index 0000000..eef8a24 + .request = bcm2835_sdhost_request, + .set_ios = bcm2835_sdhost_set_ios, + .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, ++ .hw_reset = bcm2835_sdhost_reset, + .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, +}; + @@ -78513,15 +79600,19 @@ index 0000000..eef8a24 + + mrq = host->mrq; + -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ if (((mrq->cmd && mrq->cmd->error) || -+ (mrq->data && (mrq->data->error || -+ (mrq->data->stop && mrq->data->stop->error))))) { -+ -+ bcm2835_sdhost_reset(host); ++ /* Drop the overclock after any data corruption, or after any ++ error overclocked */ ++ if (host->overclock) { ++ if ((mrq->cmd && mrq->cmd->error) || ++ (mrq->data && mrq->data->error) || ++ (mrq->stop && mrq->stop->error)) { ++ host->overclock_50--; ++ pr_warn("%s: reducing overclock due to errors\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_set_clock(host,50*MHZ); ++ mrq->cmd->error = -EILSEQ; ++ mrq->cmd->retries = 1; ++ } + } + + host->mrq = NULL; @@ -78540,35 +79631,37 @@ index 0000000..eef8a24 +{ + struct mmc_host *mmc; + struct dma_slave_config cfg; ++ char pio_limit_string[20]; + int ret; + + mmc = host->mmc; + -+ bcm2835_sdhost_reset(host); ++ bcm2835_sdhost_reset_internal(host); + + mmc->f_max = host->max_clk; + mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; + -+ /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ -+ host->timeout_clk = mmc->f_max / 1000; -+#ifdef CONFIG_ARCH_BCM2835 -+ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; -+#endif ++ mmc->max_busy_timeout = (~(unsigned int)0)/(mmc->f_max/1000); ++ ++ pr_debug("f_max %d, f_min %d, max_busy_timeout %d\n", ++ mmc->f_max, mmc->f_min, mmc->max_busy_timeout); ++ + /* host controller capabilities */ + mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | + MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -+ MMC_CAP_NEEDS_POLL | ++ MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | + (ALLOW_CMD23 * MMC_CAP_CMD23); + + spin_lock_init(&host->lock); + + if (host->allow_dma) { -+ if (!host->dma_chan_tx || !host->dma_chan_rx || -+ IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { -+ pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); ++ if (IS_ERR_OR_NULL(host->dma_chan_tx) || ++ IS_ERR_OR_NULL(host->dma_chan_rx)) { ++ pr_err("%s: unable to initialise DMA channels. " ++ "Falling back to PIO\n", ++ mmc_hostname(mmc)); + host->have_dma = false; + } else { -+ pr_info("DMA channels allocated for the SDHost driver"); + host->have_dma = true; + + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -78586,7 +79679,6 @@ index 0000000..eef8a24 + ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); + } + } else { -+ pr_info("Forcing PIO mode\n"); + host->have_dma = false; + } + @@ -78602,18 +79694,18 @@ index 0000000..eef8a24 + tasklet_init(&host->finish_tasklet, + bcm2835_sdhost_tasklet_finish, (unsigned long)host); + -+ setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); ++ setup_timer(&host->timer, bcm2835_sdhost_timeout, ++ (unsigned long)host); ++ ++ setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, ++ (unsigned long)host); + + bcm2835_sdhost_init(host, 0); -+#ifndef CONFIG_ARCH_BCM2835 -+ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -+ mmc_hostname(mmc), host); -+#else -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, ++ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, ++ bcm2835_sdhost_thread_irq, + IRQF_SHARED, mmc_hostname(mmc), host); -+#endif + if (ret) { -+ pr_err("%s: Failed to request IRQ %d: %d\n", ++ pr_err("%s: failed to request IRQ %d: %d\n", + mmc_hostname(mmc), host->irq, ret); + goto untasklet; + } @@ -78621,10 +79713,13 @@ index 0000000..eef8a24 + mmiowb(); + mmc_add_host(mmc); + -+ pr_info("Load BCM2835 SDHost driver\n"); -+ if (host->delay_after_stop) -+ pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", -+ host->delay_after_stop); ++ pio_limit_string[0] = '\0'; ++ if (host->have_dma && (host->pio_limit > 0)) ++ sprintf(pio_limit_string, " (>%d)", host->pio_limit); ++ pr_info("%s: %s loaded - DMA %s%s\n", ++ mmc_hostname(mmc), DRIVER_NAME, ++ host->have_dma ? "enabled" : "disabled", ++ pio_limit_string); + + return 0; + @@ -78652,7 +79747,8 @@ index 0000000..eef8a24 + mmc->ops = &bcm2835_sdhost_ops; + host = mmc_priv(mmc); + host->mmc = mmc; -+ host->timeout = msecs_to_jiffies(1000); ++ host->pio_timeout = msecs_to_jiffies(500); ++ host->max_delay = 1; /* Warn if over 1ms */ + spin_lock_init(&host->lock); + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -78678,8 +79774,12 @@ index 0000000..eef8a24 + of_property_read_u32(node, + "brcm,overclock-50", + &host->overclock_50); ++ of_property_read_u32(node, ++ "brcm,pio-limit", ++ &host->pio_limit); + host->allow_dma = ALLOW_DMA && + !of_property_read_bool(node, "brcm,force-pio"); ++ host->debug = of_property_read_bool(node, "brcm,debug"); + } + + if (host->allow_dma) { @@ -78791,10 +79891,10 @@ index 0000000..eef8a24 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Phil Elwell"); -From a48f15d3cdee3004a03d04e296247625130dcbf7 Mon Sep 17 00:00:00 2001 +From a18b06512f88e732fb152b3e0af5e75312600753 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 010/204] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 020/113] cma: Add vc_cma driver to enable use of CMA Signed-off-by: popcornmix @@ -78815,23 +79915,23 @@ vc_cma: Make the vc_cma area the default contiguous DMA area create mode 100644 include/linux/broadcom/vc_cma.h diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index a4af8221..59e4d63 100644 +index a043107..2ba2d82 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig -@@ -590,6 +590,8 @@ config DEVPORT +@@ -4,6 +4,8 @@ - source "drivers/s390/char/Kconfig" + menu "Character devices" +source "drivers/char/broadcom/Kconfig" + - config MSM_SMD_PKT - bool "Enable device interface for some SMD packet ports" - default n + source "drivers/tty/Kconfig" + + config DEVMEM diff --git a/drivers/char/Makefile b/drivers/char/Makefile -index d06cde26..a9f9daf 100644 +index d8a7579..9d8662e 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile -@@ -62,3 +62,4 @@ js-rtc-y = rtc.o +@@ -60,3 +60,4 @@ js-rtc-y = rtc.o obj-$(CONFIG_TILE_SROM) += tile-srom.o obj-$(CONFIG_XILLYBUS) += xillybus/ @@ -80119,10 +81219,10 @@ index 0000000..5325832 + +#endif /* VC_CMA_H */ -From ebd29c2fcd995ebe287b4d9e771bd1f6730e6e13 Mon Sep 17 00:00:00 2001 +From bf392eddd6a629189c74d00058aafbe3ec2c3a9e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 011/204] bcm2708: alsa sound driver +Subject: [PATCH 021/113] bcm2708: alsa sound driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -80179,10 +81279,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 sound/arm/vc_vchi_audioserv_defs.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6257407..df32241 100644 +index 4ea857c..7557854 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -429,6 +429,57 @@ struct platform_device bcm2835_emmc_device = { +@@ -418,6 +418,57 @@ struct platform_device bcm2835_emmc_device = { }; #endif /* CONFIG_MMC_BCM2835 */ @@ -80240,7 +81340,7 @@ index 6257407..df32241 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -571,6 +622,8 @@ void __init bcm2708_init(void) +@@ -559,6 +610,8 @@ void __init bcm2708_init(void) #endif bcm2708_init_led(); bcm2708_init_uart1(); @@ -80250,10 +81350,10 @@ index 6257407..df32241 100644 if (!use_dt) { for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 07750ed..62c95cb 100644 +index b762819..25c42b6 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -449,6 +449,57 @@ struct platform_device bcm2835_emmc_device = { +@@ -434,6 +434,57 @@ struct platform_device bcm2835_emmc_device = { }; #endif /* CONFIG_MMC_BCM2835 */ @@ -80311,7 +81411,7 @@ index 07750ed..62c95cb 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -591,6 +642,8 @@ void __init bcm2709_init(void) +@@ -576,6 +627,8 @@ void __init bcm2709_init(void) #endif bcm2709_init_led(); bcm2709_init_uart1(); @@ -82964,10 +84064,67 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From 4978dc22bb85d1c218085aa253224bdaea6f89fc Mon Sep 17 00:00:00 2001 +From 2d9dceb6822a27c0da5c7198df976ae9f0043f0b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 27 May 2015 17:22:15 +0100 +Subject: [PATCH 022/113] bcm2835-audio: Create the platform device if the DT + node is disabled + +For backwards compatibility, allow the built-in ALSA driver to be enabled +either by loading the module from /etc/modules or by enabling the "/audio" +node in DT. +--- + arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- + arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- + 2 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 7557854..296492a 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -610,8 +610,14 @@ void __init bcm2708_init(void) + #endif + bcm2708_init_led(); + bcm2708_init_uart1(); +- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) +- bcm_register_device_dt(&bcm2708_alsa_devices[i]); ++ ++ /* Only create the platform devices for the ALSA driver in the ++ absence of an enabled "audio" DT node */ ++ if (!use_dt || ++ !of_device_is_available(of_find_node_by_path("/audio"))) { ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device(&bcm2708_alsa_devices[i]); ++ } + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 25c42b6..46a274e 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -627,8 +627,14 @@ void __init bcm2709_init(void) + #endif + bcm2709_init_led(); + bcm2709_init_uart1(); +- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) +- bcm_register_device_dt(&bcm2708_alsa_devices[i]); ++ ++ /* Only create the platform devices for the ALSA driver in the ++ absence of an enabled "audio" DT node */ ++ if (!use_dt || ++ !of_device_is_available(of_find_node_by_path("/audio"))) { ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device(&bcm2708_alsa_devices[i]); ++ } + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + +From 82d330e12d1b94ca06a4d9ba837ec54a7fd56df1 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 012/204] bcm2708 vchiq driver +Subject: [PATCH 023/113] bcm2708 vchiq driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -83057,6 +84214,84 @@ Based on work by Lubomir Rintel. Signed-off-by: Noralf Trønnes vchiq: Change logging level for inbound data + +vchiq_arm: Two cacheing fixes + +1) Make fragment size vary with cache line size +Without this patch, non-cache-line-aligned transfers may corrupt +(or be corrupted by) adjacent data structures. + +Both ARM and VC need to be updated to enable this feature. This is +ensured by having the loader apply a new DT parameter - +cache-line-size. The existence of this parameter guarantees that the +kernel is capable, and the parameter will only be modified from the +safe default if the loader is capable. + +2) Flush/invalidate vmalloc'd memory, and invalidate after reads + +vchiq: fix NULL pointer dereference when closing driver + +The following code run as root will cause a null pointer dereference oops: + + int fd = open("/dev/vc-cma", O_RDONLY); + if (fd < 0) + err(1, "open failed"); + (void)close(fd); + +[ 1704.877721] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[ 1704.877725] pgd = b899c000 +[ 1704.877736] [00000000] *pgd=37fab831, *pte=00000000, *ppte=00000000 +[ 1704.877748] Internal error: Oops: 817 [#1] PREEMPT SMP ARM +[ 1704.877765] Modules linked in: evdev i2c_bcm2708 uio_pdrv_genirq uio +[ 1704.877774] CPU: 2 PID: 3656 Comm: stress-ng-fstat Not tainted 3.19.1-12-generic-bcm2709 #12-Ubuntu +[ 1704.877777] Hardware name: BCM2709 +[ 1704.877783] task: b8ab9b00 ti: b7e68000 task.ti: b7e68000 +[ 1704.877798] PC is at __down_interruptible+0x50/0xec +[ 1704.877806] LR is at down_interruptible+0x5c/0x68 +[ 1704.877813] pc : [<80630ee8>] lr : [<800704b0>] psr: 60080093 +sp : b7e69e50 ip : b7e69e88 fp : b7e69e84 +[ 1704.877817] r10: b88123c8 r9 : 00000010 r8 : 00000001 +[ 1704.877822] r7 : b8ab9b00 r6 : 7fffffff r5 : 80a1cc34 r4 : 80a1cc34 +[ 1704.877826] r3 : b7e69e50 r2 : 00000000 r1 : 00000000 r0 : 80a1cc34 +[ 1704.877833] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user +[ 1704.877838] Control: 10c5387d Table: 3899c06a DAC: 00000015 +[ 1704.877843] Process do-oops (pid: 3656, stack limit = 0xb7e68238) +[ 1704.877848] Stack: (0xb7e69e50 to 0xb7e6a000) +[ 1704.877856] 9e40: 80a1cc3c 00000000 00000010 b88123c8 +[ 1704.877865] 9e60: b7e69e84 80a1cc34 fff9fee9 ffffffff b7e68000 00000009 b7e69ea4 b7e69e88 +[ 1704.877874] 9e80: 800704b0 80630ea4 fff9fee9 60080013 80a1cc28 fff9fee9 b7e69edc b7e69ea8 +[ 1704.877884] 9ea0: 8040f558 80070460 fff9fee9 ffffffff 00000000 00000000 00000009 80a1cb7c +[ 1704.877893] 9ec0: 00000000 80a1cb7c 00000000 00000010 b7e69ef4 b7e69ee0 803e1ba4 8040f514 +[ 1704.877902] 9ee0: 00000e48 80a1cb7c b7e69f14 b7e69ef8 803e1c9c 803e1b74 b88123c0 b92acb18 +[ 1704.877911] 9f00: b8812790 b8d815d8 b7e69f24 b7e69f18 803e2250 803e1bc8 b7e69f5c b7e69f28 +[ 1704.877921] 9f20: 80167bac 803e222c 00000000 00000000 b7e69f54 b8ab9ffc 00000000 8098c794 +[ 1704.877930] 9f40: b8ab9b00 8000efc4 b7e68000 00000000 b7e69f6c b7e69f60 80167d6c 80167b28 +[ 1704.877939] 9f60: b7e69f8c b7e69f70 80047d38 80167d60 b7e68000 b7e68010 8000efc4 b7e69fb0 +[ 1704.877949] 9f80: b7e69fac b7e69f90 80012820 80047c84 01155490 011549a8 00000001 00000006 +[ 1704.877957] 9fa0: 00000000 b7e69fb0 8000ee5c 80012790 00000000 353d8c0f 7efc4308 00000000 +[ 1704.877966] 9fc0: 01155490 011549a8 00000001 00000006 00000000 00000000 76cf3ba0 00000003 +[ 1704.877975] 9fe0: 00000000 7efc42e4 0002272f 76e2ed66 60080030 00000003 00000000 00000000 +[ 1704.877998] [<80630ee8>] (__down_interruptible) from [<800704b0>] (down_interruptible+0x5c/0x68) +[ 1704.878015] [<800704b0>] (down_interruptible) from [<8040f558>] (vchiu_queue_push+0x50/0xd8) +[ 1704.878032] [<8040f558>] (vchiu_queue_push) from [<803e1ba4>] (send_worker_msg+0x3c/0x54) +[ 1704.878045] [<803e1ba4>] (send_worker_msg) from [<803e1c9c>] (vc_cma_set_reserve+0xe0/0x1c4) +[ 1704.878057] [<803e1c9c>] (vc_cma_set_reserve) from [<803e2250>] (vc_cma_release+0x30/0x38) +[ 1704.878069] [<803e2250>] (vc_cma_release) from [<80167bac>] (__fput+0x90/0x1e0) +[ 1704.878082] [<80167bac>] (__fput) from [<80167d6c>] (____fput+0x18/0x1c) +[ 1704.878094] [<80167d6c>] (____fput) from [<80047d38>] (task_work_run+0xc0/0xf8) +[ 1704.878109] [<80047d38>] (task_work_run) from [<80012820>] (do_work_pending+0x9c/0xc4) +[ 1704.878123] [<80012820>] (do_work_pending) from [<8000ee5c>] (work_pending+0xc/0x20) +[ 1704.878133] Code: e50b1034 e3a01000 e50b2030 e580300c (e5823000) + +..the fix is to ensure that we have actually initialized the queue before we attempt +to push any items onto it. This occurs if we do an open() followed by a close() without +any activity in between. + +Signed-off-by: Colin Ian King + +vchiq_arm: Sort out the vmalloc case + +See: https://github.com/raspberrypi/linux/issues/1055 --- arch/arm/mach-bcm2708/bcm2708.c | 26 + arch/arm/mach-bcm2708/include/mach/platform.h | 2 + @@ -83075,8 +84310,8 @@ vchiq: Change logging level for inbound data .../misc/vc04_services/interface/vchi/vchi_mh.h | 42 + .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 40 + .../vc04_services/interface/vchiq_arm/vchiq_2835.h | 42 + - .../interface/vchiq_arm/vchiq_2835_arm.c | 547 +++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2886 ++++++++++++++ + .../interface/vchiq_arm/vchiq_2835_arm.c | 580 +++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2903 +++++++++++++++ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 220 ++ .../interface/vchiq_arm/vchiq_build_info.h | 37 + .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 69 + @@ -83094,10 +84329,10 @@ vchiq: Change logging level for inbound data .../interface/vchiq_arm/vchiq_memdrv.h | 71 + .../interface/vchiq_arm/vchiq_pagelist.h | 58 + .../vc04_services/interface/vchiq_arm/vchiq_shim.c | 860 +++++ - .../vc04_services/interface/vchiq_arm/vchiq_util.c | 152 + - .../vc04_services/interface/vchiq_arm/vchiq_util.h | 81 + + .../vc04_services/interface/vchiq_arm/vchiq_util.c | 156 + + .../vc04_services/interface/vchiq_arm/vchiq_util.h | 82 + .../interface/vchiq_arm/vchiq_version.c | 59 + - 39 files changed, 12810 insertions(+) + 39 files changed, 12865 insertions(+) create mode 100644 drivers/misc/vc04_services/Kconfig create mode 100644 drivers/misc/vc04_services/Makefile create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h @@ -83133,11 +84368,11 @@ vchiq: Change logging level for inbound data create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index df32241..ecf0524 100644 +index 296492a..541ee37 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -376,6 +376,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -365,6 +365,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +static struct resource bcm2708_vchiq_resources[] = { @@ -83168,16 +84403,16 @@ index df32241..ecf0524 100644 #ifdef CONFIG_BCM2708_GPIO #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" -@@ -611,6 +636,7 @@ void __init bcm2708_init(void) +@@ -599,6 +624,7 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h -index 2e7e1bb..69674e9 100644 +index a132502..0c57a57 100644 --- a/arch/arm/mach-bcm2708/include/mach/platform.h +++ b/arch/arm/mach-bcm2708/include/mach/platform.h @@ -81,6 +81,8 @@ @@ -83190,11 +84425,11 @@ index 2e7e1bb..69674e9 100644 /* diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 62c95cb..de9feaa 100644 +index 46a274e..0a7bd3e 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -396,6 +396,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -381,6 +381,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +static struct resource bcm2708_vchiq_resources[] = { @@ -83225,10 +84460,10 @@ index 62c95cb..de9feaa 100644 #ifdef CONFIG_BCM2708_GPIO #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" -@@ -631,6 +656,7 @@ void __init bcm2709_init(void) +@@ -616,6 +641,7 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); @@ -83247,10 +84482,10 @@ index 7157f38..be99733 100644 /* diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 006242c..4e6f46c3 100644 +index ccccc29..098131f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig -@@ -524,6 +524,7 @@ source "drivers/misc/carma/Kconfig" +@@ -533,6 +533,7 @@ source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/mei/Kconfig" source "drivers/misc/vmw_vmci/Kconfig" @@ -83259,7 +84494,7 @@ index 006242c..4e6f46c3 100644 source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 7d5c4cd..43d2ac9 100644 +index 537d7f3..ac24d77 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_INTEL_MEI) += mei/ @@ -83272,13 +84507,13 @@ index 7d5c4cd..43d2ac9 100644 obj-$(CONFIG_ECHO) += echo/ diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig new file mode 100644 -index 0000000..c5ba283 +index 0000000..db8e1be --- /dev/null +++ b/drivers/misc/vc04_services/Kconfig @@ -0,0 +1,9 @@ +config BCM2708_VCHIQ + tristate "Videocore VCHIQ" -+ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX ++ depends on RASPBERRYPI_FIRMWARE + default y + help + Kernel to VideoCore communication interface for the @@ -84865,10 +86100,10 @@ index 0000000..7ea5c64 +#endif /* VCHIQ_2835_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c new file mode 100644 -index 0000000..c739083 +index 0000000..c9febcc --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -0,0 +1,547 @@ +@@ -0,0 +1,580 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -84910,10 +86145,11 @@ index 0000000..c739083 +#include +#include +#include -+#include +#include +#include ++#include +#include ++#include + +#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + @@ -84935,8 +86171,10 @@ index 0000000..c739083 +} VCHIQ_2835_ARM_STATE_T; + +static void __iomem *g_regs; -+static FRAGMENTS_T *g_fragments_base; -+static FRAGMENTS_T *g_free_fragments; ++static unsigned int g_cache_line_size = sizeof(CACHE_LINE_SIZE); ++static unsigned int g_fragments_size; ++static char *g_fragments_base; ++static char *g_free_fragments; +static struct semaphore g_free_fragments_sema; +static unsigned long g_virt_to_bus_offset; + @@ -84957,18 +86195,24 @@ index 0000000..c739083 +int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) +{ + struct device *dev = &pdev->dev; ++ struct rpi_firmware *fw = platform_get_drvdata(pdev); + VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; + struct resource *res; + void *slot_mem; + dma_addr_t slot_phys; ++ u32 channelbase; + int slot_mem_size, frag_mem_size; + int err, irq, i; + + g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); + ++ (void)of_property_read_u32(dev->of_node, "cache-line-size", ++ &g_cache_line_size); ++ g_fragments_size = 2 * g_cache_line_size; ++ + /* Allocate space for the channels in coherent memory */ + slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); -+ frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); ++ frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); + + slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, + &slot_phys, GFP_KERNEL); @@ -84988,15 +86232,15 @@ index 0000000..c739083 + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = + MAX_FRAGMENTS; + -+ g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); ++ g_fragments_base = (char *)slot_mem + slot_mem_size; + slot_mem_size += frag_mem_size; + + g_free_fragments = g_fragments_base; + for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { -+ *(FRAGMENTS_T **)&g_fragments_base[i] = -+ &g_fragments_base[i + 1]; ++ *(char **)&g_fragments_base[i*g_fragments_size] = ++ &g_fragments_base[(i + 1)*g_fragments_size]; + } -+ *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; ++ *(char **)&g_fragments_base[i * g_fragments_size] = NULL; + sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); + + if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) @@ -85021,13 +86265,12 @@ index 0000000..c739083 + } + + /* Send the base address of the slots to VideoCore */ -+ -+ dsb(); /* Ensure all writes have completed */ -+ -+ err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); -+ if (err) { -+ dev_err(dev, "mailbox write failed\n"); -+ return err; ++ channelbase = slot_phys; ++ err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, ++ &channelbase, sizeof(channelbase)); ++ if (err || channelbase) { ++ dev_err(dev, "failed to set channelbase\n"); ++ return err ? : -ENXIO; + } + + vchiq_log_info(vchiq_arm_log_level, @@ -85215,7 +86458,7 @@ index 0000000..c739083 +** cached area. + +** N.B. This implementation plays slightly fast and loose with the Linux -+** driver programming rules, e.g. its use of __virt_to_bus instead of ++** driver programming rules, e.g. its use of dmac_map_area instead of +** dma_map_single, but it isn't a multi-platform driver and it benefits +** from increased speed as a result. +*/ @@ -85226,7 +86469,6 @@ index 0000000..c739083 +{ + PAGELIST_T *pagelist; + struct page **pages; -+ struct page *page; + unsigned long *addrs; + unsigned int num_pages, offset, i; + char *addr, *base_addr, *next_addr; @@ -85257,10 +86499,25 @@ index 0000000..c739083 + pages = (struct page **)(addrs + num_pages + 1); + + if (is_vmalloc_addr(buf)) { -+ for (actual_pages = 0; actual_pages < num_pages; actual_pages++) { -+ pages[actual_pages] = vmalloc_to_page(buf + (actual_pages * PAGE_SIZE)); ++ int dir = (type == PAGELIST_WRITE) ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE; ++ unsigned long length = count; ++ unsigned int off = offset; ++ ++ for (actual_pages = 0; actual_pages < num_pages; ++ actual_pages++) { ++ struct page *pg = vmalloc_to_page(buf + (actual_pages * ++ PAGE_SIZE)); ++ size_t bytes = PAGE_SIZE - off; ++ ++ if (bytes > length) ++ bytes = length; ++ pages[actual_pages] = pg; ++ dmac_map_area(page_address(pg) + off, bytes, dir); ++ length -= bytes; ++ off = 0; + } -+ *need_release = 0; /* do not try and release vmalloc pages */ ++ *need_release = 0; /* do not try and release vmalloc pages */ + } else { + down_read(&task->mm->mmap_sem); + actual_pages = get_user_pages(task, task->mm, @@ -85289,7 +86546,7 @@ index 0000000..c739083 + actual_pages = -ENOMEM; + return actual_pages; + } -+ *need_release = 1; /* release user pages */ ++ *need_release = 1; /* release user pages */ + } + + pagelist->length = count; @@ -85322,10 +86579,10 @@ index 0000000..c739083 + + /* Partial cache lines (fragments) require special measures */ + if ((type == PAGELIST_READ) && -+ ((pagelist->offset & (CACHE_LINE_SIZE - 1)) || ++ ((pagelist->offset & (g_cache_line_size - 1)) || + ((pagelist->offset + pagelist->length) & -+ (CACHE_LINE_SIZE - 1)))) { -+ FRAGMENTS_T *fragments; ++ (g_cache_line_size - 1)))) { ++ char *fragments; + + if (down_interruptible(&g_free_fragments_sema) != 0) { + kfree(pagelist); @@ -85335,19 +86592,15 @@ index 0000000..c739083 + WARN_ON(g_free_fragments == NULL); + + down(&g_free_fragments_mutex); -+ fragments = (FRAGMENTS_T *) g_free_fragments; ++ fragments = g_free_fragments; + WARN_ON(fragments == NULL); -+ g_free_fragments = *(FRAGMENTS_T **) g_free_fragments; ++ g_free_fragments = *(char **) g_free_fragments; + up(&g_free_fragments_mutex); -+ pagelist->type = -+ PAGELIST_READ_WITH_FRAGMENTS + (fragments - -+ g_fragments_base); ++ pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + ++ (fragments - g_fragments_base) / g_fragments_size; + } + -+ for (page = virt_to_page(pagelist); -+ page <= virt_to_page(addrs + num_pages - 1); page++) { -+ flush_dcache_page(page); -+ } ++ dmac_flush_range(pagelist, addrs + num_pages); + + *ppagelist = pagelist; + @@ -85373,13 +86626,14 @@ index 0000000..c739083 + + /* Deal with any partial cache lines (fragments) */ + if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { -+ FRAGMENTS_T *fragments = g_fragments_base + -+ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS); ++ char *fragments = g_fragments_base + ++ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * ++ g_fragments_size; + int head_bytes, tail_bytes; -+ head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & -+ (CACHE_LINE_SIZE - 1); ++ head_bytes = (g_cache_line_size - pagelist->offset) & ++ (g_cache_line_size - 1); + tail_bytes = (pagelist->offset + actual) & -+ (CACHE_LINE_SIZE - 1); ++ (g_cache_line_size - 1); + + if ((actual >= 0) && (head_bytes != 0)) { + if (head_bytes > actual) @@ -85387,41 +86641,55 @@ index 0000000..c739083 + + memcpy((char *)page_address(pages[0]) + + pagelist->offset, -+ fragments->headbuf, ++ fragments, + head_bytes); + } + if ((actual >= 0) && (head_bytes < actual) && + (tail_bytes != 0)) { + memcpy((char *)page_address(pages[num_pages - 1]) + + ((pagelist->offset + actual) & -+ (PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)), -+ fragments->tailbuf, tail_bytes); ++ (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), ++ fragments + g_cache_line_size, ++ tail_bytes); + } + + down(&g_free_fragments_mutex); -+ *(FRAGMENTS_T **) fragments = g_free_fragments; ++ *(char **)fragments = g_free_fragments; + g_free_fragments = fragments; + up(&g_free_fragments_mutex); + up(&g_free_fragments_sema); + } + -+ if (*need_release) { -+ for (i = 0; i < num_pages; i++) { -+ if (pagelist->type != PAGELIST_WRITE) -+ set_page_dirty(pages[i]); ++ if (*need_release) { ++ unsigned int length = pagelist->length; ++ unsigned int offset = pagelist->offset; + -+ page_cache_release(pages[i]); ++ for (i = 0; i < num_pages; i++) { ++ struct page *pg = pages[i]; ++ ++ if (pagelist->type != PAGELIST_WRITE) { ++ unsigned int bytes = PAGE_SIZE - offset; ++ ++ if (bytes > length) ++ bytes = length; ++ dmac_unmap_area(page_address(pg) + offset, ++ bytes, DMA_FROM_DEVICE); ++ length -= bytes; ++ offset = 0; ++ set_page_dirty(pg); ++ } ++ page_cache_release(pg); + } -+ } ++ } + + kfree(pagelist); +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c new file mode 100644 -index 0000000..31e2cba +index 0000000..e11c0e0 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -0,0 +1,2886 @@ +@@ -0,0 +1,2903 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -85469,7 +86737,9 @@ index 0000000..31e2cba +#include +#include +#include ++#include +#include ++#include + +#include "vchiq_core.h" +#include "vchiq_ioctl.h" @@ -88217,9 +89487,24 @@ index 0000000..31e2cba + +static int vchiq_probe(struct platform_device *pdev) +{ ++ struct device_node *fw_node; ++ struct rpi_firmware *fw; + int err; + void *ptr_err; + ++ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++/* Remove comment when booting without Device Tree is no longer supported ++ if (!fw_node) { ++ dev_err(&pdev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++*/ ++ fw = rpi_firmware_get(fw_node); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ platform_set_drvdata(pdev, fw); ++ + /* create debugfs entries */ + err = vchiq_debugfs_init(); + if (err != 0) @@ -95912,10 +97197,10 @@ index 0000000..8072ff6 +EXPORT_SYMBOL(vchi_service_release); diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c new file mode 100644 -index 0000000..05e7979 +index 0000000..384acb8 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -@@ -0,0 +1,152 @@ +@@ -0,0 +1,156 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -95964,6 +97249,7 @@ index 0000000..05e7979 + queue->size = size; + queue->read = 0; + queue->write = 0; ++ queue->initialized = 1; + + sema_init(&queue->pop, 0); + sema_init(&queue->push, 0); @@ -95994,6 +97280,9 @@ index 0000000..05e7979 + +void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) +{ ++ if (!queue->initialized) ++ return; ++ + while (queue->write == queue->read + queue->size) { + if (down_interruptible(&queue->pop) != 0) { + flush_signals(current); @@ -96070,10 +97359,10 @@ index 0000000..05e7979 +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h new file mode 100644 -index 0000000..f4d0b66 +index 0000000..4055d4b --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -@@ -0,0 +1,81 @@ +@@ -0,0 +1,82 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -96136,6 +97425,7 @@ index 0000000..f4d0b66 + int size; + int read; + int write; ++ int initialized; + + struct semaphore pop; + struct semaphore push; @@ -96221,10 +97511,10 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From 5c91907c6aec2d89bf1d57ab85e01bfdab1f0801 Mon Sep 17 00:00:00 2001 +From 05522a38c9e37b1a6e4ce6efa64ba88c7fd31008 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 16:07:06 +0100 -Subject: [PATCH 013/204] vc_mem: Add vc_mem driver +Subject: [PATCH 024/113] vc_mem: Add vc_mem driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -96241,9 +97531,9 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2709/vc_mem.c | 431 ---------------------------- drivers/char/broadcom/Kconfig | 12 +- drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/vc_mem.c | 423 +++++++++++++++++++++++++++ + drivers/char/broadcom/vc_mem.c | 422 +++++++++++++++++++++++++++ include/linux/broadcom/vc_mem.h | 35 +++ - 6 files changed, 470 insertions(+), 467 deletions(-) + 6 files changed, 469 insertions(+), 467 deletions(-) delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c create mode 100644 drivers/char/broadcom/vc_mem.c @@ -96761,10 +98051,10 @@ index 13c5bca..fce918c 100644 +obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c new file mode 100644 -index 0000000..fcde6b1 +index 0000000..be64f23 --- /dev/null +++ b/drivers/char/broadcom/vc_mem.c -@@ -0,0 +1,423 @@ +@@ -0,0 +1,422 @@ +/***************************************************************************** +* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. +* @@ -96789,7 +98079,6 @@ index 0000000..fcde6b1 +#include +#include +#include -+#include +#include + +#define DRIVER_NAME "vc-mem" @@ -97230,10 +98519,10 @@ index 0000000..20a4753 + +#endif /* _VC_MEM_H */ -From 40c1f77329886c79e9ac40afe3dee52dec5a0f5f Mon Sep 17 00:00:00 2001 +From 4a45cf27c95ae5d03dd11ed522722bf69f2ed87e Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 014/204] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 025/113] vcsm: VideoCore shared memory service for BCM2835 Add experimental support for the VideoCore shared memory service. This allows user processes to allocate memory from VideoCore's @@ -98427,7 +99716,7 @@ index 0000000..7c6ba1a +} diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c new file mode 100644 -index 0000000..0bfb42e +index 0000000..b62a3b2 --- /dev/null +++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c @@ -0,0 +1,3211 @@ @@ -99801,8 +101090,8 @@ index 0000000..0bfb42e + return 0; + +error: -+ vmcs_sm_release_resource(resource, 0); + resource->res_stats[MAP_FAIL]++; ++ vmcs_sm_release_resource(resource, 0); + return ret; +} + @@ -101643,10 +102932,2646 @@ index 0000000..0bfb42e +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); -From 89476e1e5132eb053f40bcad4d31903c2660d737 Mon Sep 17 00:00:00 2001 +From 5269a44142c6e5c26d06f9b7833a8e95e3ba1fc9 Mon Sep 17 00:00:00 2001 +From: Luke Wren +Date: Fri, 21 Aug 2015 23:14:48 +0100 +Subject: [PATCH 026/113] Add /dev/gpiomem device for rootless user GPIO access + +Signed-off-by: Luke Wren +--- + drivers/char/broadcom/Kconfig | 9 ++ + drivers/char/broadcom/Makefile | 3 + + drivers/char/broadcom/bcm2835-gpiomem.c | 265 ++++++++++++++++++++++++++++++++ + 3 files changed, 277 insertions(+) + create mode 100644 drivers/char/broadcom/bcm2835-gpiomem.c + +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index 75fa1cb..b75c9b2 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -32,3 +32,12 @@ config BCM_VC_SM + help + Support for the VC shared memory on the Broadcom reference + design. Uses the VCHIQ stack. ++ ++config BCM2835_DEVGPIOMEM ++ tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835" ++ default m ++ help ++ Provides users with root-free access to the GPIO registers ++ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO ++ register page to the user's pointer. ++ +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index de8feb9..1eb06e9 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -1,3 +1,6 @@ + obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ + obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o + obj-$(CONFIG_BCM_VC_SM) += vc_sm/ ++ ++obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o ++ +diff --git a/drivers/char/broadcom/bcm2835-gpiomem.c b/drivers/char/broadcom/bcm2835-gpiomem.c +new file mode 100644 +index 0000000..0085e13 +--- /dev/null ++++ b/drivers/char/broadcom/bcm2835-gpiomem.c +@@ -0,0 +1,265 @@ ++/** ++ * GPIO memory device driver ++ * ++ * Creates a chardev /dev/gpiomem which will provide user access to ++ * the BCM2835's GPIO registers when it is mmap()'d. ++ * No longer need root for user GPIO access, but without relaxing permissions ++ * on /dev/mem. ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DEVICE_NAME "bcm2835-gpiomem" ++#define DRIVER_NAME "gpiomem-bcm2835" ++#define DEVICE_MINOR 0 ++ ++struct bcm2835_gpiomem_instance { ++ unsigned long gpio_regs_phys; ++ struct device *dev; ++}; ++ ++static struct cdev bcm2835_gpiomem_cdev; ++static dev_t bcm2835_gpiomem_devid; ++static struct class *bcm2835_gpiomem_class; ++static struct device *bcm2835_gpiomem_dev; ++static struct bcm2835_gpiomem_instance *inst; ++ ++ ++/**************************************************************************** ++* ++* GPIO mem chardev file ops ++* ++***************************************************************************/ ++ ++static int bcm2835_gpiomem_open(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ int ret = 0; ++ ++ dev_info(inst->dev, "gpiomem device opened."); ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, "Unknown minor device: %d", dev); ++ ret = -ENXIO; ++ } ++ return ret; ++} ++ ++static int bcm2835_gpiomem_release(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ int ret = 0; ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, "Unknown minor device %d", dev); ++ ret = -ENXIO; ++ } ++ return ret; ++} ++ ++static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = { ++#ifdef CONFIG_HAVE_IOREMAP_PROT ++ .access = generic_access_phys ++#endif ++}; ++ ++static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ /* Ignore what the user says - they're getting the GPIO regs ++ whether they like it or not! */ ++ unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT; ++ ++ vma->vm_page_prot = phys_mem_access_prot(file, gpio_page, ++ PAGE_SIZE, ++ vma->vm_page_prot); ++ vma->vm_ops = &bcm2835_gpiomem_vm_ops; ++ if (remap_pfn_range(vma, vma->vm_start, ++ gpio_page, ++ PAGE_SIZE, ++ vma->vm_page_prot)) { ++ return -EAGAIN; ++ } ++ return 0; ++} ++ ++static const struct file_operations ++bcm2835_gpiomem_fops = { ++ .owner = THIS_MODULE, ++ .open = bcm2835_gpiomem_open, ++ .release = bcm2835_gpiomem_release, ++ .mmap = bcm2835_gpiomem_mmap, ++}; ++ ++ ++ /**************************************************************************** ++* ++* Probe and remove functions ++* ++***************************************************************************/ ++ ++ ++static int bcm2835_gpiomem_probe(struct platform_device *pdev) ++{ ++ int err; ++ void *ptr_err; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct resource *ioresource; ++ ++ /* Allocate buffers and instance data */ ++ ++ inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL); ++ ++ if (!inst) { ++ err = -ENOMEM; ++ goto failed_inst_alloc; ++ } ++ ++ inst->dev = dev; ++ ++ /* Create character device entries */ ++ ++ err = alloc_chrdev_region(&bcm2835_gpiomem_devid, ++ DEVICE_MINOR, 1, DEVICE_NAME); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to allocate device number"); ++ goto failed_alloc_chrdev; ++ } ++ cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops); ++ bcm2835_gpiomem_cdev.owner = THIS_MODULE; ++ err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to register device"); ++ goto failed_cdev_add; ++ } ++ ++ /* Create sysfs entries */ ++ ++ bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME); ++ ptr_err = bcm2835_gpiomem_class; ++ if (IS_ERR(ptr_err)) ++ goto failed_class_create; ++ ++ bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL, ++ bcm2835_gpiomem_devid, NULL, ++ "gpiomem"); ++ ptr_err = bcm2835_gpiomem_dev; ++ if (IS_ERR(ptr_err)) ++ goto failed_device_create; ++ ++ /* Get address from device tree if available (*_resource() correctly ++ converts the bus address in device tree to a physical address), ++ or use hardcoded offset + BCM2708_PERI_BASE if not. ++ (In spite of its name 2708 actually seems to have the correct ++ mach-dependent value on 2709 etc, as it is defined in ++ mach-bcm270x/platform.h) */ ++ ++ if (node) { ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ inst->gpio_regs_phys = ioresource->start; ++ } else { ++ inst->gpio_regs_phys = GPIO_BASE; ++ } ++ ++ dev_info(inst->dev, "Initialised: Registers at 0x%08lx", ++ inst->gpio_regs_phys); ++ ++ return 0; ++ ++failed_device_create: ++ class_destroy(bcm2835_gpiomem_class); ++failed_class_create: ++ cdev_del(&bcm2835_gpiomem_cdev); ++ err = PTR_ERR(ptr_err); ++failed_cdev_add: ++ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); ++failed_alloc_chrdev: ++ kfree(inst); ++failed_inst_alloc: ++ dev_err(inst->dev, "could not load bcm2835_gpiomem"); ++ return err; ++} ++ ++static int bcm2835_gpiomem_remove(struct platform_device *pdev) ++{ ++ struct device *dev = inst->dev; ++ ++ kfree(inst); ++ device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid); ++ class_destroy(bcm2835_gpiomem_class); ++ cdev_del(&bcm2835_gpiomem_cdev); ++ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); ++ ++ dev_info(dev, "GPIO mem driver removed - OK"); ++ return 0; ++} ++ ++ /**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_gpiomem_of_match[] = { ++ {.compatible = "brcm,bcm2835-gpiomem",}, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match); ++ ++static struct platform_driver bcm2835_gpiomem_driver = { ++ .probe = bcm2835_gpiomem_probe, ++ .remove = bcm2835_gpiomem_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_gpiomem_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_gpiomem_driver); ++ ++MODULE_ALIAS("platform:gpiomem-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); ++MODULE_AUTHOR("Luke Wren "); + +From 33a380065a1ec643623f11adfc9e35cf68e5be0c Mon Sep 17 00:00:00 2001 +From: Luke Wren +Date: Sat, 5 Sep 2015 01:14:45 +0100 +Subject: [PATCH 027/113] Add SMI driver + +Signed-off-by: Luke Wren +--- + .../bindings/misc/brcm,bcm2835-smi-dev.txt | 17 + + .../devicetree/bindings/misc/brcm,bcm2835-smi.txt | 48 + + drivers/char/broadcom/Kconfig | 8 + + drivers/char/broadcom/Makefile | 2 +- + drivers/char/broadcom/bcm2835_smi_dev.c | 402 +++++++++ + drivers/misc/Kconfig | 8 + + drivers/misc/Makefile | 1 + + drivers/misc/bcm2835_smi.c | 985 +++++++++++++++++++++ + include/linux/broadcom/bcm2835_smi.h | 391 ++++++++ + 9 files changed, 1861 insertions(+), 1 deletion(-) + create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt + create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt + create mode 100644 drivers/char/broadcom/bcm2835_smi_dev.c + create mode 100644 drivers/misc/bcm2835_smi.c + create mode 100644 include/linux/broadcom/bcm2835_smi.h + +diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt +new file mode 100644 +index 0000000..68cc8eb +--- /dev/null ++++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt +@@ -0,0 +1,17 @@ ++* Broadcom BCM2835 SMI character device driver. ++ ++SMI or secondary memory interface is a peripheral specific to certain Broadcom ++SOCs, and is helpful for talking to things like parallel-interface displays ++and NAND flashes (in fact, most things with a parallel register interface). ++ ++This driver adds a character device which provides a user-space interface to ++an instance of the SMI driver. ++ ++Required properties: ++- compatible: "brcm,bcm2835-smi-dev" ++- smi_handle: a phandle to the smi node. ++ ++Optional properties: ++- None. ++ ++ +diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt +new file mode 100644 +index 0000000..b76dc69 +--- /dev/null ++++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt +@@ -0,0 +1,48 @@ ++* Broadcom BCM2835 SMI driver. ++ ++SMI or secondary memory interface is a peripheral specific to certain Broadcom ++SOCs, and is helpful for talking to things like parallel-interface displays ++and NAND flashes (in fact, most things with a parallel register interface). ++ ++Required properties: ++- compatible: "brcm,bcm2835-smi" ++- reg: Should contain location and length of SMI registers and SMI clkman regs ++- interrupts: *the* SMI interrupt. ++- pinctrl-names: should be "default". ++- pinctrl-0: the phandle of the gpio pin node. ++- brcm,smi-clock-source: the clock source for clkman ++- brcm,smi-clock-divisor: the integer clock divisor for clkman ++- dmas: the dma controller phandle and the DREQ number (4 on a 2835) ++- dma-names: the name used by the driver to request its channel. ++ Should be "rx-tx". ++ ++Optional properties: ++- None. ++ ++Examples: ++ ++8 data pin configuration: ++ ++smi: smi@7e600000 { ++ compatible = "brcm,bcm2835-smi"; ++ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; ++ interrupts = <2 16>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&smi_pins>; ++ brcm,smi-clock-source = <6>; ++ brcm,smi-clock-divisor = <4>; ++ dmas = <&dma 4>; ++ dma-names = "rx-tx"; ++ ++ status = "okay"; ++}; ++ ++smi_pins: smi_pins { ++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15>; ++ /* Alt 1: SMI */ ++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>; ++ /* /CS, /WE and /OE are pulled high, as they are ++ generally active low signals */ ++ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0>; ++}; ++ +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index b75c9b2..2292ed2 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -41,3 +41,11 @@ config BCM2835_DEVGPIOMEM + on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO + register page to the user's pointer. + ++config BCM2835_SMI_DEV ++ tristate "Character device driver for BCM2835 Secondary Memory Interface" ++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI ++ default m ++ help ++ This driver provides a character device interface (ioctl + read/write) to ++ Broadcom's Secondary Memory interface. The low-level functionality is provided ++ by the SMI driver itself. +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index 1eb06e9..667d33e 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -3,4 +3,4 @@ obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o + obj-$(CONFIG_BCM_VC_SM) += vc_sm/ + + obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o +- ++obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o +diff --git a/drivers/char/broadcom/bcm2835_smi_dev.c b/drivers/char/broadcom/bcm2835_smi_dev.c +new file mode 100644 +index 0000000..d6efd92 +--- /dev/null ++++ b/drivers/char/broadcom/bcm2835_smi_dev.c +@@ -0,0 +1,402 @@ ++/** ++ * Character device driver for Broadcom Secondary Memory Interface ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DEVICE_NAME "bcm2835-smi-dev" ++#define DRIVER_NAME "smi-dev-bcm2835" ++#define DEVICE_MINOR 0 ++ ++static struct cdev bcm2835_smi_cdev; ++static dev_t bcm2835_smi_devid; ++static struct class *bcm2835_smi_class; ++static struct device *bcm2835_smi_dev; ++ ++struct bcm2835_smi_dev_instance { ++ struct device *dev; ++}; ++ ++static struct bcm2835_smi_instance *smi_inst; ++static struct bcm2835_smi_dev_instance *inst; ++ ++static const char *const ioctl_names[] = { ++ "READ_SETTINGS", ++ "WRITE_SETTINGS", ++ "ADDRESS" ++}; ++ ++/**************************************************************************** ++* ++* SMI chardev file ops ++* ++***************************************************************************/ ++static long ++bcm2835_smi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret = 0; ++ ++ dev_info(inst->dev, "serving ioctl..."); ++ ++ switch (cmd) { ++ case BCM2835_SMI_IOC_GET_SETTINGS:{ ++ struct smi_settings *settings; ++ ++ dev_info(inst->dev, "Reading SMI settings to user."); ++ settings = bcm2835_smi_get_settings_from_regs(smi_inst); ++ if (copy_to_user((void *)arg, settings, ++ sizeof(struct smi_settings))) ++ dev_err(inst->dev, "settings copy failed."); ++ break; ++ } ++ case BCM2835_SMI_IOC_WRITE_SETTINGS:{ ++ struct smi_settings *settings; ++ ++ dev_info(inst->dev, "Setting user's SMI settings."); ++ settings = bcm2835_smi_get_settings_from_regs(smi_inst); ++ if (copy_from_user(settings, (void *)arg, ++ sizeof(struct smi_settings))) ++ dev_err(inst->dev, "settings copy failed."); ++ else ++ bcm2835_smi_set_regs_from_settings(smi_inst); ++ break; ++ } ++ case BCM2835_SMI_IOC_ADDRESS: ++ dev_info(inst->dev, "SMI address set: 0x%02x", (int)arg); ++ bcm2835_smi_set_address(smi_inst, arg); ++ break; ++ default: ++ dev_err(inst->dev, "invalid ioctl cmd: %d", cmd); ++ ret = -ENOTTY; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int bcm2835_smi_open(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ ++ dev_dbg(inst->dev, "SMI device opened."); ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, ++ "bcm2835_smi_release: Unknown minor device: %d", ++ dev); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++static int bcm2835_smi_release(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, ++ "bcm2835_smi_release: Unknown minor device %d", dev); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++static ssize_t dma_bounce_user( ++ enum dma_transfer_direction dma_dir, ++ char __user *user_ptr, ++ size_t count, ++ struct bcm2835_smi_bounce_info *bounce) ++{ ++ int chunk_size; ++ int chunk_no = 0; ++ int count_left = count; ++ ++ while (count_left) { ++ int rv; ++ void *buf; ++ ++ /* Wait for current chunk to complete: */ ++ if (down_timeout(&bounce->callback_sem, ++ msecs_to_jiffies(1000))) { ++ dev_err(inst->dev, "DMA bounce timed out"); ++ count -= (count_left); ++ break; ++ } ++ ++ if (bounce->callback_sem.count >= DMA_BOUNCE_BUFFER_COUNT - 1) ++ dev_err(inst->dev, "WARNING: Ring buffer overflow"); ++ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? ++ DMA_BOUNCE_BUFFER_SIZE : count_left; ++ buf = bounce->buffer[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; ++ if (dma_dir == DMA_DEV_TO_MEM) ++ rv = copy_to_user(user_ptr, buf, chunk_size); ++ else ++ rv = copy_from_user(buf, user_ptr, chunk_size); ++ if (rv) ++ dev_err(inst->dev, "copy_*_user() failed!: %d", rv); ++ user_ptr += chunk_size; ++ count_left -= chunk_size; ++ chunk_no++; ++ } ++ return count; ++} ++ ++static ssize_t ++bcm2835_read_file(struct file *f, char __user *user_ptr, ++ size_t count, loff_t *offs) ++{ ++ int odd_bytes; ++ ++ dev_dbg(inst->dev, "User reading %d bytes from SMI.", count); ++ /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */ ++ if (count > DMA_THRESHOLD_BYTES) ++ odd_bytes = count & 0x3; ++ else ++ odd_bytes = count; ++ count -= odd_bytes; ++ if (count) { ++ struct bcm2835_smi_bounce_info *bounce; ++ ++ count = bcm2835_smi_user_dma(smi_inst, ++ DMA_DEV_TO_MEM, user_ptr, count, ++ &bounce); ++ if (count) ++ count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr, ++ count, bounce); ++ } ++ if (odd_bytes) { ++ /* Read from FIFO directly if not using DMA */ ++ uint8_t buf[DMA_THRESHOLD_BYTES]; ++ ++ bcm2835_smi_read_buf(smi_inst, buf, odd_bytes); ++ if (copy_to_user(user_ptr, buf, odd_bytes)) ++ dev_err(inst->dev, "copy_to_user() failed."); ++ count += odd_bytes; ++ ++ } ++ return count; ++} ++ ++static ssize_t ++bcm2835_write_file(struct file *f, const char __user *user_ptr, ++ size_t count, loff_t *offs) ++{ ++ int odd_bytes; ++ ++ dev_dbg(inst->dev, "User writing %d bytes to SMI.", count); ++ if (count > DMA_THRESHOLD_BYTES) ++ odd_bytes = count & 0x3; ++ else ++ odd_bytes = count; ++ count -= odd_bytes; ++ if (count) { ++ struct bcm2835_smi_bounce_info *bounce; ++ ++ count = bcm2835_smi_user_dma(smi_inst, ++ DMA_MEM_TO_DEV, (char __user *)user_ptr, count, ++ &bounce); ++ if (count) ++ count = dma_bounce_user(DMA_MEM_TO_DEV, ++ (char __user *)user_ptr, ++ count, bounce); ++ } ++ if (odd_bytes) { ++ uint8_t buf[DMA_THRESHOLD_BYTES]; ++ ++ if (copy_from_user(buf, user_ptr, odd_bytes)) ++ dev_err(inst->dev, "copy_from_user() failed."); ++ else ++ bcm2835_smi_write_buf(smi_inst, buf, odd_bytes); ++ count += odd_bytes; ++ } ++ return count; ++} ++ ++static const struct file_operations ++bcm2835_smi_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = bcm2835_smi_ioctl, ++ .open = bcm2835_smi_open, ++ .release = bcm2835_smi_release, ++ .read = bcm2835_read_file, ++ .write = bcm2835_write_file, ++}; ++ ++ ++/**************************************************************************** ++* ++* bcm2835_smi_probe - called when the driver is loaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_dev_probe(struct platform_device *pdev) ++{ ++ int err; ++ void *ptr_err; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node, *smi_node; ++ ++ if (!node) { ++ dev_err(dev, "No device tree node supplied!"); ++ return -EINVAL; ++ } ++ ++ smi_node = of_parse_phandle(node, "smi_handle", 0); ++ ++ if (!smi_node) { ++ dev_err(dev, "No such property: smi_handle"); ++ return -ENXIO; ++ } ++ ++ smi_inst = bcm2835_smi_get(smi_node); ++ ++ if (!smi_inst) ++ return -EPROBE_DEFER; ++ ++ /* Allocate buffers and instance data */ ++ ++ inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL); ++ ++ if (!inst) ++ return -ENOMEM; ++ ++ inst->dev = dev; ++ ++ /* Create character device entries */ ++ ++ err = alloc_chrdev_region(&bcm2835_smi_devid, ++ DEVICE_MINOR, 1, DEVICE_NAME); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to allocate device number"); ++ return -ENOMEM; ++ } ++ cdev_init(&bcm2835_smi_cdev, &bcm2835_smi_fops); ++ bcm2835_smi_cdev.owner = THIS_MODULE; ++ err = cdev_add(&bcm2835_smi_cdev, bcm2835_smi_devid, 1); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to register device"); ++ err = -ENOMEM; ++ goto failed_cdev_add; ++ } ++ ++ /* Create sysfs entries */ ++ ++ bcm2835_smi_class = class_create(THIS_MODULE, DEVICE_NAME); ++ ptr_err = bcm2835_smi_class; ++ if (IS_ERR(ptr_err)) ++ goto failed_class_create; ++ ++ bcm2835_smi_dev = device_create(bcm2835_smi_class, NULL, ++ bcm2835_smi_devid, NULL, ++ "smi"); ++ ptr_err = bcm2835_smi_dev; ++ if (IS_ERR(ptr_err)) ++ goto failed_device_create; ++ ++ dev_info(inst->dev, "initialised"); ++ ++ return 0; ++ ++failed_device_create: ++ class_destroy(bcm2835_smi_class); ++failed_class_create: ++ cdev_del(&bcm2835_smi_cdev); ++ err = PTR_ERR(ptr_err); ++failed_cdev_add: ++ unregister_chrdev_region(bcm2835_smi_devid, 1); ++ dev_err(dev, "could not load bcm2835_smi_dev"); ++ return err; ++} ++ ++/**************************************************************************** ++* ++* bcm2835_smi_remove - called when the driver is unloaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_dev_remove(struct platform_device *pdev) ++{ ++ device_destroy(bcm2835_smi_class, bcm2835_smi_devid); ++ class_destroy(bcm2835_smi_class); ++ cdev_del(&bcm2835_smi_cdev); ++ unregister_chrdev_region(bcm2835_smi_devid, 1); ++ ++ dev_info(inst->dev, "SMI character dev removed - OK"); ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_smi_dev_of_match[] = { ++ {.compatible = "brcm,bcm2835-smi-dev",}, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_smi_dev_of_match); ++ ++static struct platform_driver bcm2835_smi_dev_driver = { ++ .probe = bcm2835_smi_dev_probe, ++ .remove = bcm2835_smi_dev_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_smi_dev_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_smi_dev_driver); ++ ++MODULE_ALIAS("platform:smi-dev-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION( ++ "Character device driver for BCM2835's secondary memory interface"); ++MODULE_AUTHOR("Luke Wren "); +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 098131f..c25f99b 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D + select INPUT_POLLDEV + default n + ++config BCM2835_SMI ++ tristate "Broadcom 283x Secondary Memory Interface driver" ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 ++ default m ++ help ++ Driver for enabling and using Broadcom's Secondary/Slow Memory Interface. ++ Appears as /dev/bcm2835_smi. For ioctl interface see drivers/misc/bcm2835_smi.h ++ + config AD525X_DPOT + tristate "Analog Devices Digital Potentiometers" + depends on (I2C || SPI) && SYSFS +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index ac24d77..1acff5b 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o + obj-$(CONFIG_INTEL_MID_PTI) += pti.o + obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o + obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o ++obj-$(CONFIG_BCM2835_SMI) += bcm2835_smi.o + obj-$(CONFIG_BMP085) += bmp085.o + obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o + obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o +diff --git a/drivers/misc/bcm2835_smi.c b/drivers/misc/bcm2835_smi.c +new file mode 100644 +index 0000000..63a4ea0 +--- /dev/null ++++ b/drivers/misc/bcm2835_smi.c +@@ -0,0 +1,985 @@ ++/** ++ * Broadcom Secondary Memory Interface driver ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BCM2835_SMI_IMPLEMENTATION ++#include ++ ++#define DRIVER_NAME "smi-bcm2835" ++ ++#define N_PAGES_FROM_BYTES(n) ((n + PAGE_SIZE-1) / PAGE_SIZE) ++ ++#define DMA_WRITE_TO_MEM true ++#define DMA_READ_FROM_MEM false ++ ++struct bcm2835_smi_instance { ++ struct device *dev; ++ struct smi_settings settings; ++ __iomem void *smi_regs_ptr, *cm_smi_regs_ptr; ++ dma_addr_t smi_regs_busaddr; ++ ++ struct dma_chan *dma_chan; ++ struct dma_slave_config dma_config; ++ ++ struct bcm2835_smi_bounce_info bounce; ++ ++ struct scatterlist buffer_sgl; ++ ++ int clock_source; ++ int clock_divisor; ++ ++ /* Sometimes we are called into in an atomic context (e.g. by ++ JFFS2 + MTD) so we can't use a mutex */ ++ spinlock_t transaction_lock; ++}; ++ ++/**************************************************************************** ++* ++* SMI clock manager setup ++* ++***************************************************************************/ ++ ++static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst, ++ u32 val, unsigned reg) ++{ ++ writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg); ++} ++ ++static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst, ++ unsigned reg) ++{ ++ return readl(inst->cm_smi_regs_ptr + reg); ++} ++ ++static void smi_setup_clock(struct bcm2835_smi_instance *inst) ++{ ++ dev_dbg(inst->dev, "Setting up clock..."); ++ /* Disable SMI clock and wait for it to stop. */ ++ write_smi_cm_reg(inst, 0, CM_SMI_CTL); ++ while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY) ++ ; ++ ++ write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS), ++ CM_SMI_DIV); ++ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS), ++ CM_SMI_CTL); ++ ++ /* Enable the clock */ ++ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) | ++ CM_SMI_CTL_ENAB, CM_SMI_CTL); ++} ++ ++/**************************************************************************** ++* ++* SMI peripheral setup ++* ++***************************************************************************/ ++ ++static inline void write_smi_reg(struct bcm2835_smi_instance *inst, ++ u32 val, unsigned reg) ++{ ++ writel(val, inst->smi_regs_ptr + reg); ++} ++ ++static inline u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg) ++{ ++ return readl(inst->smi_regs_ptr + reg); ++} ++ ++/* Token-paste macro for e.g SMIDSR_RSTROBE -> value of SMIDSR_RSTROBE_MASK */ ++#define _CONCAT(x, y) x##y ++#define CONCAT(x, y) _CONCAT(x, y) ++ ++#define SET_BIT_FIELD(dest, field, bits) ((dest) = \ ++ ((dest) & ~CONCAT(field, _MASK)) | (((bits) << CONCAT(field, _OFFS))& \ ++ CONCAT(field, _MASK))) ++#define GET_BIT_FIELD(src, field) (((src) & \ ++ CONCAT(field, _MASK)) >> CONCAT(field, _OFFS)) ++ ++static void smi_dump_context_labelled(struct bcm2835_smi_instance *inst, ++ const char *label) ++{ ++ dev_err(inst->dev, "SMI context dump: %s", label); ++ dev_err(inst->dev, "SMICS: 0x%08x", read_smi_reg(inst, SMICS)); ++ dev_err(inst->dev, "SMIL: 0x%08x", read_smi_reg(inst, SMIL)); ++ dev_err(inst->dev, "SMIDSR: 0x%08x", read_smi_reg(inst, SMIDSR0)); ++ dev_err(inst->dev, "SMIDSW: 0x%08x", read_smi_reg(inst, SMIDSW0)); ++ dev_err(inst->dev, "SMIDC: 0x%08x", read_smi_reg(inst, SMIDC)); ++ dev_err(inst->dev, "SMIFD: 0x%08x", read_smi_reg(inst, SMIFD)); ++ dev_err(inst->dev, " "); ++} ++ ++static inline void smi_dump_context(struct bcm2835_smi_instance *inst) ++{ ++ smi_dump_context_labelled(inst, ""); ++} ++ ++static void smi_get_default_settings(struct bcm2835_smi_instance *inst) ++{ ++ struct smi_settings *settings = &inst->settings; ++ ++ settings->data_width = SMI_WIDTH_16BIT; ++ settings->pack_data = true; ++ ++ settings->read_setup_time = 1; ++ settings->read_hold_time = 1; ++ settings->read_pace_time = 1; ++ settings->read_strobe_time = 3; ++ ++ settings->write_setup_time = settings->read_setup_time; ++ settings->write_hold_time = settings->read_hold_time; ++ settings->write_pace_time = settings->read_pace_time; ++ settings->write_strobe_time = settings->read_strobe_time; ++ ++ settings->dma_enable = true; ++ settings->dma_passthrough_enable = false; ++ settings->dma_read_thresh = 0x01; ++ settings->dma_write_thresh = 0x3f; ++ settings->dma_panic_read_thresh = 0x20; ++ settings->dma_panic_write_thresh = 0x20; ++} ++ ++void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst) ++{ ++ struct smi_settings *settings = &inst->settings; ++ int smidsr_temp = 0, smidsw_temp = 0, smics_temp, ++ smidcs_temp, smidc_temp = 0; ++ ++ spin_lock(&inst->transaction_lock); ++ ++ /* temporarily disable the peripheral: */ ++ smics_temp = read_smi_reg(inst, SMICS); ++ write_smi_reg(inst, 0, SMICS); ++ smidcs_temp = read_smi_reg(inst, SMIDCS); ++ write_smi_reg(inst, 0, SMIDCS); ++ ++ if (settings->pack_data) ++ smics_temp |= SMICS_PXLDAT; ++ else ++ smics_temp &= ~SMICS_PXLDAT; ++ ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time); ++ write_smi_reg(inst, smidsr_temp, SMIDSR0); ++ ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width); ++ if (settings->data_width == SMI_WIDTH_8BIT) ++ smidsw_temp |= SMIDSW_WSWAP; ++ else ++ smidsw_temp &= ~SMIDSW_WSWAP; ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time); ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time); ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time); ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE, ++ settings->write_strobe_time); ++ write_smi_reg(inst, smidsw_temp, SMIDSW0); ++ ++ SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh); ++ SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh); ++ SET_BIT_FIELD(smidc_temp, SMIDC_PANICR, ++ settings->dma_panic_read_thresh); ++ SET_BIT_FIELD(smidc_temp, SMIDC_PANICW, ++ settings->dma_panic_write_thresh); ++ if (settings->dma_passthrough_enable) { ++ smidc_temp |= SMIDC_DMAP; ++ smidsr_temp |= SMIDSR_RDREQ; ++ write_smi_reg(inst, smidsr_temp, SMIDSR0); ++ smidsw_temp |= SMIDSW_WDREQ; ++ write_smi_reg(inst, smidsw_temp, SMIDSW0); ++ } else ++ smidc_temp &= ~SMIDC_DMAP; ++ if (settings->dma_enable) ++ smidc_temp |= SMIDC_DMAEN; ++ else ++ smidc_temp &= ~SMIDC_DMAEN; ++ ++ write_smi_reg(inst, smidc_temp, SMIDC); ++ ++ /* re-enable (if was previously enabled) */ ++ write_smi_reg(inst, smics_temp, SMICS); ++ write_smi_reg(inst, smidcs_temp, SMIDCS); ++ ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_set_regs_from_settings); ++ ++struct smi_settings *bcm2835_smi_get_settings_from_regs ++ (struct bcm2835_smi_instance *inst) ++{ ++ struct smi_settings *settings = &inst->settings; ++ int smidsr, smidsw, smidc; ++ ++ spin_lock(&inst->transaction_lock); ++ ++ smidsr = read_smi_reg(inst, SMIDSR0); ++ smidsw = read_smi_reg(inst, SMIDSW0); ++ smidc = read_smi_reg(inst, SMIDC); ++ ++ settings->pack_data = (read_smi_reg(inst, SMICS) & SMICS_PXLDAT) ? ++ true : false; ++ ++ settings->data_width = GET_BIT_FIELD(smidsr, SMIDSR_RWIDTH); ++ settings->read_setup_time = GET_BIT_FIELD(smidsr, SMIDSR_RSETUP); ++ settings->read_hold_time = GET_BIT_FIELD(smidsr, SMIDSR_RHOLD); ++ settings->read_pace_time = GET_BIT_FIELD(smidsr, SMIDSR_RPACE); ++ settings->read_strobe_time = GET_BIT_FIELD(smidsr, SMIDSR_RSTROBE); ++ ++ settings->write_setup_time = GET_BIT_FIELD(smidsw, SMIDSW_WSETUP); ++ settings->write_hold_time = GET_BIT_FIELD(smidsw, SMIDSW_WHOLD); ++ settings->write_pace_time = GET_BIT_FIELD(smidsw, SMIDSW_WPACE); ++ settings->write_strobe_time = GET_BIT_FIELD(smidsw, SMIDSW_WSTROBE); ++ ++ settings->dma_read_thresh = GET_BIT_FIELD(smidc, SMIDC_REQR); ++ settings->dma_write_thresh = GET_BIT_FIELD(smidc, SMIDC_REQW); ++ settings->dma_panic_read_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICR); ++ settings->dma_panic_write_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICW); ++ settings->dma_passthrough_enable = (smidc & SMIDC_DMAP) ? true : false; ++ settings->dma_enable = (smidc & SMIDC_DMAEN) ? true : false; ++ ++ spin_unlock(&inst->transaction_lock); ++ ++ return settings; ++} ++EXPORT_SYMBOL(bcm2835_smi_get_settings_from_regs); ++ ++static inline void smi_set_address(struct bcm2835_smi_instance *inst, ++ unsigned int address) ++{ ++ int smia_temp = 0, smida_temp = 0; ++ ++ SET_BIT_FIELD(smia_temp, SMIA_ADDR, address); ++ SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address); ++ ++ /* Write to both address registers - user doesn't care whether we're ++ doing programmed or direct transfers. */ ++ write_smi_reg(inst, smia_temp, SMIA); ++ write_smi_reg(inst, smida_temp, SMIDA); ++} ++ ++static void smi_setup_regs(struct bcm2835_smi_instance *inst) ++{ ++ ++ dev_dbg(inst->dev, "Initialising SMI registers..."); ++ /* Disable the peripheral if already enabled */ ++ write_smi_reg(inst, 0, SMICS); ++ write_smi_reg(inst, 0, SMIDCS); ++ ++ smi_get_default_settings(inst); ++ bcm2835_smi_set_regs_from_settings(inst); ++ smi_set_address(inst, 0); ++ ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ENABLE, SMICS); ++ write_smi_reg(inst, read_smi_reg(inst, SMIDCS) | SMIDCS_ENABLE, ++ SMIDCS); ++} ++ ++/**************************************************************************** ++* ++* Low-level SMI access functions ++* Other modules should use the exported higher-level functions e.g. ++* bcm2835_smi_write_buf() unless they have a good reason to use these ++* ++***************************************************************************/ ++ ++static inline uint32_t smi_read_single_word(struct bcm2835_smi_instance *inst) ++{ ++ int timeout = 0; ++ ++ write_smi_reg(inst, SMIDCS_ENABLE, SMIDCS); ++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_START, SMIDCS); ++ /* Make sure things happen in the right order...*/ ++ mb(); ++ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && ++ ++timeout < 10000) ++ ; ++ if (timeout < 10000) ++ return read_smi_reg(inst, SMIDD); ++ ++ dev_err(inst->dev, ++ "SMI direct read timed out (is the clock set up correctly?)"); ++ return 0; ++} ++ ++static inline void smi_write_single_word(struct bcm2835_smi_instance *inst, ++ uint32_t data) ++{ ++ int timeout = 0; ++ ++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE, SMIDCS); ++ write_smi_reg(inst, data, SMIDD); ++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE | SMIDCS_START, ++ SMIDCS); ++ ++ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && ++ ++timeout < 10000) ++ ; ++ if (timeout >= 10000) ++ dev_err(inst->dev, ++ "SMI direct write timed out (is the clock set up correctly?)"); ++} ++ ++/* Initiates a programmed read into the read FIFO. It is up to the caller to ++ * read data from the FIFO - either via paced DMA transfer, ++ * or polling SMICS_RXD to check whether data is available. ++ * SMICS_ACTIVE will go low upon completion. */ ++static void smi_init_programmed_read(struct bcm2835_smi_instance *inst, ++ int num_transfers) ++{ ++ int smics_temp; ++ ++ /* Disable the peripheral: */ ++ smics_temp = read_smi_reg(inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE); ++ write_smi_reg(inst, smics_temp, SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) ++ ; ++ ++ /* Program the transfer count: */ ++ write_smi_reg(inst, num_transfers, SMIL); ++ ++ /* re-enable and start: */ ++ smics_temp |= SMICS_ENABLE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ smics_temp |= SMICS_CLEAR; ++ /* Just to be certain: */ ++ mb(); ++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) ++ ; ++ write_smi_reg(inst, smics_temp, SMICS); ++ smics_temp |= SMICS_START; ++ write_smi_reg(inst, smics_temp, SMICS); ++} ++ ++/* Initiates a programmed write sequence, using data from the write FIFO. ++ * It is up to the caller to initiate a DMA transfer before calling, ++ * or use another method to keep the write FIFO topped up. ++ * SMICS_ACTIVE will go low upon completion. ++ */ ++static void smi_init_programmed_write(struct bcm2835_smi_instance *inst, ++ int num_transfers) ++{ ++ int smics_temp; ++ ++ /* Disable the peripheral: */ ++ smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) ++ ; ++ ++ /* Program the transfer count: */ ++ write_smi_reg(inst, num_transfers, SMIL); ++ ++ /* setup, re-enable and start: */ ++ smics_temp |= SMICS_WRITE | SMICS_ENABLE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ smics_temp |= SMICS_START; ++ write_smi_reg(inst, smics_temp, SMICS); ++} ++ ++/* Initiate a read and then poll FIFO for data, reading out as it appears. */ ++static void smi_read_fifo(struct bcm2835_smi_instance *inst, ++ uint32_t *dest, int n_bytes) ++{ ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { ++ smi_dump_context_labelled(inst, ++ "WARNING: read FIFO not empty at start of read call."); ++ while (read_smi_reg(inst, SMICS)) ++ ; ++ } ++ ++ /* Dispatch the read: */ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_read(inst, n_bytes); ++ else if (inst->settings.data_width == SMI_WIDTH_16BIT) ++ smi_init_programmed_read(inst, n_bytes / 2); ++ else { ++ dev_err(inst->dev, "Unsupported data width for read."); ++ return; ++ } ++ ++ /* Poll FIFO to keep it empty */ ++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) ++ *dest++ = read_smi_reg(inst, SMID); ++ ++ /* Ensure that the FIFO is emptied */ ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { ++ int fifo_count; ++ ++ fifo_count = GET_BIT_FIELD(read_smi_reg(inst, SMIFD), ++ SMIFD_FCNT); ++ while (fifo_count--) ++ *dest++ = read_smi_reg(inst, SMID); ++ } ++ ++ if (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) ++ smi_dump_context_labelled(inst, ++ "WARNING: transaction finished but done bit not set."); ++ ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) ++ smi_dump_context_labelled(inst, ++ "WARNING: read FIFO not empty at end of read call."); ++ ++} ++ ++/* Initiate a write, and then keep the FIFO topped up. */ ++static void smi_write_fifo(struct bcm2835_smi_instance *inst, ++ uint32_t *src, int n_bytes) ++{ ++ int i, timeout = 0; ++ ++ /* Empty FIFOs if not already so */ ++ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) { ++ smi_dump_context_labelled(inst, ++ "WARNING: write fifo not empty at start of write call."); ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_CLEAR, ++ SMICS); ++ } ++ ++ /* Initiate the transfer */ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_write(inst, n_bytes); ++ else if (inst->settings.data_width == SMI_WIDTH_16BIT) ++ smi_init_programmed_write(inst, n_bytes / 2); ++ else { ++ dev_err(inst->dev, "Unsupported data width for write."); ++ return; ++ } ++ /* Fill the FIFO: */ ++ for (i = 0; i < (n_bytes - 1) / 4 + 1; ++i) { ++ while (!(read_smi_reg(inst, SMICS) & SMICS_TXD)) ++ ; ++ write_smi_reg(inst, *src++, SMID); ++ } ++ /* Busy wait... */ ++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE) && ++timeout < ++ 1000000) ++ ; ++ if (timeout >= 1000000) ++ smi_dump_context_labelled(inst, ++ "Timed out on write operation!"); ++ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) ++ smi_dump_context_labelled(inst, ++ "WARNING: FIFO not empty at end of write operation."); ++} ++ ++/**************************************************************************** ++* ++* SMI DMA operations ++* ++***************************************************************************/ ++ ++/* Disable SMI and put it into the correct direction before doing DMA setup. ++ Stops spurious DREQs during setup. Peripheral is re-enabled by init_*() */ ++static void smi_disable(struct bcm2835_smi_instance *inst, ++ enum dma_transfer_direction direction) ++{ ++ int smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; ++ ++ if (direction == DMA_DEV_TO_MEM) ++ smics_temp &= ~SMICS_WRITE; ++ else ++ smics_temp |= SMICS_WRITE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) ++ ; ++} ++ ++static struct scatterlist *smi_scatterlist_from_buffer( ++ struct bcm2835_smi_instance *inst, ++ dma_addr_t buf, ++ size_t len, ++ struct scatterlist *sg) ++{ ++ sg_init_table(sg, 1); ++ sg_dma_address(sg) = buf; ++ sg_dma_len(sg) = len; ++ return sg; ++} ++ ++static void smi_dma_callback_user_copy(void *param) ++{ ++ /* Notify the bottom half that a chunk is ready for user copy */ ++ struct bcm2835_smi_instance *inst = ++ (struct bcm2835_smi_instance *)param; ++ ++ up(&inst->bounce.callback_sem); ++} ++ ++/* Creates a descriptor, assigns the given callback, and submits the ++ descriptor to dmaengine. Does not block - can queue up multiple ++ descriptors and then wait for them all to complete. ++ sg_len is the number of control blocks, NOT the number of bytes. ++ dir can be DMA_MEM_TO_DEV or DMA_DEV_TO_MEM. ++ callback can be NULL - in this case it is not called. */ ++static inline struct dma_async_tx_descriptor *smi_dma_submit_sgl( ++ struct bcm2835_smi_instance *inst, ++ struct scatterlist *sgl, ++ size_t sg_len, ++ enum dma_transfer_direction dir, ++ dma_async_tx_callback callback) ++{ ++ struct dma_async_tx_descriptor *desc; ++ ++ desc = dmaengine_prep_slave_sg(inst->dma_chan, ++ sgl, ++ sg_len, ++ dir, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK | ++ DMA_PREP_FENCE); ++ if (!desc) { ++ dev_err(inst->dev, "read_sgl: dma slave preparation failed!"); ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) & ~SMICS_ACTIVE, ++ SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) ++ cpu_relax(); ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ACTIVE, ++ SMICS); ++ return NULL; ++ } ++ desc->callback = callback; ++ desc->callback_param = inst; ++ if (dmaengine_submit(desc) < 0) ++ return NULL; ++ return desc; ++} ++ ++/* NB this function blocks until the transfer is complete */ ++static void ++smi_dma_read_sgl(struct bcm2835_smi_instance *inst, ++ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) ++{ ++ struct dma_async_tx_descriptor *desc; ++ ++ /* Disable SMI and set to read before dispatching DMA - if SMI is in ++ * write mode and TX fifo is empty, it will generate a DREQ which may ++ * cause the read DMA to complete before the SMI read command is even ++ * dispatched! We want to dispatch DMA before SMI read so that reading ++ * is gapless, for logic analyser. ++ */ ++ ++ smi_disable(inst, DMA_DEV_TO_MEM); ++ ++ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL); ++ dma_async_issue_pending(inst->dma_chan); ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_read(inst, n_bytes); ++ else ++ smi_init_programmed_read(inst, n_bytes / 2); ++ ++ if (dma_wait_for_async_tx(desc) == DMA_ERROR) ++ smi_dump_context_labelled(inst, "DMA timeout!"); ++} ++ ++static void ++smi_dma_write_sgl(struct bcm2835_smi_instance *inst, ++ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) ++{ ++ struct dma_async_tx_descriptor *desc; ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_write(inst, n_bytes); ++ else ++ smi_init_programmed_write(inst, n_bytes / 2); ++ ++ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_MEM_TO_DEV, NULL); ++ dma_async_issue_pending(inst->dma_chan); ++ ++ if (dma_wait_for_async_tx(desc) == DMA_ERROR) ++ smi_dump_context_labelled(inst, "DMA timeout!"); ++ else ++ /* Wait for SMI to finish our writes */ ++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) ++ cpu_relax(); ++} ++ ++ssize_t bcm2835_smi_user_dma( ++ struct bcm2835_smi_instance *inst, ++ enum dma_transfer_direction dma_dir, ++ char __user *user_ptr, size_t count, ++ struct bcm2835_smi_bounce_info **bounce) ++{ ++ int chunk_no = 0, chunk_size, count_left = count; ++ struct scatterlist *sgl; ++ void (*init_trans_func)(struct bcm2835_smi_instance *, int); ++ ++ spin_lock(&inst->transaction_lock); ++ ++ if (dma_dir == DMA_DEV_TO_MEM) ++ init_trans_func = smi_init_programmed_read; ++ else ++ init_trans_func = smi_init_programmed_write; ++ ++ smi_disable(inst, dma_dir); ++ ++ sema_init(&inst->bounce.callback_sem, 0); ++ if (bounce) ++ *bounce = &inst->bounce; ++ while (count_left) { ++ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? ++ DMA_BOUNCE_BUFFER_SIZE : count_left; ++ if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) { ++ sgl = ++ &inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; ++ } else { ++ sgl = smi_scatterlist_from_buffer( ++ inst, ++ inst->bounce.phys[ ++ chunk_no % DMA_BOUNCE_BUFFER_COUNT], ++ chunk_size, ++ &inst->buffer_sgl); ++ } ++ ++ if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir, ++ smi_dma_callback_user_copy ++ )) { ++ dev_err(inst->dev, "sgl submit failed"); ++ count = 0; ++ goto out; ++ } ++ count_left -= chunk_size; ++ chunk_no++; ++ } ++ dma_async_issue_pending(inst->dma_chan); ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ init_trans_func(inst, count); ++ else if (inst->settings.data_width == SMI_WIDTH_16BIT) ++ init_trans_func(inst, count / 2); ++out: ++ spin_unlock(&inst->transaction_lock); ++ return count; ++} ++EXPORT_SYMBOL(bcm2835_smi_user_dma); ++ ++ ++/**************************************************************************** ++* ++* High level buffer transfer functions - for use by other drivers ++* ++***************************************************************************/ ++ ++/* Buffer must be physically contiguous - i.e. kmalloc, not vmalloc! */ ++void bcm2835_smi_write_buf( ++ struct bcm2835_smi_instance *inst, ++ const void *buf, size_t n_bytes) ++{ ++ int odd_bytes = n_bytes & 0x3; ++ ++ n_bytes -= odd_bytes; ++ ++ spin_lock(&inst->transaction_lock); ++ ++ if (n_bytes > DMA_THRESHOLD_BYTES) { ++ dma_addr_t phy_addr = dma_map_single( ++ inst->dev, ++ (void *)buf, ++ n_bytes, ++ DMA_MEM_TO_DEV); ++ struct scatterlist *sgl = ++ smi_scatterlist_from_buffer(inst, phy_addr, n_bytes, ++ &inst->buffer_sgl); ++ ++ if (!sgl) { ++ smi_dump_context_labelled(inst, ++ "Error: could not create scatterlist for write!"); ++ goto out; ++ } ++ smi_dma_write_sgl(inst, sgl, 1, n_bytes); ++ ++ dma_unmap_single ++ (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); ++ } else if (n_bytes) { ++ smi_write_fifo(inst, (uint32_t *) buf, n_bytes); ++ } ++ buf += n_bytes; ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) { ++ while (odd_bytes--) ++ smi_write_single_word(inst, *(uint8_t *) (buf++)); ++ } else { ++ while (odd_bytes >= 2) { ++ smi_write_single_word(inst, *(uint16_t *)buf); ++ buf += 2; ++ odd_bytes -= 2; ++ } ++ if (odd_bytes) { ++ /* Reading an odd number of bytes on a 16 bit bus is ++ a user bug. It's kinder to fail early and tell them ++ than to e.g. transparently give them the bottom byte ++ of a 16 bit transfer. */ ++ dev_err(inst->dev, ++ "WARNING: odd number of bytes specified for wide transfer."); ++ dev_err(inst->dev, ++ "At least one byte dropped as a result."); ++ dump_stack(); ++ } ++ } ++out: ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_write_buf); ++ ++void bcm2835_smi_read_buf(struct bcm2835_smi_instance *inst, ++ void *buf, size_t n_bytes) ++{ ++ ++ /* SMI is inherently 32-bit, which causes surprising amounts of mess ++ for bytes % 4 != 0. Easiest to avoid this mess altogether ++ by handling remainder separately. */ ++ int odd_bytes = n_bytes & 0x3; ++ ++ spin_lock(&inst->transaction_lock); ++ n_bytes -= odd_bytes; ++ if (n_bytes > DMA_THRESHOLD_BYTES) { ++ dma_addr_t phy_addr = dma_map_single(inst->dev, ++ buf, n_bytes, ++ DMA_DEV_TO_MEM); ++ struct scatterlist *sgl = smi_scatterlist_from_buffer( ++ inst, phy_addr, n_bytes, ++ &inst->buffer_sgl); ++ if (!sgl) { ++ smi_dump_context_labelled(inst, ++ "Error: could not create scatterlist for read!"); ++ goto out; ++ } ++ smi_dma_read_sgl(inst, sgl, 1, n_bytes); ++ dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); ++ } else if (n_bytes) { ++ smi_read_fifo(inst, (uint32_t *)buf, n_bytes); ++ } ++ buf += n_bytes; ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) { ++ while (odd_bytes--) ++ *((uint8_t *) (buf++)) = smi_read_single_word(inst); ++ } else { ++ while (odd_bytes >= 2) { ++ *(uint16_t *) buf = smi_read_single_word(inst); ++ buf += 2; ++ odd_bytes -= 2; ++ } ++ if (odd_bytes) { ++ dev_err(inst->dev, ++ "WARNING: odd number of bytes specified for wide transfer."); ++ dev_err(inst->dev, ++ "At least one byte dropped as a result."); ++ dump_stack(); ++ } ++ } ++out: ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_read_buf); ++ ++void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, ++ unsigned int address) ++{ ++ spin_lock(&inst->transaction_lock); ++ smi_set_address(inst, address); ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_set_address); ++ ++struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node) ++{ ++ struct platform_device *pdev; ++ ++ if (!node) ++ return NULL; ++ ++ pdev = of_find_device_by_node(node); ++ if (!pdev) ++ return NULL; ++ ++ return platform_get_drvdata(pdev); ++} ++EXPORT_SYMBOL(bcm2835_smi_get); ++ ++/**************************************************************************** ++* ++* bcm2835_smi_probe - called when the driver is loaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_dma_setup(struct bcm2835_smi_instance *inst) ++{ ++ int i, rv = 0; ++ ++ inst->dma_chan = dma_request_slave_channel(inst->dev, "rx-tx"); ++ ++ inst->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ inst->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ inst->dma_config.src_addr = inst->smi_regs_busaddr + SMID; ++ inst->dma_config.dst_addr = inst->dma_config.src_addr; ++ /* Direction unimportant - always overridden by prep_slave_sg */ ++ inst->dma_config.direction = DMA_DEV_TO_MEM; ++ dmaengine_slave_config(inst->dma_chan, &inst->dma_config); ++ /* Alloc and map bounce buffers */ ++ for (i = 0; i < DMA_BOUNCE_BUFFER_COUNT; ++i) { ++ inst->bounce.buffer[i] = ++ dmam_alloc_coherent(inst->dev, DMA_BOUNCE_BUFFER_SIZE, ++ &inst->bounce.phys[i], ++ GFP_KERNEL); ++ if (!inst->bounce.buffer[i]) { ++ dev_err(inst->dev, "Could not allocate buffer!"); ++ rv = -ENOMEM; ++ break; ++ } ++ smi_scatterlist_from_buffer( ++ inst, ++ inst->bounce.phys[i], ++ DMA_BOUNCE_BUFFER_SIZE, ++ &inst->bounce.sgl[i] ++ ); ++ } ++ ++ return rv; ++} ++ ++static int bcm2835_smi_probe(struct platform_device *pdev) ++{ ++ int err; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct resource *ioresource; ++ struct bcm2835_smi_instance *inst; ++ ++ /* Allocate buffers and instance data */ ++ ++ inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance), ++ GFP_KERNEL); ++ ++ if (!inst) ++ return -ENOMEM; ++ ++ inst->dev = dev; ++ spin_lock_init(&inst->transaction_lock); ++ ++ /* We require device tree support */ ++ if (!node) ++ return -EINVAL; ++ ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource); ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource); ++ inst->smi_regs_busaddr = be32_to_cpu( ++ *of_get_address(node, 0, NULL, NULL)); ++ of_property_read_u32(node, ++ "brcm,smi-clock-source", ++ &inst->clock_source); ++ of_property_read_u32(node, ++ "brcm,smi-clock-divisor", ++ &inst->clock_divisor); ++ ++ err = bcm2835_smi_dma_setup(inst); ++ if (err) ++ return err; ++ ++ /* Finally, do peripheral setup */ ++ ++ smi_setup_clock(inst); ++ smi_setup_regs(inst); ++ ++ platform_set_drvdata(pdev, inst); ++ ++ dev_info(inst->dev, "initialised"); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* bcm2835_smi_remove - called when the driver is unloaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev); ++ struct device *dev = inst->dev; ++ ++ dev_info(dev, "SMI device removed - OK"); ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_smi_of_match[] = { ++ {.compatible = "brcm,bcm2835-smi",}, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_smi_of_match); ++ ++static struct platform_driver bcm2835_smi_driver = { ++ .probe = bcm2835_smi_probe, ++ .remove = bcm2835_smi_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_smi_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_smi_driver); ++ ++MODULE_ALIAS("platform:smi-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Device driver for BCM2835's secondary memory interface"); ++MODULE_AUTHOR("Luke Wren "); +diff --git a/include/linux/broadcom/bcm2835_smi.h b/include/linux/broadcom/bcm2835_smi.h +new file mode 100644 +index 0000000..ee3a75e +--- /dev/null ++++ b/include/linux/broadcom/bcm2835_smi.h +@@ -0,0 +1,391 @@ ++/** ++ * Declarations and definitions for Broadcom's Secondary Memory Interface ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. ++ */ ++ ++#ifndef BCM2835_SMI_H ++#define BCM2835_SMI_H ++ ++#include ++ ++#ifndef __KERNEL__ ++#include ++#include ++#endif ++ ++#define BCM2835_SMI_IOC_MAGIC 0x1 ++#define BCM2835_SMI_INVALID_HANDLE (~0) ++ ++/* IOCTLs 0x100...0x1ff are not device-specific - we can use them */ ++#define BCM2835_SMI_IOC_GET_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 0) ++#define BCM2835_SMI_IOC_WRITE_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 1) ++#define BCM2835_SMI_IOC_ADDRESS _IO(BCM2835_SMI_IOC_MAGIC, 2) ++#define BCM2835_SMI_IOC_MAX 2 ++ ++#define SMI_WIDTH_8BIT 0 ++#define SMI_WIDTH_16BIT 1 ++#define SMI_WIDTH_9BIT 2 ++#define SMI_WIDTH_18BIT 3 ++ ++/* max number of bytes where DMA will not be used */ ++#define DMA_THRESHOLD_BYTES 128 ++#define DMA_BOUNCE_BUFFER_SIZE (1024 * 1024 / 2) ++#define DMA_BOUNCE_BUFFER_COUNT 3 ++ ++ ++struct smi_settings { ++ int data_width; ++ /* Whether or not to pack multiple SMI transfers into a ++ single 32 bit FIFO word */ ++ bool pack_data; ++ ++ /* Timing for reads (writes the same but for WE) ++ * ++ * OE ----------+ +-------------------- ++ * | | ++ * +----------+ ++ * SD -<==============================>----------- ++ * SA -<=========================================>- ++ * <-setup-> <-strobe -> <-hold -> <- pace -> ++ */ ++ ++ int read_setup_time; ++ int read_hold_time; ++ int read_pace_time; ++ int read_strobe_time; ++ ++ int write_setup_time; ++ int write_hold_time; ++ int write_pace_time; ++ int write_strobe_time; ++ ++ bool dma_enable; /* DREQs */ ++ bool dma_passthrough_enable; /* External DREQs */ ++ int dma_read_thresh; ++ int dma_write_thresh; ++ int dma_panic_read_thresh; ++ int dma_panic_write_thresh; ++}; ++ ++/**************************************************************************** ++* ++* Declare exported SMI functions ++* ++***************************************************************************/ ++ ++#ifdef __KERNEL__ ++ ++#include /* for enum dma_transfer_direction */ ++#include ++#include ++ ++struct bcm2835_smi_instance; ++ ++struct bcm2835_smi_bounce_info { ++ struct semaphore callback_sem; ++ void *buffer[DMA_BOUNCE_BUFFER_COUNT]; ++ dma_addr_t phys[DMA_BOUNCE_BUFFER_COUNT]; ++ struct scatterlist sgl[DMA_BOUNCE_BUFFER_COUNT]; ++}; ++ ++ ++void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *); ++ ++struct smi_settings *bcm2835_smi_get_settings_from_regs( ++ struct bcm2835_smi_instance *inst); ++ ++void bcm2835_smi_write_buf( ++ struct bcm2835_smi_instance *inst, ++ const void *buf, ++ size_t n_bytes); ++ ++void bcm2835_smi_read_buf( ++ struct bcm2835_smi_instance *inst, ++ void *buf, ++ size_t n_bytes); ++ ++void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, ++ unsigned int address); ++ ++ssize_t bcm2835_smi_user_dma( ++ struct bcm2835_smi_instance *inst, ++ enum dma_transfer_direction dma_dir, ++ char __user *user_ptr, ++ size_t count, ++ struct bcm2835_smi_bounce_info **bounce); ++ ++struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node); ++ ++#endif /* __KERNEL__ */ ++ ++/**************************************************************** ++* ++* Implementation-only declarations ++* ++****************************************************************/ ++ ++#ifdef BCM2835_SMI_IMPLEMENTATION ++ ++/* Clock manager registers for SMI clock: */ ++#define CM_SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x1010b0) ++/* Clock manager "password" to protect registers from spurious writes */ ++#define CM_PWD (0x5a << 24) ++ ++#define CM_SMI_CTL 0x00 ++#define CM_SMI_DIV 0x04 ++ ++#define CM_SMI_CTL_FLIP (1 << 8) ++#define CM_SMI_CTL_BUSY (1 << 7) ++#define CM_SMI_CTL_KILL (1 << 5) ++#define CM_SMI_CTL_ENAB (1 << 4) ++#define CM_SMI_CTL_SRC_MASK (0xf) ++#define CM_SMI_CTL_SRC_OFFS (0) ++ ++#define CM_SMI_DIV_DIVI_MASK (0xf << 12) ++#define CM_SMI_DIV_DIVI_OFFS (12) ++#define CM_SMI_DIV_DIVF_MASK (0xff << 4) ++#define CM_SMI_DIV_DIVF_OFFS (4) ++ ++/* SMI register mapping:*/ ++#define SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x600000) ++ ++#define SMICS 0x00 /* control + status register */ ++#define SMIL 0x04 /* length/count (n external txfers) */ ++#define SMIA 0x08 /* address register */ ++#define SMID 0x0c /* data register */ ++#define SMIDSR0 0x10 /* device 0 read settings */ ++#define SMIDSW0 0x14 /* device 0 write settings */ ++#define SMIDSR1 0x18 /* device 1 read settings */ ++#define SMIDSW1 0x1c /* device 1 write settings */ ++#define SMIDSR2 0x20 /* device 2 read settings */ ++#define SMIDSW2 0x24 /* device 2 write settings */ ++#define SMIDSR3 0x28 /* device 3 read settings */ ++#define SMIDSW3 0x2c /* device 3 write settings */ ++#define SMIDC 0x30 /* DMA control registers */ ++#define SMIDCS 0x34 /* direct control/status register */ ++#define SMIDA 0x38 /* direct address register */ ++#define SMIDD 0x3c /* direct data registers */ ++#define SMIFD 0x40 /* FIFO debug register */ ++ ++ ++ ++/* Control and Status register bits: ++ * SMICS_RXF : RX fifo full: 1 when RX fifo is full ++ * SMICS_TXE : TX fifo empty: 1 when empty. ++ * SMICS_RXD : RX fifo contains data: 1 when there is data. ++ * SMICS_TXD : TX fifo can accept data: 1 when true. ++ * SMICS_RXR : RX fifo needs reading: 1 when fifo more than 3/4 full, or ++ * when "DONE" and fifo not emptied. ++ * SMICS_TXW : TX fifo needs writing: 1 when less than 1/4 full. ++ * SMICS_AFERR : AXI FIFO error: 1 when fifo read when empty or written ++ * when full. Write 1 to clear. ++ * SMICS_EDREQ : 1 when external DREQ received. ++ * SMICS_PXLDAT : Pixel data: write 1 to enable pixel transfer modes. ++ * SMICS_SETERR : 1 if there was an error writing to setup regs (e.g. ++ * tx was in progress). Write 1 to clear. ++ * SMICS_PVMODE : Set to 1 to enable pixel valve mode. ++ * SMICS_INTR : Set to 1 to enable interrupt on RX. ++ * SMICS_INTT : Set to 1 to enable interrupt on TX. ++ * SMICS_INTD : Set to 1 to enable interrupt on DONE condition. ++ * SMICS_TEEN : Tear effect mode enabled: Programmed transfers will wait ++ * for a TE trigger before writing. ++ * SMICS_PAD1 : Padding settings for external transfers. For writes: the ++ * number of bytes initially written to the TX fifo that ++ * SMICS_PAD0 : should be ignored. For reads: the number of bytes that will ++ * be read before the data, and should be dropped. ++ * SMICS_WRITE : Transfer direction: 1 = write to external device, 0 = read ++ * SMICS_CLEAR : Write 1 to clear the FIFOs. ++ * SMICS_START : Write 1 to start the programmed transfer. ++ * SMICS_ACTIVE : Reads as 1 when a programmed transfer is underway. ++ * SMICS_DONE : Reads as 1 when transfer finished. For RX, not set until ++ * FIFO emptied. ++ * SMICS_ENABLE : Set to 1 to enable the SMI peripheral, 0 to disable. ++ */ ++ ++#define SMICS_RXF (1 << 31) ++#define SMICS_TXE (1 << 30) ++#define SMICS_RXD (1 << 29) ++#define SMICS_TXD (1 << 28) ++#define SMICS_RXR (1 << 27) ++#define SMICS_TXW (1 << 26) ++#define SMICS_AFERR (1 << 25) ++#define SMICS_EDREQ (1 << 15) ++#define SMICS_PXLDAT (1 << 14) ++#define SMICS_SETERR (1 << 13) ++#define SMICS_PVMODE (1 << 12) ++#define SMICS_INTR (1 << 11) ++#define SMICS_INTT (1 << 10) ++#define SMICS_INTD (1 << 9) ++#define SMICS_TEEN (1 << 8) ++#define SMICS_PAD1 (1 << 7) ++#define SMICS_PAD0 (1 << 6) ++#define SMICS_WRITE (1 << 5) ++#define SMICS_CLEAR (1 << 4) ++#define SMICS_START (1 << 3) ++#define SMICS_ACTIVE (1 << 2) ++#define SMICS_DONE (1 << 1) ++#define SMICS_ENABLE (1 << 0) ++ ++/* Address register bits: */ ++ ++#define SMIA_DEVICE_MASK ((1 << 9) | (1 << 8)) ++#define SMIA_DEVICE_OFFS (8) ++#define SMIA_ADDR_MASK (0x3f) /* bits 5 -> 0 */ ++#define SMIA_ADDR_OFFS (0) ++ ++/* DMA control register bits: ++ * SMIDC_DMAEN : DMA enable: set 1: DMA requests will be issued. ++ * SMIDC_DMAP : DMA passthrough: when set to 0, top two data pins are used by ++ * SMI as usual. When set to 1, the top two pins are used for ++ * external DREQs: pin 16 read request, 17 write. ++ * SMIDC_PANIC* : Threshold at which DMA will panic during read/write. ++ * SMIDC_REQ* : Threshold at which DMA will generate a DREQ. ++ */ ++ ++#define SMIDC_DMAEN (1 << 28) ++#define SMIDC_DMAP (1 << 24) ++#define SMIDC_PANICR_MASK (0x3f << 18) ++#define SMIDC_PANICR_OFFS (18) ++#define SMIDC_PANICW_MASK (0x3f << 12) ++#define SMIDC_PANICW_OFFS (12) ++#define SMIDC_REQR_MASK (0x3f << 6) ++#define SMIDC_REQR_OFFS (6) ++#define SMIDC_REQW_MASK (0x3f) ++#define SMIDC_REQW_OFFS (0) ++ ++/* Device settings register bits: same for all 4 (or 3?) device register sets. ++ * Device read settings: ++ * SMIDSR_RWIDTH : Read transfer width. 00 = 8bit, 01 = 16bit, ++ * 10 = 18bit, 11 = 9bit. ++ * SMIDSR_RSETUP : Read setup time: number of core cycles between chip ++ * select/address and read strobe. Min 1, max 64. ++ * SMIDSR_MODE68 : 1 for System 68 mode (i.e. enable + direction pins, ++ * rather than OE + WE pin) ++ * SMIDSR_FSETUP : If set to 1, setup time only applies to first ++ * transfer after address change. ++ * SMIDSR_RHOLD : Number of core cycles between read strobe going ++ * inactive and CS/address going inactive. Min 1, max 64 ++ * SMIDSR_RPACEALL : When set to 1, this device's RPACE value will always ++ * be used for the next transaction, even if it is not ++ * to this device. ++ * SMIDSR_RPACE : Number of core cycles spent waiting between CS ++ * deassert and start of next transfer. Min 1, max 128 ++ * SMIDSR_RDREQ : 1 = use external DMA request on SD16 to pace reads ++ * from device. Must also set DMAP in SMICS. ++ * SMIDSR_RSTROBE : Number of cycles to assert the read strobe. ++ * min 1, max 128. ++ */ ++#define SMIDSR_RWIDTH_MASK ((1<<31)|(1<<30)) ++#define SMIDSR_RWIDTH_OFFS (30) ++#define SMIDSR_RSETUP_MASK (0x3f << 24) ++#define SMIDSR_RSETUP_OFFS (24) ++#define SMIDSR_MODE68 (1 << 23) ++#define SMIDSR_FSETUP (1 << 22) ++#define SMIDSR_RHOLD_MASK (0x3f << 16) ++#define SMIDSR_RHOLD_OFFS (16) ++#define SMIDSR_RPACEALL (1 << 15) ++#define SMIDSR_RPACE_MASK (0x7f << 8) ++#define SMIDSR_RPACE_OFFS (8) ++#define SMIDSR_RDREQ (1 << 7) ++#define SMIDSR_RSTROBE_MASK (0x7f) ++#define SMIDSR_RSTROBE_OFFS (0) ++ ++/* Device write settings: ++ * SMIDSW_WWIDTH : Write transfer width. 00 = 8bit, 01 = 16bit, ++ * 10= 18bit, 11 = 9bit. ++ * SMIDSW_WSETUP : Number of cycles between CS assert and write strobe. ++ * Min 1, max 64. ++ * SMIDSW_WFORMAT : Pixel format of input. 0 = 16bit RGB 565, ++ * 1 = 32bit RGBA 8888 ++ * SMIDSW_WSWAP : 1 = swap pixel data bits. (Use with SMICS_PXLDAT) ++ * SMIDSW_WHOLD : Time between WE deassert and CS deassert. 1 to 64 ++ * SMIDSW_WPACEALL : 1: this device's WPACE will be used for the next ++ * transfer, regardless of that transfer's device. ++ * SMIDSW_WPACE : Cycles between CS deassert and next CS assert. ++ * Min 1, max 128 ++ * SMIDSW_WDREQ : Use external DREQ on pin 17 to pace writes. DMAP must ++ * be set in SMICS. ++ * SMIDSW_WSTROBE : Number of cycles to assert the write strobe. ++ * Min 1, max 128 ++ */ ++#define SMIDSW_WWIDTH_MASK ((1<<31)|(1<<30)) ++#define SMIDSW_WWIDTH_OFFS (30) ++#define SMIDSW_WSETUP_MASK (0x3f << 24) ++#define SMIDSW_WSETUP_OFFS (24) ++#define SMIDSW_WFORMAT (1 << 23) ++#define SMIDSW_WSWAP (1 << 22) ++#define SMIDSW_WHOLD_MASK (0x3f << 16) ++#define SMIDSW_WHOLD_OFFS (16) ++#define SMIDSW_WPACEALL (1 << 15) ++#define SMIDSW_WPACE_MASK (0x7f << 8) ++#define SMIDSW_WPACE_OFFS (8) ++#define SMIDSW_WDREQ (1 << 7) ++#define SMIDSW_WSTROBE_MASK (0x7f) ++#define SMIDSW_WSTROBE_OFFS (0) ++ ++/* Direct transfer control + status register ++ * SMIDCS_WRITE : Direction of transfer: 1 -> write, 0 -> read ++ * SMIDCS_DONE : 1 when a transfer has finished. Write 1 to clear. ++ * SMIDCS_START : Write 1 to start a transfer, if one is not already underway. ++ * SMIDCE_ENABLE: Write 1 to enable SMI in direct mode. ++ */ ++ ++#define SMIDCS_WRITE (1 << 3) ++#define SMIDCS_DONE (1 << 2) ++#define SMIDCS_START (1 << 1) ++#define SMIDCS_ENABLE (1 << 0) ++ ++/* Direct transfer address register ++ * SMIDA_DEVICE : Indicates which of the device settings banks should be used. ++ * SMIDA_ADDR : The value to be asserted on the address pins. ++ */ ++ ++#define SMIDA_DEVICE_MASK ((1<<9)|(1<<8)) ++#define SMIDA_DEVICE_OFFS (8) ++#define SMIDA_ADDR_MASK (0x3f) ++#define SMIDA_ADDR_OFFS (0) ++ ++/* FIFO debug register ++ * SMIFD_FLVL : The high-tide mark of FIFO count during the most recent txfer ++ * SMIFD_FCNT : The current FIFO count. ++ */ ++#define SMIFD_FLVL_MASK (0x3f << 8) ++#define SMIFD_FLVL_OFFS (8) ++#define SMIFD_FCNT_MASK (0x3f) ++#define SMIFD_FCNT_OFFS (0) ++ ++#endif /* BCM2835_SMI_IMPLEMENTATION */ ++ ++#endif /* BCM2835_SMI_H */ + +From d263fa3cf01ecca6447ce0f62a43c33d715a27de Mon Sep 17 00:00:00 2001 +From: Luke Wren +Date: Sat, 5 Sep 2015 01:16:10 +0100 +Subject: [PATCH 028/113] Add SMI NAND driver + +Signed-off-by: Luke Wren +--- + .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++ + drivers/mtd/nand/Kconfig | 7 + + drivers/mtd/nand/Makefile | 1 + + drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++ + 4 files changed, 318 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt + create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c + +diff --git a/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt +new file mode 100644 +index 0000000..159544d +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt +@@ -0,0 +1,42 @@ ++* BCM2835 SMI NAND flash ++ ++This driver is a shim between the BCM2835 SMI driver (SMI is a peripheral for ++talking to parallel register interfaces) and Linux's MTD layer. ++ ++Required properties: ++- compatible: "brcm,bcm2835-smi-nand" ++- status: "okay" ++ ++Optional properties: ++- partition@n, where n is an integer from a consecutive sequence starting at 0 ++ - Difficult to store partition table on NAND device - normally put it ++ in the source code, kernel bootparams, or device tree (the best way!) ++ - Sub-properties: ++ - label: the partition name, as shown by mtdinfo /dev/mtd* ++ - reg: the size and offset of this partition. ++ - (optional) read-only: an empty property flagging as read only ++ ++Example: ++ ++nand: flash@0 { ++ compatible = "brcm,bcm2835-smi-nand"; ++ status = "okay"; ++ ++ partition@0 { ++ label = "stage2"; ++ // 128k ++ reg = <0 0x20000>; ++ read-only; ++ }; ++ partition@1 { ++ label = "firmware"; ++ // 16M ++ reg = <0x20000 0x1000000>; ++ read-only; ++ }; ++ partition@2 { ++ label = "root"; ++ // 2G ++ reg = <0x1020000 0x80000000>; ++ }; ++}; +\ No newline at end of file +diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig +index 3324281..1dc71d9 100644 +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -41,6 +41,13 @@ config MTD_SM_COMMON + tristate + default n + ++config MTD_NAND_BCM2835_SMI ++ tristate "Use Broadcom's Secondary Memory Interface as a NAND controller (BCM283x)" ++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI && MTD_NAND ++ default m ++ help ++ Uses the BCM2835's SMI peripheral as a NAND controller. ++ + config MTD_NAND_DENALI + tristate + +diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile +index 075a027..fad42ff 100644 +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o + obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o + obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o + obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o ++obj-$(CONFIG_MTD_NAND_BCM2835_SMI) += bcm2835_smi_nand.o + obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o + obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o + obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o +diff --git a/drivers/mtd/nand/bcm2835_smi_nand.c b/drivers/mtd/nand/bcm2835_smi_nand.c +new file mode 100644 +index 0000000..b747326 +--- /dev/null ++++ b/drivers/mtd/nand/bcm2835_smi_nand.c +@@ -0,0 +1,268 @@ ++/** ++ * NAND flash driver for Broadcom Secondary Memory Interface ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DEVICE_NAME "bcm2835-smi-nand" ++#define DRIVER_NAME "smi-nand-bcm2835" ++ ++struct bcm2835_smi_nand_host { ++ struct bcm2835_smi_instance *smi_inst; ++ struct nand_chip nand_chip; ++ struct mtd_info mtd; ++ struct device *dev; ++}; ++ ++/**************************************************************************** ++* ++* NAND functionality implementation ++* ++****************************************************************************/ ++ ++#define SMI_NAND_CLE_PIN 0x01 ++#define SMI_NAND_ALE_PIN 0x02 ++ ++static inline void bcm2835_smi_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, ++ unsigned int ctrl) ++{ ++ uint32_t cmd32 = cmd; ++ uint32_t addr = ~(SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ if (ctrl & NAND_CLE) ++ addr |= SMI_NAND_CLE_PIN; ++ if (ctrl & NAND_ALE) ++ addr |= SMI_NAND_ALE_PIN; ++ /* Lower ALL the CS pins! */ ++ if (ctrl & NAND_NCE) ++ addr &= (SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); ++ ++ bcm2835_smi_set_address(inst, addr); ++ ++ if (cmd != NAND_CMD_NONE) ++ bcm2835_smi_write_buf(inst, &cmd32, 1); ++} ++ ++static inline uint8_t bcm2835_smi_nand_read_byte(struct mtd_info *mtd) ++{ ++ uint8_t byte; ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_read_buf(inst, &byte, 1); ++ return byte; ++} ++ ++static inline void bcm2835_smi_nand_write_byte(struct mtd_info *mtd, ++ uint8_t byte) ++{ ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_write_buf(inst, &byte, 1); ++} ++ ++static inline void bcm2835_smi_nand_write_buf(struct mtd_info *mtd, ++ const uint8_t *buf, int len) ++{ ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_write_buf(inst, buf, len); ++} ++ ++static inline void bcm2835_smi_nand_read_buf(struct mtd_info *mtd, ++ uint8_t *buf, int len) ++{ ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_read_buf(inst, buf, len); ++} ++ ++/**************************************************************************** ++* ++* Probe and remove functions ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_nand_probe(struct platform_device *pdev) ++{ ++ struct bcm2835_smi_nand_host *host; ++ struct nand_chip *this; ++ struct mtd_info *mtd; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node, *smi_node; ++ struct mtd_part_parser_data ppdata; ++ struct smi_settings *smi_settings; ++ struct bcm2835_smi_instance *smi_inst; ++ int ret = -ENXIO; ++ ++ if (!node) { ++ dev_err(dev, "No device tree node supplied!"); ++ return -EINVAL; ++ } ++ ++ smi_node = of_parse_phandle(node, "smi_handle", 0); ++ ++ /* Request use of SMI peripheral: */ ++ smi_inst = bcm2835_smi_get(smi_node); ++ ++ if (!smi_inst) { ++ dev_err(dev, "Could not register with SMI."); ++ return -EPROBE_DEFER; ++ } ++ ++ /* Set SMI timing and bus width */ ++ ++ smi_settings = bcm2835_smi_get_settings_from_regs(smi_inst); ++ ++ smi_settings->data_width = SMI_WIDTH_8BIT; ++ smi_settings->read_setup_time = 2; ++ smi_settings->read_hold_time = 1; ++ smi_settings->read_pace_time = 1; ++ smi_settings->read_strobe_time = 3; ++ ++ smi_settings->write_setup_time = 2; ++ smi_settings->write_hold_time = 1; ++ smi_settings->write_pace_time = 1; ++ smi_settings->write_strobe_time = 3; ++ ++ bcm2835_smi_set_regs_from_settings(smi_inst); ++ ++ host = devm_kzalloc(dev, sizeof(struct bcm2835_smi_nand_host), ++ GFP_KERNEL); ++ if (!host) ++ return -ENOMEM; ++ ++ host->dev = dev; ++ host->smi_inst = smi_inst; ++ ++ platform_set_drvdata(pdev, host); ++ ++ /* Link the structures together */ ++ ++ this = &host->nand_chip; ++ mtd = &host->mtd; ++ mtd->priv = this; ++ mtd->owner = THIS_MODULE; ++ mtd->dev.parent = dev; ++ mtd->name = DRIVER_NAME; ++ ppdata.of_node = node; ++ ++ /* 20 us command delay time... */ ++ this->chip_delay = 20; ++ ++ this->priv = host; ++ this->cmd_ctrl = bcm2835_smi_nand_cmd_ctrl; ++ this->read_byte = bcm2835_smi_nand_read_byte; ++ this->write_byte = bcm2835_smi_nand_write_byte; ++ this->write_buf = bcm2835_smi_nand_write_buf; ++ this->read_buf = bcm2835_smi_nand_read_buf; ++ ++ this->ecc.mode = NAND_ECC_SOFT; ++ ++ /* Should never be accessed directly: */ ++ ++ this->IO_ADDR_R = (void *)0xdeadbeef; ++ this->IO_ADDR_W = (void *)0xdeadbeef; ++ ++ /* First scan to find the device and get the page size */ ++ ++ if (nand_scan_ident(mtd, 1, NULL)) ++ return -ENXIO; ++ ++ /* Second phase scan */ ++ ++ if (nand_scan_tail(mtd)) ++ return -ENXIO; ++ ++ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); ++ if (!ret) ++ return 0; ++ ++ nand_release(mtd); ++ return -EINVAL; ++} ++ ++static int bcm2835_smi_nand_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_smi_nand_host *host = platform_get_drvdata(pdev); ++ ++ nand_release(&host->mtd); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_smi_nand_of_match[] = { ++ {.compatible = "brcm,bcm2835-smi-nand",}, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_smi_nand_of_match); ++ ++static struct platform_driver bcm2835_smi_nand_driver = { ++ .probe = bcm2835_smi_nand_probe, ++ .remove = bcm2835_smi_nand_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_smi_nand_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_smi_nand_driver); ++ ++MODULE_ALIAS("platform:smi-nand-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION ++ ("Driver for NAND chips using Broadcom Secondary Memory Interface"); ++MODULE_AUTHOR("Luke Wren "); + +From e28e00facc7bc54d995a0111f3a301cf3d5cadc7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:51:55 +0100 -Subject: [PATCH 015/204] Add hwrng (hardware random number generator) driver +Subject: [PATCH 029/113] Add hwrng (hardware random number generator) driver --- drivers/char/hw_random/Kconfig | 13 +++- @@ -101823,10 +105748,10 @@ index 0000000..340f004 +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL and additional rights"); -From 0f09a4b263925916b493657ad19334d1b62ee299 Mon Sep 17 00:00:00 2001 +From fa1c1a7ff57c800a80cb50c0ed4908e098bc8d66 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 016/204] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 030/113] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -102679,29 +106604,29 @@ index 0000000..24563ec +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -From 7dc35f47e29f40755b9a66b6c1b8f693d0a7e414 Mon Sep 17 00:00:00 2001 +From 72e14f691b5b697160bb2bc0926ff3adb3672ef0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 017/204] Add cpufreq driver +Subject: [PATCH 031/113] Add cpufreq driver Signed-off-by: popcornmix --- drivers/cpufreq/Kconfig.arm | 9 ++ drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/bcm2835-cpufreq.c | 224 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 234 insertions(+) + drivers/cpufreq/bcm2835-cpufreq.c | 213 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 223 insertions(+) create mode 100644 drivers/cpufreq/bcm2835-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index 4f3dbc8..a1039f0 100644 +index cd0391e..d54b721 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm -@@ -258,6 +258,15 @@ config ARM_SPEAR_CPUFREQ +@@ -206,6 +206,15 @@ config ARM_SPEAR_CPUFREQ help This adds the CPUFreq driver support for SPEAr SOCs. +config ARM_BCM2835_CPUFREQ -+ depends on BCM2708_MBOX ++ depends on RASPBERRYPI_FIRMWARE + bool "BCM2835 Driver" + default y + help @@ -102709,27 +106634,27 @@ index 4f3dbc8..a1039f0 100644 + + If in doubt, say N. + - config ARM_TEGRA_CPUFREQ - bool "TEGRA CPUFreq support" + config ARM_TEGRA20_CPUFREQ + bool "Tegra20 CPUFreq support" depends on ARCH_TEGRA diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index cdce92a..c420f3f 100644 +index 4134038..51ce004 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile -@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o +@@ -73,6 +73,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o +obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o - obj-$(CONFIG_ARM_TEGRA_CPUFREQ) += tegra-cpufreq.o + obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o + obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o - diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c new file mode 100644 -index 0000000..6735da9 +index 0000000..3eb9e93 --- /dev/null +++ b/drivers/cpufreq/bcm2835-cpufreq.c -@@ -0,0 +1,224 @@ +@@ -0,0 +1,213 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -102758,7 +106683,7 @@ index 0000000..6735da9 +#include +#include +#include -+#include ++#include + +/* ---------- DEFINES ---------- */ +/*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ @@ -102775,23 +106700,6 @@ index 0000000..6735da9 +#define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) +#define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__) + -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the message id */ -+ uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -+ uint32_t data_size; /* amount of data being sent or received */ -+ uint32_t dev_id; /* the ID of the clock/voltage to get or set */ -+ uint32_t val; /* the value (e.g. rate (in Hz)) to set */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ +/* ---------- GLOBALS ---------- */ +static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */ + @@ -102806,62 +106714,63 @@ index 0000000..6735da9 + clk_rate either gets or sets the clock rates. + =============================================== +*/ ++ ++static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) ++{ ++ struct rpi_firmware *fw = rpi_firmware_get(NULL); ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ int ret; ++ ++ packet.id = id; ++ packet.val = *val; ++ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); ++ if (ret) ++ return ret; ++ ++ *val = packet.val; ++ ++ return 0; ++} ++ +static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) +{ -+ int s, actual_rate=0; -+ struct vc_msg msg; ++ u32 rate = arm_rate * 1000; ++ int ret; + -+ /* wipe all previous message data */ -+ memset(&msg, 0, sizeof msg); ++ ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate); ++ if (ret) { ++ print_err("Failed to set clock: %d (%d)\n", arm_rate, ret); ++ return 0; ++ } + -+ msg.msg_size = sizeof msg; ++ rate /= 1000; ++ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate); + -+ msg.tag.tag_id = VCMSG_SET_CLOCK_RATE; -+ msg.tag.buffer_size = 8; -+ msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */ -+ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; -+ msg.tag.val = arm_rate * 1000; -+ -+ /* send the message */ -+ s = bcm_mailbox_property(&msg, sizeof msg); -+ -+ /* check if it was all ok and return the rate in KHz */ -+ if (s == 0 && (msg.request_code & 0x80000000)) -+ actual_rate = msg.tag.val/1000; -+ -+ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate); -+ return actual_rate; ++ return rate; +} + +static uint32_t bcm2835_cpufreq_get_clock(int tag) +{ -+ int s; -+ int arm_rate = 0; -+ struct vc_msg msg; ++ u32 rate; ++ int ret; + -+ /* wipe all previous message data */ -+ memset(&msg, 0, sizeof msg); ++ ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate); ++ if (ret) { ++ print_err("Failed to get clock (%d)\n", ret); ++ return 0; ++ } + -+ msg.msg_size = sizeof msg; -+ msg.tag.tag_id = tag; -+ msg.tag.buffer_size = 8; -+ msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */ -+ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; ++ rate /= 1000; ++ print_debug("%s frequency = %u\n", ++ tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current": ++ tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min": ++ tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max": ++ "Unexpected", rate); + -+ /* send the message */ -+ s = bcm_mailbox_property(&msg, sizeof msg); -+ -+ /* check if it was all ok and return the rate in KHz */ -+ if (s == 0 && (msg.request_code & 0x80000000)) -+ arm_rate = msg.tag.val/1000; -+ -+ print_debug("%s frequency = %d\n", -+ tag == VCMSG_GET_CLOCK_RATE ? "Current": -+ tag == VCMSG_GET_MIN_CLOCK ? "Min": -+ tag == VCMSG_GET_MAX_CLOCK ? "Max": -+ "Unexpected", arm_rate); -+ -+ return arm_rate; ++ return rate; +} + +/* @@ -102897,9 +106806,14 @@ index 0000000..6735da9 + /* measured value of how long it takes to change frequency */ + const unsigned int transition_latency = 355000; /* ns */ + ++ if (!rpi_firmware_get(NULL)) { ++ print_err("Firmware is not available\n"); ++ return -ENODEV; ++ } ++ + /* now find out what the maximum and minimum frequencies are */ -+ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK); -+ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK); ++ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); ++ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); + + print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency); + return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency); @@ -102933,8 +106847,8 @@ index 0000000..6735da9 + +static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu) +{ -+ unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE); -+ print_debug("%d: freq=%d\n", cpu, actual_rate); ++ unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE); ++ print_debug("cpu%d: freq=%d\n", cpu, actual_rate); + return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency; +} + @@ -102955,10 +106869,10 @@ index 0000000..6735da9 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From d8057ff6ba5dece8ae393713e563362dc53bbde4 Mon Sep 17 00:00:00 2001 +From 9a6fb64fe686eca62c0d649cbae566e4626d32e3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 018/204] Added hwmon/thermal driver for reporting core +Subject: [PATCH 032/113] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -102976,15 +106890,15 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2709/bcm2709.c | 6 ++ drivers/thermal/Kconfig | 7 ++ drivers/thermal/Makefile | 1 + - drivers/thermal/bcm2835-thermal.c | 190 ++++++++++++++++++++++++++++++++++++++ - 5 files changed, 210 insertions(+) + drivers/thermal/bcm2835-thermal.c | 141 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 161 insertions(+) create mode 100644 drivers/thermal/bcm2835-thermal.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index ecf0524..978aaff 100644 +index 541ee37..30b77dc 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -505,6 +505,10 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -494,6 +494,10 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -102995,9 +106909,9 @@ index ecf0524..978aaff 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -651,6 +655,8 @@ void __init bcm2708_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -645,6 +649,8 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2835_thermal_device); + @@ -103005,10 +106919,10 @@ index ecf0524..978aaff 100644 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index de9feaa..0e5c8e3 100644 +index 0a7bd3e..c6341ba 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -525,6 +525,10 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -510,6 +510,10 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103019,9 +106933,9 @@ index de9feaa..0e5c8e3 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -671,6 +675,8 @@ void __init bcm2709_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -662,6 +666,8 @@ void __init bcm2709_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2835_thermal_device); + @@ -103029,15 +106943,15 @@ index de9feaa..0e5c8e3 100644 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index af40db0..ddc77ad 100644 +index 5aabc4b..748880c 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig -@@ -238,6 +238,13 @@ config INTEL_POWERCLAMP +@@ -271,6 +271,13 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. +config THERMAL_BCM2835 -+ depends on BCM2708_MBOX ++ depends on RASPBERRYPI_FIRMWARE + tristate "BCM2835 Thermal Driver" + help + This will enable temperature monitoring for the Broadcom BCM2835 @@ -103047,23 +106961,23 @@ index af40db0..ddc77ad 100644 tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile -index fa0dc48..453d4d9 100644 +index 26f1608..61b0d4f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile -@@ -33,6 +33,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o +@@ -35,6 +35,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o +obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o + obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE) += intel_soc_dts_iosf.o obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o - obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c new file mode 100644 -index 0000000..3bc80f1 +index 0000000..c1d8f1b --- /dev/null +++ b/drivers/thermal/bcm2835-thermal.c -@@ -0,0 +1,190 @@ +@@ -0,0 +1,141 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -103078,161 +106992,113 @@ index 0000000..3bc80f1 +* consent. +*****************************************************************************/ + -+#include +#include -+#include -+#include +#include -+#include -+#include +#include ++#include + -+ -+/* --- DEFINITIONS --- */ -+#define MODULE_NAME "bcm2835_thermal" -+ -+/*#define THERMAL_DEBUG_ENABLE*/ -+ -+#ifdef THERMAL_DEBUG_ENABLE -+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) -+#else -+#define print_debug(fmt,...) -+#endif -+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) -+ -+#define VC_TAG_GET_TEMP 0x00030006 -+#define VC_TAG_GET_MAX_TEMP 0x0003000A -+ -+typedef enum { -+ TEMP, -+ MAX_TEMP, -+} temp_type; -+ -+/* --- STRUCTS --- */ -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the tag ID for the temperature */ -+ uint32_t buffer_size; /* size of the buffer (should be 8) */ -+ uint32_t request_code; /* identifies message as a request (should be 0) */ -+ uint32_t id; /* extra ID field (should be 0) */ -+ uint32_t val; /* returned value of the temperature */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ -+struct bcm2835_thermal_data { -+ struct thermal_zone_device *thermal_dev; -+ struct vc_msg msg; -+}; -+ -+/* --- GLOBALS --- */ -+static struct bcm2835_thermal_data bcm2835_data; -+ -+/* Thermal Device Operations */ -+static struct thermal_zone_device_ops ops; -+ -+/* --- FUNCTIONS --- */ -+ -+static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id) ++static int bcm2835_thermal_get_property(struct thermal_zone_device *tz, ++ unsigned long *temp, u32 tag) +{ -+ int result = -1, retry = 3; -+ print_debug("IN"); ++ struct rpi_firmware *fw = tz->devdata; ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ int ret; + + *temp = 0; -+ while (result != 0 && retry-- > 0) { -+ /* wipe all previous message data */ -+ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg); -+ -+ /* prepare message */ -+ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg; -+ bcm2835_data.msg.tag.buffer_size = 8; -+ bcm2835_data.msg.tag.tag_id = tag_id; -+ -+ /* send the message */ -+ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg); -+ print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code); -+ if (!(bcm2835_data.msg.request_code & 0x80000000)) -+ result = -1; ++ packet.id = 0; ++ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); ++ if (ret) { ++ dev_err(&tz->device, "Failed to get temperature\n"); ++ return ret; + } + -+ /* check if it was all ok and return the rate in milli degrees C */ -+ if (result == 0) -+ *temp = (uint)bcm2835_data.msg.tag.val; -+ else -+ print_err("Failed to get temperature! (%x:%d)\n", tag_id, result); -+ print_debug("OUT"); -+ return result; -+} ++ *temp = packet.val; ++ dev_dbg(&tz->device, "%stemp=%lu\n", ++ tag == RPI_FIRMWARE_GET_MAX_TEMPERATURE ? "max" : "", *temp); + -+static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp) -+{ -+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP); -+} -+ -+static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp) -+{ -+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP); -+} -+ -+static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type) -+{ -+ *trip_type = THERMAL_TRIP_HOT; + return 0; +} + -+ -+static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode) ++static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz, ++ unsigned long *temp) +{ -+ *dev_mode = THERMAL_DEVICE_ENABLED; ++ return bcm2835_thermal_get_property(tz, temp, ++ RPI_FIRMWARE_GET_TEMPERATURE); ++} ++ ++static int bcm2835_thermal_get_max_temp(struct thermal_zone_device *tz, ++ int trip, unsigned long *temp) ++{ ++ /* ++ * The maximum safe temperature of the SoC. ++ * Overclock may be disabled above this temperature. ++ */ ++ return bcm2835_thermal_get_property(tz, temp, ++ RPI_FIRMWARE_GET_MAX_TEMPERATURE); ++} ++ ++static int bcm2835_thermal_get_trip_type(struct thermal_zone_device *tz, ++ int trip, enum thermal_trip_type *type) ++{ ++ *type = THERMAL_TRIP_HOT; ++ + return 0; +} + -+ -+static int bcm2835_thermal_probe(struct platform_device *pdev) ++static int bcm2835_thermal_get_mode(struct thermal_zone_device *tz, ++ enum thermal_device_mode *mode) +{ -+ print_debug("IN"); -+ print_debug("THERMAL Driver has been probed!"); -+ -+ /* check that the device isn't null!*/ -+ if(pdev == NULL) -+ { -+ print_debug("Platform device is empty!"); -+ return -ENODEV; -+ } -+ -+ if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0))) -+ { -+ print_debug("Unable to register the thermal device!"); -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+ -+static int bcm2835_thermal_remove(struct platform_device *pdev) -+{ -+ print_debug("IN"); -+ -+ thermal_zone_device_unregister(bcm2835_data.thermal_dev); -+ -+ print_debug("OUT"); ++ *mode = THERMAL_DEVICE_ENABLED; + + return 0; +} + +static struct thermal_zone_device_ops ops = { -+ .get_temp = bcm2835_get_temp, -+ .get_trip_temp = bcm2835_get_max_temp, -+ .get_trip_type = bcm2835_get_trip_type, -+ .get_mode = bcm2835_get_mode, ++ .get_temp = bcm2835_thermal_get_temp, ++ .get_trip_temp = bcm2835_thermal_get_max_temp, ++ .get_trip_type = bcm2835_thermal_get_trip_type, ++ .get_mode = bcm2835_thermal_get_mode, +}; + ++static int bcm2835_thermal_probe(struct platform_device *pdev) ++{ ++ struct device_node *fw_np; ++ struct rpi_firmware *fw; ++ struct thermal_zone_device *tz; ++ ++ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++/* Remove comment when booting without Device Tree is no longer supported ++ if (!fw_np) { ++ dev_err(&pdev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++*/ ++ fw = rpi_firmware_get(fw_np); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ tz = thermal_zone_device_register("bcm2835_thermal", 1, 0, fw, &ops, ++ NULL, 0, 0); ++ if (IS_ERR(tz)) { ++ dev_err(&pdev->dev, "Failed to register the thermal device\n"); ++ return PTR_ERR(tz); ++ } ++ ++ platform_set_drvdata(pdev, tz); ++ ++ return 0; ++} ++ ++static int bcm2835_thermal_remove(struct platform_device *pdev) ++{ ++ thermal_zone_device_unregister(platform_get_drvdata(pdev)); ++ ++ return 0; ++} ++ +static const struct of_device_id bcm2835_thermal_of_match_table[] = { + { .compatible = "brcm,bcm2835-thermal", }, + {}, @@ -103243,22 +107109,21 @@ index 0000000..3bc80f1 + .probe = bcm2835_thermal_probe, + .remove = bcm2835_thermal_remove, + .driver = { -+ .name = "bcm2835_thermal", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_thermal_of_match_table, -+ }, ++ .name = "bcm2835_thermal", ++ .of_match_table = bcm2835_thermal_of_match_table, ++ }, +}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Dorian Peake"); -+MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); -+ +module_platform_driver(bcm2835_thermal_driver); ++ ++MODULE_AUTHOR("Dorian Peake"); ++MODULE_AUTHOR("Noralf Trønnes"); ++MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); ++MODULE_LICENSE("GPL"); -From 320c58bca444bc390f7eccfebbb529fe8e98ed10 Mon Sep 17 00:00:00 2001 +From 0e7a0a423a5a6a1f125ea03eb0dc9d2fd9344a26 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:41:33 +0100 -Subject: [PATCH 019/204] Add Chris Boot's spi driver. +Subject: [PATCH 033/113] Add Chris Boot's spi driver. spi: bcm2708: add device tree support @@ -103292,6 +107157,10 @@ This does not affect behaviour under the current clock implementation. Also add a missing clk_disable_unprepare() in the probe error path. Signed-off-by: Noralf Tronnes + +spi-bcm2708: Increase timeout from 150ms to 1s + +See: https://github.com/raspberrypi/linux/issues/260 --- arch/arm/mach-bcm2708/Kconfig | 7 + arch/arm/mach-bcm2708/bcm2708.c | 53 ++++ @@ -103319,10 +107188,10 @@ index 4cbda0c..68e3706 100644 + Binds spidev driver to the SPI0 master endmenu diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 978aaff..31ad9da 100644 +index 30b77dc..3e5181f 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -34,6 +34,7 @@ +@@ -35,6 +35,7 @@ #include #include #include @@ -103330,7 +107199,7 @@ index 978aaff..31ad9da 100644 #include #include -@@ -505,6 +506,50 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -494,6 +495,50 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103381,16 +107250,16 @@ index 978aaff..31ad9da 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -655,6 +700,8 @@ void __init bcm2708_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -649,6 +694,8 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2708_spi_device); + bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -665,6 +712,12 @@ void __init bcm2708_init(void) +@@ -659,6 +706,12 @@ void __init bcm2708_init(void) } system_rev = boardrev; system_serial_low = serial; @@ -103402,9 +107271,9 @@ index 978aaff..31ad9da 100644 +#endif } - static void timer_set_mode(enum clock_event_mode mode, + static int timer_set_oneshot(struct clock_event_device *unused) diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 0e5c8e3..6874633 100644 +index c6341ba..bb86982 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -34,6 +34,7 @@ @@ -103415,7 +107284,7 @@ index 0e5c8e3..6874633 100644 #include #include -@@ -525,6 +526,50 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -510,6 +511,50 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103466,16 +107335,16 @@ index 0e5c8e3..6874633 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -675,6 +720,8 @@ void __init bcm2709_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -666,6 +711,8 @@ void __init bcm2709_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2708_spi_device); + bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -685,6 +732,12 @@ void __init bcm2709_init(void) +@@ -676,6 +723,12 @@ void __init bcm2709_init(void) } system_rev = boardrev; system_serial_low = serial; @@ -103489,19 +107358,19 @@ index 0e5c8e3..6874633 100644 #ifdef SYSTEM_TIMER diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 72b0590..ea5e5de 100644 +index 4887f31..47ab8ee 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -77,7 +77,7 @@ config SPI_ATMEL - +@@ -78,7 +78,7 @@ config SPI_ATMEL config SPI_BCM2835 tristate "BCM2835 SPI controller" + depends on GPIOLIB - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST depends on GPIOLIB help This selects a driver for the Broadcom BCM2835 SPI master. -@@ -87,6 +87,14 @@ config SPI_BCM2835 +@@ -88,6 +88,14 @@ config SPI_BCM2835 is for the regular SPI controller. Slave mode operation is not also not supported. @@ -103517,7 +107386,7 @@ index 72b0590..ea5e5de 100644 tristate "SPI controller driver for ADI Blackfin5xx" depends on BLACKFIN && !BF60x diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile -index d8cbf65..0dcd03d 100644 +index 6a7f6f9..11bb1e7 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o @@ -103530,7 +107399,7 @@ index d8cbf65..0dcd03d 100644 obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c new file mode 100644 -index 0000000..041b5e2 +index 0000000..5c0214e --- /dev/null +++ b/drivers/spi/spi-bcm2708.c @@ -0,0 +1,635 @@ @@ -103606,9 +107475,9 @@ index 0000000..041b5e2 +#define SPI_CS_CS_10 0x00000002 +#define SPI_CS_CS_01 0x00000001 + -+#define SPI_TIMEOUT_MS 150 ++#define SPI_TIMEOUT_MS 1000 + -+#define DRV_NAME "bcm2708_spi" ++#define DRV_NAME "bcm2708_spi" + +struct bcm2708_spi { + spinlock_t lock; @@ -104170,10 +108039,10 @@ index 0000000..041b5e2 +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From db4e6f4abd7eb95d3224be99d7f04c791f4ceb8d Mon Sep 17 00:00:00 2001 +From 3040b3426c57b28ae1d5c7f173fe3a7697d51009 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 020/204] Add Chris Boot's i2c driver +Subject: [PATCH 034/113] Add Chris Boot's i2c driver i2c-bcm2708: fixed baudrate @@ -104224,20 +108093,44 @@ Fix grabbing lock from atomic context in i2c driver - Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock. i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl + +i2c-bcm2708: Increase timeouts to allow larger transfers + +Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting +for completion. The default timeout is 1 second. + +See: https://github.com/raspberrypi/linux/issues/260 + +i2c-bcm2708/BCM270X_DT: Add support for I2C2 + +The third I2C bus (I2C2) is normally reserved for HDMI use. Careless +use of this bus can break an attached display - use with caution. + +It is recommended to disable accesses by VideoCore by setting +hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt. + +The interface is disabled by default - enable using the +i2c2_iknowwhatimdoing DT parameter. + +bcm2708-spi: Don't use static pin configuration with DT + +Also remove superfluous error checking - the SPI framework ensures the +validity of the chip_select value. --- arch/arm/mach-bcm2708/bcm2708.c | 51 ++++ arch/arm/mach-bcm2709/bcm2709.c | 51 ++++ drivers/i2c/busses/Kconfig | 21 +- drivers/i2c/busses/Makefile | 2 + - drivers/i2c/busses/i2c-bcm2708.c | 522 +++++++++++++++++++++++++++++++++++++++ - 5 files changed, 646 insertions(+), 1 deletion(-) + drivers/i2c/busses/i2c-bcm2708.c | 524 +++++++++++++++++++++++++++++++++++++++ + drivers/spi/spi-bcm2708.c | 11 +- + 6 files changed, 650 insertions(+), 10 deletions(-) create mode 100644 drivers/i2c/busses/i2c-bcm2708.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 31ad9da..26be516 100644 +index 3e5181f..7dc0cc7 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -83,6 +83,7 @@ static unsigned uart_clock = UART0_CLOCK; +@@ -84,6 +84,7 @@ static unsigned uart_clock = UART0_CLOCK; static unsigned disk_led_gpio = 16; static unsigned disk_led_active_low = 1; static unsigned reboot_part = 0; @@ -104245,7 +108138,7 @@ index 31ad9da..26be516 100644 static unsigned use_dt = 0; -@@ -550,6 +551,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { +@@ -539,6 +540,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { }; #endif @@ -104291,7 +108184,7 @@ index 31ad9da..26be516 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -702,6 +742,15 @@ void __init bcm2708_init(void) +@@ -696,6 +736,15 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2708_spi_device); @@ -104307,14 +108200,14 @@ index 31ad9da..26be516 100644 bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -893,3 +942,5 @@ module_param(uart_clock, uint, 0644); +@@ -878,3 +927,5 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); +module_param(vc_i2c_override, bool, 0644); +MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 6874633..50843df 100644 +index bb86982..7d70eeb 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -85,6 +85,7 @@ static unsigned uart_clock = UART0_CLOCK; @@ -104325,7 +108218,7 @@ index 6874633..50843df 100644 static unsigned use_dt = 0; -@@ -570,6 +571,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { +@@ -555,6 +556,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { }; #endif @@ -104371,7 +108264,7 @@ index 6874633..50843df 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -722,6 +762,15 @@ void __init bcm2709_init(void) +@@ -713,6 +753,15 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2708_spi_device); @@ -104387,14 +108280,14 @@ index 6874633..50843df 100644 bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -1061,3 +1110,5 @@ module_param(uart_clock, uint, 0644); +@@ -1052,3 +1101,5 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); +module_param(vc_i2c_override, bool, 0644); +MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 2255af2..5b0c772 100644 +index 08b8617..eb5f729 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" @@ -104433,7 +108326,7 @@ index 2255af2..5b0c772 100644 If you say yes to this option, support will be included for the BCM2835 I2C controller. diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index cdf941d..e0176d7 100644 +index 6df3b30..a58f550 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -2,6 +2,8 @@ @@ -104447,10 +108340,10 @@ index cdf941d..e0176d7 100644 diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c new file mode 100644 -index 0000000..8773203 +index 0000000..8b8762d --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,522 @@ +@@ -0,0 +1,524 @@ +/* + * Driver for Broadcom BCM2708 BSC Controllers + * @@ -104520,10 +108413,9 @@ index 0000000..8773203 +#define BSC_S_DONE 0x00000002 +#define BSC_S_TA 0x00000001 + -+#define I2C_TIMEOUT_MS 150 -+#define I2C_WAIT_LOOP_COUNT 40 ++#define I2C_WAIT_LOOP_COUNT 200 + -+#define DRV_NAME "bcm2708_i2c" ++#define DRV_NAME "bcm2708_i2c" + +static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); @@ -104758,7 +108650,7 @@ index 0000000..8773203 + goto error_timeout; + } + -+ ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); ++ ret = wait_for_completion_timeout(&bi->done, adap->timeout); + if (ret == 0) { + dev_err(&adap->dev, "transfer timed out\n"); + goto error_timeout; @@ -104860,8 +108752,11 @@ index 0000000..8773203 + case 1: + adap->class = I2C_CLASS_DDC; + break; ++ case 2: ++ adap->class = I2C_CLASS_DDC; ++ break; + default: -+ dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); ++ dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n"); + err = -ENXIO; + goto out_free_bi; + } @@ -104973,11 +108868,443 @@ index 0000000..8773203 +MODULE_AUTHOR("Chris Boot "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c +index 5c0214e..781c747 100644 +--- a/drivers/spi/spi-bcm2708.c ++++ b/drivers/spi/spi-bcm2708.c +@@ -386,14 +386,6 @@ static int bcm2708_spi_setup(struct spi_device *spi) + if (bs->stopping) + return -ESHUTDOWN; + +- if (!(spi->mode & SPI_NO_CS) && +- (spi->chip_select > spi->master->num_chipselect)) { +- dev_dbg(&spi->dev, +- "setup: invalid chipselect %u (%u defined)\n", +- spi->chip_select, spi->master->num_chipselect); +- return -EINVAL; +- } +- + state = spi->controller_state; + if (!state) { + state = kzalloc(sizeof(*state), GFP_KERNEL); +@@ -496,7 +488,8 @@ static int bcm2708_spi_probe(struct platform_device *pdev) + return PTR_ERR(clk); + } + +- bcm2708_init_pinmode(); ++ if (!pdev->dev.of_node) ++ bcm2708_init_pinmode(); + + master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + if (!master) { -From fb0599a8dc95e605fe75e510c39a99e77fe627f8 Mon Sep 17 00:00:00 2001 +From 1a6f52fa2ef4d7bc5a05f152162f42888b469252 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:27:06 +0200 +Subject: [PATCH 035/113] char: broadcom: Add vcio module +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add module for accessing the mailbox property channel through +/dev/vcio. Was previously in bcm2708-vcio. + +Signed-off-by: Noralf Trønnes +--- + drivers/char/broadcom/Kconfig | 6 ++ + drivers/char/broadcom/Makefile | 1 + + drivers/char/broadcom/vcio.c | 175 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 182 insertions(+) + create mode 100644 drivers/char/broadcom/vcio.c + +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index 2292ed2..5489f19 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -22,6 +22,12 @@ config BCM2708_VCMEM + help + Helper for videocore memory access and total size allocation. + ++config BCM_VCIO ++ tristate "Mailbox userspace access" ++ depends on BCM2835_MBOX ++ help ++ Gives access to the mailbox property channel from userspace. ++ + endif + + config BCM_VC_SM +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index 667d33e..14775c9 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -1,5 +1,6 @@ + obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ + obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o ++obj-$(CONFIG_BCM_VCIO) += vcio.o + obj-$(CONFIG_BCM_VC_SM) += vc_sm/ + + obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o +diff --git a/drivers/char/broadcom/vcio.c b/drivers/char/broadcom/vcio.c +new file mode 100644 +index 0000000..c19bc20 +--- /dev/null ++++ b/drivers/char/broadcom/vcio.c +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2015 Noralf Trønnes ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MBOX_CHAN_PROPERTY 8 ++ ++#define VCIO_IOC_MAGIC 100 ++#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) ++ ++static struct { ++ dev_t devt; ++ struct cdev cdev; ++ struct class *class; ++ struct rpi_firmware *fw; ++} vcio; ++ ++static int vcio_user_property_list(void *user) ++{ ++ u32 *buf, size; ++ int ret; ++ ++ /* The first 32-bit is the size of the buffer */ ++ if (copy_from_user(&size, user, sizeof(size))) ++ return -EFAULT; ++ ++ buf = kmalloc(size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ if (copy_from_user(buf, user, size)) { ++ kfree(buf); ++ return -EFAULT; ++ } ++ ++ /* Strip off protocol encapsulation */ ++ ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); ++ if (ret) { ++ kfree(buf); ++ return ret; ++ } ++ ++ buf[1] = RPI_FIRMWARE_STATUS_SUCCESS; ++ if (copy_to_user(user, buf, size)) ++ ret = -EFAULT; ++ ++ kfree(buf); ++ ++ return ret; ++} ++ ++static int vcio_device_open(struct inode *inode, struct file *file) ++{ ++ try_module_get(THIS_MODULE); ++ ++ return 0; ++} ++ ++static int vcio_device_release(struct inode *inode, struct file *file) ++{ ++ module_put(THIS_MODULE); ++ ++ return 0; ++} ++ ++static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, ++ unsigned long ioctl_param) ++{ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY: ++ return vcio_user_property_list((void *)ioctl_param); ++ default: ++ pr_err("unknown ioctl: %d\n", ioctl_num); ++ return -EINVAL; ++ } ++} ++ ++const struct file_operations vcio_fops = { ++ .unlocked_ioctl = vcio_device_ioctl, ++ .open = vcio_device_open, ++ .release = vcio_device_release, ++}; ++ ++static int __init vcio_init(void) ++{ ++ struct device_node *np; ++ static struct device *dev; ++ int ret; ++ ++ np = of_find_compatible_node(NULL, NULL, ++ "raspberrypi,bcm2835-firmware"); ++/* Uncomment this when we only boot with Device Tree ++ if (!of_device_is_available(np)) ++ return -ENODEV; ++*/ ++ vcio.fw = rpi_firmware_get(np); ++ if (!vcio.fw) ++ return -ENODEV; ++ ++ ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); ++ if (ret) { ++ pr_err("failed to allocate device number\n"); ++ return ret; ++ } ++ ++ cdev_init(&vcio.cdev, &vcio_fops); ++ vcio.cdev.owner = THIS_MODULE; ++ ret = cdev_add(&vcio.cdev, vcio.devt, 1); ++ if (ret) { ++ pr_err("failed to register device\n"); ++ goto err_unregister_chardev; ++ } ++ ++ /* ++ * Create sysfs entries ++ * 'bcm2708_vcio' is used for backwards compatibility so we don't break ++ * userspace. Raspian has a udev rule that changes the permissions. ++ */ ++ vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); ++ if (IS_ERR(vcio.class)) { ++ ret = PTR_ERR(vcio.class); ++ pr_err("failed to create class\n"); ++ goto err_cdev_del; ++ } ++ ++ dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); ++ if (IS_ERR(dev)) { ++ ret = PTR_ERR(dev); ++ pr_err("failed to create device\n"); ++ goto err_class_destroy; ++ } ++ ++ return 0; ++ ++err_class_destroy: ++ class_destroy(vcio.class); ++err_cdev_del: ++ cdev_del(&vcio.cdev); ++err_unregister_chardev: ++ unregister_chrdev_region(vcio.devt, 1); ++ ++ return ret; ++} ++module_init(vcio_init); ++ ++static void __exit vcio_exit(void) ++{ ++ device_destroy(vcio.class, vcio.devt); ++ class_destroy(vcio.class); ++ cdev_del(&vcio.cdev); ++ unregister_chrdev_region(vcio.devt, 1); ++} ++module_exit(vcio_exit); ++ ++MODULE_AUTHOR("Gray Girling"); ++MODULE_AUTHOR("Noralf Trønnes"); ++MODULE_DESCRIPTION("Mailbox userspace access"); ++MODULE_LICENSE("GPL"); + +From be94a3df5455d2d2848547fef93ca5912669977c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:21:20 +0200 +Subject: [PATCH 036/113] firmware: bcm2835: Add missing property tags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index 9d9efb7..d3933af 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -60,6 +60,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, + RPI_FIRMWARE_GET_TURBO = 0x00030009, + RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, ++ RPI_FIRMWARE_GET_STC = 0x0003000b, + RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, + RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, + RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, +@@ -69,10 +70,12 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, + RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, + RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, ++ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, + RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, + RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, + RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, + RPI_FIRMWARE_SET_TURBO = 0x00038009, ++ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, +@@ -86,6 +89,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, + RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, + RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, + RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, +@@ -95,6 +99,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, + RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, + RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, +@@ -103,6 +108,9 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, ++ ++ RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, + + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, + +From 67c97253ca03276086cebf0c93fe6c24544087e6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:25:01 +0200 +Subject: [PATCH 037/113] firmware: bcm2835: Support ARCH_BCM270x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Support booting without Device Tree. +Turn on USB power. +Load driver early because of lacking support for deferred probing +in many drivers. + +Signed-off-by: Noralf Trønnes +--- + drivers/firmware/raspberrypi.c | 41 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 39 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c +index dd506cd3..b980d53 100644 +--- a/drivers/firmware/raspberrypi.c ++++ b/drivers/firmware/raspberrypi.c +@@ -28,6 +28,8 @@ struct rpi_firmware { + u32 enabled; + }; + ++static struct platform_device *g_pdev; ++ + static DEFINE_MUTEX(transaction_lock); + + static void response_callback(struct mbox_client *cl, void *msg) +@@ -183,6 +185,25 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) + } + } + ++static int raspberrypi_firmware_set_power(struct rpi_firmware *fw, ++ u32 domain, bool on) ++{ ++ struct { ++ u32 domain; ++ u32 on; ++ } packet; ++ int ret; ++ ++ packet.domain = domain; ++ packet.on = on; ++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POWER_STATE, ++ &packet, sizeof(packet)); ++ if (!ret && packet.on != on) ++ ret = -EINVAL; ++ ++ return ret; ++} ++ + static int rpi_firmware_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -207,9 +228,13 @@ static int rpi_firmware_probe(struct platform_device *pdev) + init_completion(&fw->c); + + platform_set_drvdata(pdev, fw); ++ g_pdev = pdev; + + rpi_firmware_print_firmware_revision(fw); + ++ if (raspberrypi_firmware_set_power(fw, 3, true)) ++ dev_err(dev, "failed to turn on USB power\n"); ++ + return 0; + } + +@@ -218,6 +243,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) + struct rpi_firmware *fw = platform_get_drvdata(pdev); + + mbox_free_channel(fw->chan); ++ g_pdev = NULL; + + return 0; + } +@@ -230,7 +256,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) + */ + struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) + { +- struct platform_device *pdev = of_find_device_by_node(firmware_node); ++ struct platform_device *pdev = g_pdev; + + if (!pdev) + return NULL; +@@ -253,7 +279,18 @@ static struct platform_driver rpi_firmware_driver = { + .probe = rpi_firmware_probe, + .remove = rpi_firmware_remove, + }; +-module_platform_driver(rpi_firmware_driver); ++ ++static int __init rpi_firmware_init(void) ++{ ++ return platform_driver_register(&rpi_firmware_driver); ++} ++subsys_initcall(rpi_firmware_init); ++ ++static void __init rpi_firmware_exit(void) ++{ ++ platform_driver_unregister(&rpi_firmware_driver); ++} ++module_exit(rpi_firmware_exit); + + MODULE_AUTHOR("Eric Anholt "); + MODULE_DESCRIPTION("Raspberry Pi firmware driver"); + +From 431856b45e7ed8fd40676902e48fe82569a89206 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 021/204] bcm2835: add v4l2 camera device +Subject: [PATCH 038/113] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -105215,16 +109542,46 @@ VIDIOC_TRY_FMT and VIDIOC_S_FMT tests were faling due to reporting V4L2_COLORSPACE_JPEG when the colour format wasn't V4L2_PIX_FMT_JPEG. Now reports V4L2_COLORSPACE_SMPTE170M for YUV formats. + +bcm2835 camera planar/packed stride length + +Added a field to the mmal_fmt struct used to compute the bytes per line +when using a particular format. This results in the correct stride being +calculated even when the format is planar. + +Signed-off-by: Garrett Wilson + +bcm2835: camera: check for scene not being found + +static analysis by cppcheck detected some potential NULL pointer +dereference issues: + +[drivers/media/platform/bcm2835/controls.c:854]: (error) Possible null + pointer dereference: scene + (and lines 858, 859 too) + +it is possible that scene is not found because of an invalue ctrl->val +and is therefore NULL and hence causing a null pointer dereference. + +Signed-off-by: Colin Ian King + +bcm2835: memcpy port data to m rather than rmsg + +static analysis by cppcheck detected a memcpy to rmsg which is +not actually initialized at that point. The memcpy should be copying +to variable m instead. + +Signed-off-by: Colin Ian King --- Documentation/video4linux/bcm2835-v4l2.txt | 60 + drivers/media/platform/Kconfig | 2 + drivers/media/platform/Makefile | 2 + drivers/media/platform/bcm2835/Kconfig | 25 + drivers/media/platform/bcm2835/Makefile | 5 + - drivers/media/platform/bcm2835/bcm2835-camera.c | 1828 +++++++++++++++++++++ + drivers/media/platform/bcm2835/bcm2835-camera.c | 1842 +++++++++++++++++++++ drivers/media/platform/bcm2835/bcm2835-camera.h | 126 ++ - drivers/media/platform/bcm2835/controls.c | 1322 +++++++++++++++ - drivers/media/platform/bcm2835/mmal-common.h | 52 + + drivers/media/platform/bcm2835/controls.c | 1324 +++++++++++++++ + drivers/media/platform/bcm2835/mmal-common.h | 53 + drivers/media/platform/bcm2835/mmal-encodings.h | 127 ++ drivers/media/platform/bcm2835/mmal-msg-common.h | 50 + drivers/media/platform/bcm2835/mmal-msg-format.h | 81 + @@ -105233,7 +109590,7 @@ Now reports V4L2_COLORSPACE_SMPTE170M for YUV formats. drivers/media/platform/bcm2835/mmal-parameters.h | 656 ++++++++ drivers/media/platform/bcm2835/mmal-vchiq.c | 1916 ++++++++++++++++++++++ drivers/media/platform/bcm2835/mmal-vchiq.h | 178 ++ - 17 files changed, 6941 insertions(+) + 17 files changed, 6958 insertions(+) create mode 100644 Documentation/video4linux/bcm2835-v4l2.txt create mode 100644 drivers/media/platform/bcm2835/Kconfig create mode 100644 drivers/media/platform/bcm2835/Makefile @@ -105317,7 +109674,7 @@ index 0000000..c585a8f + +$ v4l2-ctl --list-formats diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index 421f531..34ad311 100644 +index dc75694..2370af5 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -11,6 +11,8 @@ menuconfig V4L_PLATFORM_DRIVERS @@ -105330,7 +109687,7 @@ index 421f531..34ad311 100644 config VIDEO_VIA_CAMERA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index 8f85561..7b15c24 100644 +index efa0295..8c0b3b5 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,6 +2,8 @@ @@ -105386,10 +109743,10 @@ index 0000000..f17c79c +ccflags-$(CONFIG_VIDEO_BCM2835) += -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel -D__VCCOREVER__=0x04000000 diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c new file mode 100644 -index 0000000..eb4d831 +index 0000000..04a1711 --- /dev/null +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -0,0 +1,1828 @@ +@@ -0,0 +1,1842 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -105480,12 +109837,13 @@ index 0000000..eb4d831 +/* video formats */ +static struct mmal_fmt formats[] = { + { -+ .name = "4:2:0, packed YUV", ++ .name = "4:2:0, planar, YUV", + .fourcc = V4L2_PIX_FMT_YUV420, + .flags = 0, + .mmal = MMAL_ENCODING_I420, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { + .name = "4:2:2, packed, YUYV", @@ -105494,6 +109852,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_YUYV, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { + .name = "RGB24 (LE)", @@ -105502,6 +109861,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_BGR24, + .depth = 24, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 3, + }, + { + .name = "JPEG", @@ -105510,6 +109870,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_JPEG, + .depth = 8, + .mmal_component = MMAL_COMPONENT_IMAGE_ENCODE, ++ .ybbp = 0, + }, + { + .name = "H264", @@ -105518,6 +109879,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_H264, + .depth = 8, + .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, ++ .ybbp = 0, + }, + { + .name = "MJPEG", @@ -105526,6 +109888,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_MJPEG, + .depth = 8, + .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, ++ .ybbp = 0, + }, + { + .name = "4:2:2, packed, YVYU", @@ -105534,6 +109897,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_YVYU, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { + .name = "4:2:2, packed, VYUY", @@ -105542,6 +109906,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_VYUY, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { + .name = "4:2:2, packed, UYVY", @@ -105550,14 +109915,16 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_UYVY, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { -+ .name = "4:2:0, packed, NV12", ++ .name = "4:2:0, planar, NV12", + .fourcc = V4L2_PIX_FMT_NV12, + .flags = 0, + .mmal = MMAL_ENCODING_NV12, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { + .name = "RGB24 (BE)", @@ -105566,22 +109933,25 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_RGB24, + .depth = 24, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 3, + }, + { -+ .name = "4:2:0, packed YVU", ++ .name = "4:2:0, planar, YVU", + .fourcc = V4L2_PIX_FMT_YVU420, + .flags = 0, + .mmal = MMAL_ENCODING_YV12, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { -+ .name = "4:2:0, packed, NV21", ++ .name = "4:2:0, planar, NV21", + .fourcc = V4L2_PIX_FMT_NV21, + .flags = 0, + .mmal = MMAL_ENCODING_NV21, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { + .name = "RGB32 (BE)", @@ -105590,6 +109960,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_BGRA, + .depth = 32, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 4, + }, +}; + @@ -106163,7 +110534,7 @@ index 0000000..eb4d831 + a->fmt.width = preview_port->es.video.width; + a->fmt.height = preview_port->es.video.height; + a->fmt.pixelformat = V4L2_PIX_FMT_YUV420; -+ a->fmt.bytesperline = (preview_port->es.video.width * 3)>>1; ++ a->fmt.bytesperline = preview_port->es.video.width; + a->fmt.sizeimage = (preview_port->es.video.width * + preview_port->es.video.height * 3)>>1; + a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -106286,7 +110657,7 @@ index 0000000..eb4d831 + + v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1, + &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0); -+ f->fmt.pix.bytesperline = (f->fmt.pix.width * mfmt->depth)>>3; ++ f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; + + /* Image buffer has to be padded to allow for alignment, even though + * we then remove that padding before delivering the buffer. @@ -107352,10 +111723,10 @@ index 0000000..7fe9f65 +} diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c new file mode 100644 -index 0000000..3017b94 +index 0000000..f9f903f --- /dev/null +++ b/drivers/media/platform/bcm2835/controls.c -@@ -0,0 +1,1322 @@ +@@ -0,0 +1,1324 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -108203,6 +112574,8 @@ index 0000000..3017b94 + break; + } + } ++ if (!scene) ++ return -EINVAL; + if (i >= ARRAY_SIZE(scene_configs)) + return -EINVAL; + @@ -108680,10 +113053,10 @@ index 0000000..3017b94 +} diff --git a/drivers/media/platform/bcm2835/mmal-common.h b/drivers/media/platform/bcm2835/mmal-common.h new file mode 100644 -index 0000000..35698c8 +index 0000000..15788a1 --- /dev/null +++ b/drivers/media/platform/bcm2835/mmal-common.h -@@ -0,0 +1,52 @@ +@@ -0,0 +1,53 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -108716,6 +113089,7 @@ index 0000000..35698c8 + u32 mmal; + int depth; + u32 mmal_component; /* MMAL component index to be used to encode */ ++ u32 ybbp; /* depth of first Y plane for planar formats */ +}; + +/* buffer for one video frame */ @@ -110199,7 +114573,7 @@ index 0000000..aa0fd18 +}; diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c new file mode 100644 -index 0000000..76f249e +index 0000000..7813225 --- /dev/null +++ b/drivers/media/platform/bcm2835/mmal-vchiq.c @@ -0,0 +1,1916 @@ @@ -111056,7 +115430,7 @@ index 0000000..76f249e + sizeof(union mmal_es_specific_format)); + + m.u.port_info_set.format.extradata_size = port->format.extradata_size; -+ memcpy(rmsg->u.port_info_set.extradata, port->format.extradata, ++ memcpy(&m.u.port_info_set.extradata, port->format.extradata, + port->format.extradata_size); + + ret = send_synchronous_mmal_msg(instance, &m, @@ -112304,5226 +116678,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 55141e6e23fd7c2f2b98d6f472dd4e1f11fcdb50 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 23 Jan 2015 14:48:55 +0000 -Subject: [PATCH 022/204] scripts/dtc: Update to upstream version with overlay - patches - ---- - scripts/dtc/checks.c | 151 ++- - scripts/dtc/data.c | 12 +- - scripts/dtc/dtc-lexer.l | 70 +- - scripts/dtc/dtc-lexer.lex.c_shipped | 540 +++++----- - scripts/dtc/dtc-parser.tab.c_shipped | 1783 ++++++++++++++++------------------ - scripts/dtc/dtc-parser.tab.h_shipped | 116 ++- - scripts/dtc/dtc-parser.y | 158 +-- - scripts/dtc/dtc.c | 23 +- - scripts/dtc/dtc.h | 56 +- - scripts/dtc/flattree.c | 145 ++- - scripts/dtc/fstree.c | 16 +- - scripts/dtc/livetree.c | 4 +- - scripts/dtc/srcpos.c | 49 +- - scripts/dtc/srcpos.h | 15 +- - scripts/dtc/treesource.c | 14 +- - scripts/dtc/util.c | 18 +- - scripts/dtc/util.h | 4 +- - scripts/dtc/version_gen.h | 2 +- - 18 files changed, 1697 insertions(+), 1479 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index ee96a25..27f45f1 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -53,7 +53,7 @@ struct check { - void *data; - bool warn, error; - enum checkstatus status; -- int inprogress; -+ bool inprogress; - int num_prereqs; - struct check **prereq; - }; -@@ -113,6 +113,7 @@ static inline void check_msg(struct check *c, const char *fmt, ...) - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } -+ va_end(ap); - } - - #define FAIL(c, ...) \ -@@ -141,9 +142,9 @@ static void check_nodes_props(struct check *c, struct node *dt, struct node *nod - check_nodes_props(c, dt, child); - } - --static int run_check(struct check *c, struct node *dt) -+static bool run_check(struct check *c, struct node *dt) - { -- int error = 0; -+ bool error = false; - int i; - - assert(!c->inprogress); -@@ -151,11 +152,11 @@ static int run_check(struct check *c, struct node *dt) - if (c->status != UNCHECKED) - goto out; - -- c->inprogress = 1; -+ c->inprogress = true; - - for (i = 0; i < c->num_prereqs; i++) { - struct check *prq = c->prereq[i]; -- error |= run_check(prq, dt); -+ error = error || run_check(prq, dt); - if (prq->status != PASSED) { - c->status = PREREQ; - check_msg(c, "Failed prerequisite '%s'", -@@ -177,9 +178,9 @@ static int run_check(struct check *c, struct node *dt) - TRACE(c, "\tCompleted, status %d", c->status); - - out: -- c->inprogress = 0; -+ c->inprogress = false; - if ((c->status != PASSED) && (c->error)) -- error = 1; -+ error = true; - return error; - } - -@@ -457,22 +458,93 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -+ struct fixup *f, **fp; -+ struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; -+ int has_phandle_refs; -+ -+ has_phandle_refs = 0; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ has_phandle_refs = 1; -+ break; -+ } -+ -+ if (!has_phandle_refs) -+ return; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); -- if (! refnode) { -+ if (!refnode && !symbol_fixup_support) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ m->ref); - continue; - } - -- phandle = get_node_phandle(dt, refnode); -- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); -+ if (!refnode) { -+ /* allocate fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* search for an already existing fixup */ -+ for_each_fixup(dt, f) -+ if (strcmp(f->ref, m->ref) == 0) -+ break; -+ -+ /* no fixup found, add new */ -+ if (f == NULL) { -+ f = xmalloc(sizeof(*f)); -+ f->ref = m->ref; -+ f->entries = NULL; -+ f->next = NULL; -+ -+ /* add it to the tree */ -+ fp = &dt->fixups; -+ while (*fp) -+ fp = &(*fp)->next; -+ *fp = f; -+ } -+ -+ /* and now append fixup entry */ -+ fep = &f->entries; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ -+ /* mark the entry as unresolved */ -+ phandle = 0xdeadbeef; -+ } else { -+ phandle = get_node_phandle(dt, refnode); -+ -+ /* if it's a plugin, we need to record it */ -+ if (symbol_fixup_support && dt->is_plugin) { -+ -+ /* allocate a new local fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* append it to the local fixups */ -+ fep = &dt->local_fixups; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ } -+ } -+ -+ *((cell_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(phandle); - } -+ - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, - &duplicate_node_names, &explicit_phandles); -@@ -624,11 +696,11 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt, - if (!reg && !ranges) - return; - -- if ((node->parent->addr_cells == -1)) -+ if (node->parent->addr_cells == -1) - FAIL(c, "Relying on default #address-cells value for %s", - node->fullpath); - -- if ((node->parent->size_cells == -1)) -+ if (node->parent->size_cells == -1) - FAIL(c, "Relying on default #size-cells value for %s", - node->fullpath); - } -@@ -651,6 +723,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - -+static void check_auto_label_phandles(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct label *l; -+ struct symbol *s, **sp; -+ int has_label; -+ -+ if (!symbol_fixup_support) -+ return; -+ -+ has_label = 0; -+ for_each_label(node->labels, l) { -+ has_label = 1; -+ break; -+ } -+ -+ if (!has_label) -+ return; -+ -+ /* force allocation of a phandle for this node */ -+ (void)get_node_phandle(dt, node); -+ -+ /* add the symbol */ -+ for_each_label(node->labels, l) { -+ -+ s = xmalloc(sizeof(*s)); -+ s->label = l; -+ s->node = node; -+ s->next = NULL; -+ -+ /* add it to the symbols list */ -+ sp = &dt->symbols; -+ while (*sp) -+ sp = &((*sp)->next); -+ *sp = s; -+ } -+} -+NODE_WARNING(auto_label_phandles, NULL); -+ - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -669,6 +780,8 @@ static struct check *check_table[] = { - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -+ &auto_label_phandles, -+ - &always_fail, - }; - -@@ -706,15 +819,15 @@ static void disable_warning_error(struct check *c, bool warn, bool error) - c->error = c->error && !error; - } - --void parse_checks_option(bool warn, bool error, const char *optarg) -+void parse_checks_option(bool warn, bool error, const char *arg) - { - int i; -- const char *name = optarg; -+ const char *name = arg; - bool enable = true; - -- if ((strncmp(optarg, "no-", 3) == 0) -- || (strncmp(optarg, "no_", 3) == 0)) { -- name = optarg + 3; -+ if ((strncmp(arg, "no-", 3) == 0) -+ || (strncmp(arg, "no_", 3) == 0)) { -+ name = arg + 3; - enable = false; - } - -@@ -733,7 +846,7 @@ void parse_checks_option(bool warn, bool error, const char *optarg) - die("Unrecognized check name \"%s\"\n", name); - } - --void process_checks(int force, struct boot_info *bi) -+void process_checks(bool force, struct boot_info *bi) - { - struct node *dt = bi->dt; - int i; -diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c -index 4a40c5b..8cae237 100644 ---- a/scripts/dtc/data.c -+++ b/scripts/dtc/data.c -@@ -74,7 +74,7 @@ struct data data_copy_escape_string(const char *s, int len) - struct data d; - char *q; - -- d = data_grow_for(empty_data, strlen(s)+1); -+ d = data_grow_for(empty_data, len + 1); - - q = d.val; - while (i < len) { -@@ -250,20 +250,20 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref) - return data_append_markers(d, m); - } - --int data_is_one_string(struct data d) -+bool data_is_one_string(struct data d) - { - int i; - int len = d.len; - - if (len == 0) -- return 0; -+ return false; - - for (i = 0; i < len-1; i++) - if (d.val[i] == '\0') -- return 0; -+ return false; - - if (d.val[len-1] != '\0') -- return 0; -+ return false; - -- return 1; -+ return true; - } -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 3b41bfc..dd44ba2 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -20,7 +20,6 @@ - - %option noyywrap nounput noinput never-interactive - --%x INCLUDE - %x BYTESTRING - %x PROPNODENAME - %s V1 -@@ -40,6 +39,7 @@ LINECOMMENT "//".*\n - #include "dtc-parser.tab.h" - - YYLTYPE yylloc; -+extern bool treesource_error; - - /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ - #define YY_USER_ACTION \ -@@ -61,7 +61,8 @@ static int dts_version = 1; - BEGIN(V1); \ - - static void push_input_file(const char *filename); --static int pop_input_file(void); -+static bool pop_input_file(void); -+static void lexical_error(const char *fmt, ...); - %} - - %% -@@ -75,11 +76,11 @@ static int pop_input_file(void); - char *line, *tmp, *fn; - /* skip text before line # */ - line = yytext; -- while (!isdigit(*line)) -+ while (!isdigit((unsigned char)*line)) - line++; - /* skip digits in line # */ - tmp = line; -- while (!isspace(*tmp)) -+ while (!isspace((unsigned char)*tmp)) - tmp++; - /* "NULL"-terminate line # */ - *tmp = '\0'; -@@ -112,6 +113,11 @@ static int pop_input_file(void); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -@@ -146,15 +152,42 @@ static int pop_input_file(void); - } - - ([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { -- yylval.literal = xstrdup(yytext); -- DPRINT("Literal: '%s'\n", yylval.literal); -+ char *e; -+ DPRINT("Integer Literal: '%s'\n", yytext); -+ -+ errno = 0; -+ yylval.integer = strtoull(yytext, &e, 0); -+ -+ assert(!(*e) || !e[strspn(e, "UL")]); -+ -+ if (errno == ERANGE) -+ lexical_error("Integer literal '%s' out of range", -+ yytext); -+ else -+ /* ERANGE is the only strtoull error triggerable -+ * by strings matching the pattern */ -+ assert(errno == 0); - return DT_LITERAL; - } - - <*>{CHAR_LITERAL} { -- yytext[yyleng-1] = '\0'; -- yylval.literal = xstrdup(yytext+1); -- DPRINT("Character literal: %s\n", yylval.literal); -+ struct data d; -+ DPRINT("Character literal: %s\n", yytext); -+ -+ d = data_copy_escape_string(yytext+1, yyleng-2); -+ if (d.len == 1) { -+ lexical_error("Empty character literal"); -+ yylval.integer = 0; -+ return DT_CHAR_LITERAL; -+ } -+ -+ yylval.integer = (unsigned char)d.val[0]; -+ -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ - return DT_CHAR_LITERAL; - } - -@@ -164,7 +197,7 @@ static int pop_input_file(void); - return DT_REF; - } - --<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ -+<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); -@@ -238,13 +271,24 @@ static void push_input_file(const char *filename) - } - - --static int pop_input_file(void) -+static bool pop_input_file(void) - { - if (srcfile_pop() == 0) -- return 0; -+ return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - -- return 1; -+ return true; -+} -+ -+static void lexical_error(const char *fmt, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, fmt); -+ srcpos_verror(&yylloc, "Lexical error", fmt, ap); -+ va_end(ap); -+ -+ treesource_error = true; - } -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 2d30f41..1518525 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -372,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -381,25 +381,26 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[161] = -+static yyconst flex_int16_t yy_accept[166] = - { 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 31, 29, 18, 18, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 29, 29, 15, 16, -- 16, 29, 16, 10, 10, 18, 26, 0, 3, 0, -- 27, 12, 0, 0, 11, 0, 0, 0, 0, 0, -- 0, 0, 21, 23, 25, 24, 22, 0, 9, 28, -- 0, 0, 0, 14, 14, 16, 16, 16, 10, 10, -- 10, 0, 12, 0, 11, 0, 0, 0, 20, 0, -- 0, 0, 0, 0, 0, 0, 0, 16, 10, 10, -- 10, 0, 19, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 16, 13, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 16, 6, 0, 0, 0, 0, 0, -- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, -- 4, 17, 0, 0, 2, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -- 0, 0, 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - - static yyconst flex_int32_t yy_ec[256] = -@@ -415,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -434,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static yyconst flex_int32_t yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 1 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[175] = -+static yyconst flex_int16_t yy_base[180] = - { 0, -- 0, 385, 378, 40, 41, 383, 72, 382, 34, 44, -- 388, 393, 61, 117, 368, 116, 115, 115, 115, 48, -- 367, 107, 368, 339, 127, 120, 0, 147, 393, 0, -- 127, 0, 133, 156, 168, 153, 393, 125, 393, 380, -- 393, 0, 369, 127, 393, 160, 371, 377, 347, 21, -- 343, 346, 393, 393, 393, 393, 393, 359, 393, 393, -- 183, 343, 339, 393, 356, 0, 183, 340, 187, 348, -- 347, 0, 0, 0, 178, 359, 195, 365, 354, 326, -- 332, 325, 334, 328, 204, 326, 331, 324, 393, 335, -- 150, 311, 343, 342, 315, 322, 340, 179, 313, 207, -- -- 319, 316, 317, 393, 337, 333, 305, 302, 311, 301, -- 310, 190, 338, 337, 393, 307, 322, 301, 305, 277, -- 208, 311, 307, 278, 271, 270, 248, 246, 213, 130, -- 393, 393, 263, 235, 207, 221, 218, 229, 213, 213, -- 206, 234, 218, 210, 208, 193, 219, 393, 223, 204, -- 176, 157, 393, 393, 120, 106, 97, 119, 393, 393, -- 245, 251, 259, 263, 267, 273, 280, 284, 292, 300, -- 304, 310, 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[175] = -+static yyconst flex_int16_t yy_def[180] = - { 0, -- 160, 1, 1, 1, 1, 5, 160, 7, 1, 1, -- 160, 160, 160, 160, 160, 161, 162, 163, 160, 160, -- 160, 160, 164, 160, 160, 160, 165, 164, 160, 166, -- 167, 166, 166, 160, 160, 160, 160, 161, 160, 161, -- 160, 168, 160, 163, 160, 163, 169, 170, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 164, 160, 160, -- 160, 160, 160, 160, 164, 166, 167, 166, 160, 160, -- 160, 171, 168, 172, 163, 169, 169, 170, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 166, 160, 160, -- 171, 172, 160, 160, 160, 160, 160, 160, 160, 160, -- -- 160, 160, 166, 160, 160, 160, 160, 160, 160, 160, -- 160, 173, 160, 166, 160, 160, 160, 160, 160, 160, -- 173, 160, 173, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 174, 160, 160, 160, 174, 160, 174, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 0, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[440] = -+static yyconst flex_int16_t yy_nxt[449] = - { 0, -- 12, 13, 14, 13, 15, 16, 12, 17, 18, 12, -- 12, 12, 19, 12, 12, 12, 12, 20, 21, 22, -- 23, 23, 23, 23, 23, 12, 12, 23, 23, 23, -- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -- 23, 23, 23, 12, 24, 12, 25, 34, 35, 35, -- 25, 81, 26, 26, 27, 27, 27, 34, 35, 35, -- 82, 28, 36, 36, 36, 53, 54, 29, 28, 28, -- 28, 28, 12, 13, 14, 13, 15, 16, 30, 17, -- 18, 30, 30, 30, 26, 30, 30, 30, 12, 20, -- 21, 22, 31, 31, 31, 31, 31, 32, 12, 31, -- -- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -- 31, 31, 31, 31, 31, 12, 24, 12, 36, 36, -- 36, 39, 41, 45, 47, 56, 57, 48, 61, 47, -- 39, 159, 48, 66, 61, 45, 66, 66, 66, 158, -- 46, 40, 49, 59, 50, 157, 51, 49, 52, 50, -- 40, 63, 46, 52, 36, 36, 36, 156, 43, 62, -- 65, 65, 65, 59, 136, 68, 137, 65, 75, 69, -- 69, 69, 70, 71, 65, 65, 65, 65, 70, 71, -- 72, 69, 69, 69, 61, 46, 45, 155, 154, 66, -- 70, 71, 66, 66, 66, 122, 85, 85, 85, 59, -- -- 69, 69, 69, 46, 77, 100, 109, 93, 100, 70, -- 71, 110, 112, 122, 129, 123, 153, 85, 85, 85, -- 135, 135, 135, 148, 148, 160, 135, 135, 135, 152, -- 142, 142, 142, 123, 143, 142, 142, 142, 151, 143, -- 150, 146, 145, 149, 149, 38, 38, 38, 38, 38, -- 38, 38, 38, 42, 144, 141, 140, 42, 42, 44, -- 44, 44, 44, 44, 44, 44, 44, 58, 58, 58, -- 58, 64, 139, 64, 66, 138, 134, 66, 133, 66, -- 66, 67, 132, 131, 67, 67, 67, 67, 73, 130, -- 73, 73, 76, 76, 76, 76, 76, 76, 76, 76, -- -- 78, 78, 78, 78, 78, 78, 78, 78, 91, 160, -- 91, 92, 129, 92, 92, 128, 92, 92, 121, 121, -- 121, 121, 121, 121, 121, 121, 147, 147, 147, 147, -- 147, 147, 147, 147, 127, 126, 125, 124, 61, 61, -- 120, 119, 118, 117, 116, 115, 47, 114, 110, 113, -- 111, 108, 107, 106, 48, 105, 104, 89, 103, 102, -- 101, 99, 98, 97, 96, 95, 94, 79, 77, 90, -- 89, 88, 59, 87, 86, 59, 84, 83, 80, 79, -- 77, 74, 160, 60, 59, 55, 37, 160, 33, 25, -- 26, 25, 11, 160, 160, 160, 160, 160, 160, 160, -- -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160 -+ 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, -+ 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, -+ 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, -+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[440] = -+static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 4, 9, 9, 9, -- 10, 50, 4, 5, 5, 5, 5, 10, 10, 10, -- 50, 5, 13, 13, 13, 20, 20, 5, 5, 5, -- 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, -- 14, 16, 17, 18, 19, 22, 22, 19, 25, 26, -- 38, 158, 26, 31, 33, 44, 31, 31, 31, 157, -- 18, 16, 19, 31, 19, 156, 19, 26, 19, 26, -- 38, 26, 44, 26, 36, 36, 36, 155, 17, 25, -- 28, 28, 28, 28, 130, 33, 130, 28, 46, 34, -- 34, 34, 91, 91, 28, 28, 28, 28, 34, 34, -- 34, 35, 35, 35, 61, 46, 75, 152, 151, 67, -- 35, 35, 67, 67, 67, 112, 61, 61, 61, 67, -- -- 69, 69, 69, 75, 77, 85, 98, 77, 100, 69, -- 69, 98, 100, 121, 129, 112, 150, 85, 85, 85, -- 135, 135, 135, 143, 147, 149, 129, 129, 129, 146, -- 138, 138, 138, 121, 138, 142, 142, 142, 145, 142, -- 144, 141, 140, 143, 147, 161, 161, 161, 161, 161, -- 161, 161, 161, 162, 139, 137, 136, 162, 162, 163, -- 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, -- 164, 165, 134, 165, 166, 133, 128, 166, 127, 166, -- 166, 167, 126, 125, 167, 167, 167, 167, 168, 124, -- 168, 168, 169, 169, 169, 169, 169, 169, 169, 169, -- -- 170, 170, 170, 170, 170, 170, 170, 170, 171, 123, -- 171, 172, 122, 172, 172, 120, 172, 172, 173, 173, -- 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, -- 174, 174, 174, 174, 119, 118, 117, 116, 114, 113, -- 111, 110, 109, 108, 107, 106, 105, 103, 102, 101, -- 99, 97, 96, 95, 94, 93, 92, 90, 88, 87, -- 86, 84, 83, 82, 81, 80, 79, 78, 76, 71, -- 70, 68, 65, 63, 62, 58, 52, 51, 49, 48, -- 47, 43, 40, 24, 23, 21, 15, 11, 8, 6, -- 3, 2, 160, 160, 160, 160, 160, 160, 160, 160, -- -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160 -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, -+ 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -+ -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -631,13 +634,13 @@ char *yytext; - - - -- --#line 38 "dtc-lexer.l" -+#line 37 "dtc-lexer.l" - #include "dtc.h" - #include "srcpos.h" - #include "dtc-parser.tab.h" - - YYLTYPE yylloc; -+extern bool treesource_error; - - /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ - #define YY_USER_ACTION \ -@@ -659,14 +662,14 @@ static int dts_version = 1; - BEGIN(V1); \ - - static void push_input_file(const char *filename); --static int pop_input_file(void); --#line 664 "dtc-lexer.lex.c" -+static bool pop_input_file(void); -+static void lexical_error(const char *fmt, ...); -+#line 668 "dtc-lexer.lex.c" - - #define INITIAL 0 --#define INCLUDE 1 --#define BYTESTRING 2 --#define PROPNODENAME 3 --#define V1 4 -+#define BYTESTRING 1 -+#define PROPNODENAME 2 -+#define V1 3 - - #ifndef YY_NO_UNISTD_H - /* Special case for "unistd.h", since it is non-ANSI. We include it way -@@ -852,9 +855,9 @@ YY_DECL - register char *yy_cp, *yy_bp; - register int yy_act; - --#line 67 "dtc-lexer.l" -+#line 68 "dtc-lexer.l" - --#line 858 "dtc-lexer.lex.c" -+#line 861 "dtc-lexer.lex.c" - - if ( !(yy_init) ) - { -@@ -908,13 +911,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 161 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 160 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -937,7 +940,7 @@ do_action: /* This label is used only to access EOF actions. */ - case 1: - /* rule 1 can match eol */ - YY_RULE_SETUP --#line 68 "dtc-lexer.l" -+#line 69 "dtc-lexer.l" - { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; -@@ -947,16 +950,16 @@ YY_RULE_SETUP - case 2: - /* rule 2 can match eol */ - YY_RULE_SETUP --#line 74 "dtc-lexer.l" -+#line 75 "dtc-lexer.l" - { - char *line, *tmp, *fn; - /* skip text before line # */ - line = yytext; -- while (!isdigit(*line)) -+ while (!isdigit((unsigned char)*line)) - line++; - /* skip digits in line # */ - tmp = line; -- while (!isspace(*tmp)) -+ while (!isspace((unsigned char)*tmp)) - tmp++; - /* "NULL"-terminate line # */ - *tmp = '\0'; -@@ -970,11 +973,10 @@ YY_RULE_SETUP - } - YY_BREAK - case YY_STATE_EOF(INITIAL): --case YY_STATE_EOF(INCLUDE): - case YY_STATE_EOF(BYTESTRING): - case YY_STATE_EOF(PROPNODENAME): - case YY_STATE_EOF(V1): --#line 95 "dtc-lexer.l" -+#line 96 "dtc-lexer.l" - { - if (!pop_input_file()) { - yyterminate(); -@@ -984,7 +986,7 @@ case YY_STATE_EOF(V1): - case 3: - /* rule 3 can match eol */ - YY_RULE_SETUP --#line 101 "dtc-lexer.l" -+#line 102 "dtc-lexer.l" - { - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, -@@ -994,7 +996,7 @@ YY_RULE_SETUP - YY_BREAK - case 4: - YY_RULE_SETUP --#line 108 "dtc-lexer.l" -+#line 109 "dtc-lexer.l" - { - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; -@@ -1004,25 +1006,33 @@ YY_RULE_SETUP - YY_BREAK - case 5: - YY_RULE_SETUP --#line 115 "dtc-lexer.l" -+#line 116 "dtc-lexer.l" -+{ -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 121 "dtc-lexer.l" - { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 121 "dtc-lexer.l" -+#line 127 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 127 "dtc-lexer.l" -+#line 133 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1030,9 +1040,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 134 "dtc-lexer.l" -+#line 140 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1040,9 +1050,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 141 "dtc-lexer.l" -+#line 147 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1050,38 +1060,65 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 148 "dtc-lexer.l" -+#line 154 "dtc-lexer.l" - { -- yylval.literal = xstrdup(yytext); -- DPRINT("Literal: '%s'\n", yylval.literal); -+ char *e; -+ DPRINT("Integer Literal: '%s'\n", yytext); -+ -+ errno = 0; -+ yylval.integer = strtoull(yytext, &e, 0); -+ -+ assert(!(*e) || !e[strspn(e, "UL")]); -+ -+ if (errno == ERANGE) -+ lexical_error("Integer literal '%s' out of range", -+ yytext); -+ else -+ /* ERANGE is the only strtoull error triggerable -+ * by strings matching the pattern */ -+ assert(errno == 0); - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 154 "dtc-lexer.l" -+#line 173 "dtc-lexer.l" - { -- yytext[yyleng-1] = '\0'; -- yylval.literal = xstrdup(yytext+1); -- DPRINT("Character literal: %s\n", yylval.literal); -+ struct data d; -+ DPRINT("Character literal: %s\n", yytext); -+ -+ d = data_copy_escape_string(yytext+1, yyleng-2); -+ if (d.len == 1) { -+ lexical_error("Empty character literal"); -+ yylval.integer = 0; -+ return DT_CHAR_LITERAL; -+ } -+ -+ yylval.integer = (unsigned char)d.val[0]; -+ -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 161 "dtc-lexer.l" -+#line 194 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 167 "dtc-lexer.l" -+#line 200 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1089,27 +1126,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 174 "dtc-lexer.l" -+#line 207 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 180 "dtc-lexer.l" -+#line 213 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 186 "dtc-lexer.l" -+#line 219 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1118,75 +1155,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 194 "dtc-lexer.l" -+#line 227 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 199 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 200 "dtc-lexer.l" --/* eat C-style comments */ -+#line 232 "dtc-lexer.l" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 201 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 233 "dtc-lexer.l" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 203 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 234 "dtc-lexer.l" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 204 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 236 "dtc-lexer.l" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 205 "dtc-lexer.l" --{ return DT_LE; }; -+#line 237 "dtc-lexer.l" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 206 "dtc-lexer.l" --{ return DT_GE; }; -+#line 238 "dtc-lexer.l" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 207 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 239 "dtc-lexer.l" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 208 "dtc-lexer.l" --{ return DT_NE; }; -+#line 240 "dtc-lexer.l" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 209 "dtc-lexer.l" --{ return DT_AND; }; -+#line 241 "dtc-lexer.l" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 210 "dtc-lexer.l" --{ return DT_OR; }; -+#line 242 "dtc-lexer.l" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 212 "dtc-lexer.l" -+#line 243 "dtc-lexer.l" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 245 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1202,12 +1239,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 227 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1211 "dtc-lexer.lex.c" -+#line 1248 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1499,7 +1536,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 161 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1527,11 +1564,11 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 161 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 160); -+ yy_is_jam = (yy_current_state == 165); - - return yy_is_jam ? 0 : yy_current_state; - } -@@ -2166,7 +2203,7 @@ void yyfree (void * ptr ) - - #define YYTABLES_NAME "yytables" - --#line 227 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - - - -@@ -2182,14 +2219,25 @@ static void push_input_file(const char *filename) - } - - --static int pop_input_file(void) -+static bool pop_input_file(void) - { - if (srcfile_pop() == 0) -- return 0; -+ return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - -- return 1; -+ return true; -+} -+ -+static void lexical_error(const char *fmt, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, fmt); -+ srcpos_verror(&yylloc, "Lexical error", fmt, ap); -+ va_end(ap); -+ -+ treesource_error = true; - } - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index c8769d5..1938d20 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.7.12-4996. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison implementation for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,7 +26,7 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "2.7.12-4996" -+#define YYBISON_VERSION "3.0.2" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -62,34 +62,32 @@ - - - /* Copy the first part of user declarations. */ --/* Line 371 of yacc.c */ --#line 21 "dtc-parser.y" -+#line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include -+#include - - #include "dtc.h" - #include "srcpos.h" - --YYLTYPE yylloc; -- - extern int yylex(void); --extern void print_error(char const *fmt, ...); - extern void yyerror(char const *s); -+#define ERROR(loc, ...) \ -+ do { \ -+ srcpos_error((loc), "Error", __VA_ARGS__); \ -+ treesource_error = true; \ -+ } while (0) - - extern struct boot_info *the_boot_info; --extern int treesource_error; -- --static unsigned long long eval_literal(const char *s, int base, int bits); --static unsigned char eval_char_literal(const char *s); -+extern bool treesource_error; - --/* Line 371 of yacc.c */ --#line 87 "dtc-parser.tab.c" -+#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ - --# ifndef YY_NULL -+# ifndef YY_NULLPTR - # if defined __cplusplus && 201103L <= __cplusplus --# define YY_NULL nullptr -+# define YY_NULLPTR nullptr - # else --# define YY_NULL 0 -+# define YY_NULLPTR 0 - # endif - # endif - -@@ -105,7 +103,7 @@ static unsigned char eval_char_literal(const char *s); - by #include "dtc-parser.tab.h". */ - #ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED - # define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Enabling traces. */ -+/* Debug traces. */ - #ifndef YYDEBUG - # define YYDEBUG 0 - #endif -@@ -113,48 +111,45 @@ static unsigned char eval_char_literal(const char *s); - extern int yydebug; - #endif - --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BASE = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { --/* Line 387 of yacc.c */ --#line 40 "dtc-parser.y" -+#line 39 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; -- char *literal; - char *labelref; -- unsigned int cbase; - uint8_t byte; - struct data data; - -@@ -169,38 +164,38 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - -- --/* Line 387 of yacc.c */ --#line 176 "dtc-parser.tab.c" --} YYSTYPE; -+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --extern YYSTYPE yylval; -- --#ifdef YYPARSE_PARAM --#if defined __STDC__ || defined __cplusplus --int yyparse (void *YYPARSE_PARAM); --#else --int yyparse (); -+/* Location type. */ -+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE -+{ -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+}; -+# define YYLTYPE_IS_DECLARED 1 -+# define YYLTYPE_IS_TRIVIAL 1 - #endif --#else /* ! YYPARSE_PARAM */ --#if defined __STDC__ || defined __cplusplus -+ -+ -+extern YYSTYPE yylval; -+extern YYLTYPE yylloc; - int yyparse (void); --#else --int yyparse (); --#endif --#endif /* ! YYPARSE_PARAM */ - - #endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ - - /* Copy the second part of user declarations. */ - --/* Line 390 of yacc.c */ --#line 204 "dtc-parser.tab.c" -+#line 199 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -214,11 +209,8 @@ typedef unsigned char yytype_uint8; - - #ifdef YYTYPE_INT8 - typedef YYTYPE_INT8 yytype_int8; --#elif (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --typedef signed char yytype_int8; - #else --typedef short int yytype_int8; -+typedef signed char yytype_int8; - #endif - - #ifdef YYTYPE_UINT16 -@@ -238,8 +230,7 @@ typedef short int yytype_int16; - # define YYSIZE_T __SIZE_TYPE__ - # elif defined size_t - # define YYSIZE_T size_t --# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# elif ! defined YYSIZE_T - # include /* INFRINGES ON USER NAME SPACE */ - # define YYSIZE_T size_t - # else -@@ -261,11 +252,30 @@ typedef short int yytype_int16; - # endif - #endif - --#ifndef __attribute__ --/* This feature is available in gcc versions 2.5 and later. */ --# if (! defined __GNUC__ || __GNUC__ < 2 \ -- || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) --# define __attribute__(Spec) /* empty */ -+#ifndef YY_ATTRIBUTE -+# if (defined __GNUC__ \ -+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ -+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -+# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -+# else -+# define YY_ATTRIBUTE(Spec) /* empty */ -+# endif -+#endif -+ -+#ifndef YY_ATTRIBUTE_PURE -+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -+#endif -+ -+#ifndef YY_ATTRIBUTE_UNUSED -+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -+#endif -+ -+#if !defined _Noreturn \ -+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -+# if defined _MSC_VER && 1200 <= _MSC_VER -+# define _Noreturn __declspec (noreturn) -+# else -+# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) - # endif - #endif - -@@ -276,25 +286,26 @@ typedef short int yytype_int16; - # define YYUSE(E) /* empty */ - #endif - -- --/* Identity function, used to suppress warnings about constant conditions. */ --#ifndef lint --# define YYID(N) (N) --#else --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static int --YYID (int yyi) -+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -+/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ -+ _Pragma ("GCC diagnostic push") \ -+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ -+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ -+ _Pragma ("GCC diagnostic pop") - #else --static int --YYID (yyi) -- int yyi; -+# define YY_INITIAL_VALUE(Value) Value - #endif --{ -- return yyi; --} -+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END -+#endif -+#ifndef YY_INITIAL_VALUE -+# define YY_INITIAL_VALUE(Value) /* Nothing. */ - #endif - -+ - #if ! defined yyoverflow || YYERROR_VERBOSE - - /* The parser invokes alloca or malloc; define the necessary symbols. */ -@@ -312,8 +323,7 @@ YYID (yyi) - # define alloca _alloca - # else - # define YYSTACK_ALLOC alloca --# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS - # include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ - # ifndef EXIT_SUCCESS -@@ -325,8 +335,8 @@ YYID (yyi) - # endif - - # ifdef YYSTACK_ALLOC -- /* Pacify GCC's `empty if-body' warning. */ --# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -+ /* Pacify GCC's 'empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) - # ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely -@@ -342,7 +352,7 @@ YYID (yyi) - # endif - # if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ -- && (defined YYFREE || defined free))) -+ && (defined YYFREE || defined free))) - # include /* INFRINGES ON USER NAME SPACE */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 -@@ -350,15 +360,13 @@ YYID (yyi) - # endif - # ifndef YYMALLOC - # define YYMALLOC malloc --# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined malloc && ! defined EXIT_SUCCESS - void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif - # ifndef YYFREE - # define YYFREE free --# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined free && ! defined EXIT_SUCCESS - void free (void *); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif -@@ -368,13 +376,15 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ - - #if (! defined yyoverflow \ - && (! defined __cplusplus \ -- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - - /* A type that is properly aligned for any stack member. */ - union yyalloc - { - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -+ YYLTYPE yyls_alloc; - }; - - /* The size of the maximum gap between one aligned stack and the next. */ -@@ -383,8 +393,8 @@ union yyalloc - /* The size of an array large to enough to hold all stacks, each with - N elements. */ - # define YYSTACK_BYTES(N) \ -- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ -- + YYSTACK_GAP_MAXIMUM) -+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ -+ + 2 * YYSTACK_GAP_MAXIMUM) - - # define YYCOPY_NEEDED 1 - -@@ -393,16 +403,16 @@ union yyalloc - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ --# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -- do \ -- { \ -- YYSIZE_T yynewbytes; \ -- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -- Stack = &yyptr->Stack_alloc; \ -- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -- yyptr += yynewbytes / sizeof (*yyptr); \ -- } \ -- while (YYID (0)) -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) - - #endif - -@@ -421,7 +431,7 @@ union yyalloc - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ -- while (YYID (0)) -+ while (0) - # endif - # endif - #endif /* !YYCOPY_NEEDED */ -@@ -429,25 +439,27 @@ union yyalloc - /* YYFINAL -- State number of the termination state. */ - #define YYFINAL 4 - /* YYLAST -- Last index in YYTABLE. */ --#define YYLAST 133 -+#define YYLAST 135 - - /* YYNTOKENS -- Number of terminals. */ - #define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 29 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 79 --/* YYNRULES -- Number of states. */ --#define YYNSTATES 141 -+#define YYNRULES 81 -+/* YYNSTATES -- Number of states. */ -+#define YYNSTATES 144 - --/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned -+ by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 - #define YYMAXUTOK 279 - --#define YYTRANSLATE(YYX) \ -+#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - --/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM -+ as returned by yylex, without out-of-bounds checking. */ - static const yytype_uint8 yytranslate[] = - { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -481,63 +493,18 @@ static const yytype_uint8 yytranslate[] = - }; - - #if YYDEBUG --/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -- YYRHS. */ --static const yytype_uint16 yyprhs[] = --{ -- 0, 0, 3, 8, 9, 12, 17, 20, 23, 27, -- 31, 36, 42, 43, 46, 51, 54, 58, 61, 64, -- 68, 73, 76, 86, 92, 95, 96, 99, 102, 106, -- 108, 111, 114, 117, 119, 121, 125, 127, 129, 135, -- 137, 141, 143, 147, 149, 153, 155, 159, 161, 165, -- 167, 171, 175, 177, 181, 185, 189, 193, 197, 201, -- 203, 207, 211, 213, 217, 221, 225, 227, 229, 232, -- 235, 238, 239, 242, 245, 246, 249, 252, 255, 259 --}; -- --/* YYRHS -- A `-1'-separated list of the rules' RHS. */ --static const yytype_int8 yyrhs[] = --{ -- 49, 0, -1, 3, 25, 50, 52, -1, -1, 51, -- 50, -1, 4, 59, 59, 25, -1, 22, 51, -1, -- 26, 53, -1, 52, 26, 53, -1, 52, 23, 53, -- -1, 52, 15, 23, 25, -1, 27, 54, 74, 28, -- 25, -1, -1, 54, 55, -1, 16, 29, 56, 25, -- -1, 16, 25, -1, 14, 16, 25, -1, 22, 55, -- -1, 57, 21, -1, 57, 58, 30, -1, 57, 31, -- 73, 32, -1, 57, 23, -1, 57, 24, 33, 21, -- 34, 59, 34, 59, 35, -1, 57, 24, 33, 21, -- 35, -1, 56, 22, -1, -1, 56, 34, -1, 57, -- 22, -1, 13, 17, 36, -1, 36, -1, 58, 59, -- -1, 58, 23, -1, 58, 22, -1, 17, -1, 18, -- -1, 33, 60, 35, -1, 61, -1, 62, -1, 62, -- 37, 60, 38, 61, -1, 63, -1, 62, 12, 63, -- -1, 64, -1, 63, 11, 64, -1, 65, -1, 64, -- 39, 65, -1, 66, -1, 65, 40, 66, -1, 67, -- -1, 66, 41, 67, -1, 68, -1, 67, 9, 68, -- -1, 67, 10, 68, -1, 69, -1, 68, 36, 69, -- -1, 68, 30, 69, -1, 68, 7, 69, -1, 68, -- 8, 69, -1, 69, 5, 70, -1, 69, 6, 70, -- -1, 70, -1, 70, 42, 71, -1, 70, 43, 71, -- -1, 71, -1, 71, 44, 72, -1, 71, 26, 72, -- -1, 71, 45, 72, -1, 72, -1, 59, -1, 43, -- 72, -1, 46, 72, -1, 47, 72, -1, -1, 73, -- 20, -1, 73, 22, -1, -1, 75, 74, -1, 75, -- 55, -1, 16, 53, -1, 15, 16, 25, -1, 22, -- 75, -1 --}; -- --/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 109, 109, 118, 121, 128, 132, 140, 144, 148, -- 158, 172, 180, 183, 190, 194, 198, 202, 210, 214, -- 218, 222, 226, 243, 253, 261, 264, 268, 275, 290, -- 295, 315, 329, 336, 340, 344, 351, 355, 356, 360, -- 361, 365, 366, 370, 371, 375, 376, 380, 381, 385, -- 386, 387, 391, 392, 393, 394, 395, 399, 400, 401, -- 405, 406, 407, 411, 412, 413, 414, 418, 419, 420, -- 421, 426, 429, 433, 441, 444, 448, 456, 460, 464 -+ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, -+ 156, 160, 170, 185, 193, 196, 203, 207, 211, 215, -+ 223, 227, 231, 235, 239, 255, 265, 273, 276, 280, -+ 287, 303, 308, 327, 341, 348, 349, 350, 357, 361, -+ 362, 366, 367, 371, 372, 376, 377, 381, 382, 386, -+ 387, 391, 392, 393, 397, 398, 399, 400, 401, 405, -+ 406, 407, 411, 412, 413, 417, 418, 419, 420, 424, -+ 425, 426, 427, 432, 435, 439, 447, 450, 454, 462, -+ 466, 470 - }; - #endif - -@@ -546,25 +513,25 @@ static const yytype_uint16 yyrline[] = - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", - "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", - "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", - "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULL -+ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -+ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -+ "integer_prim", "integer_expr", "integer_trinary", "integer_or", -+ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -+ "integer_eq", "integer_rela", "integer_shift", "integer_add", -+ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR - }; - #endif - - # ifdef YYPRINT --/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -- token YYLEX-NUM. */ -+/* YYTOKNUM[NUM] -- (External) token number corresponding to the -+ (internal) symbol number NUM (which must be that of a token). */ - static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -@@ -575,183 +542,173 @@ static const yytype_uint16 yytoknum[] = - }; - # endif - --/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ --static const yytype_uint8 yyr1[] = --{ -- 0, 48, 49, 50, 50, 51, 51, 52, 52, 52, -- 52, 53, 54, 54, 55, 55, 55, 55, 56, 56, -- 56, 56, 56, 56, 56, 57, 57, 57, 58, 58, -- 58, 58, 58, 59, 59, 59, 60, 61, 61, 62, -- 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, -- 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, -- 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, -- 72, 73, 73, 73, 74, 74, 74, 75, 75, 75 --}; -+#define YYPACT_NINF -41 - --/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ --static const yytype_uint8 yyr2[] = -+#define yypact_value_is_default(Yystate) \ -+ (!!((Yystate) == (-41))) -+ -+#define YYTABLE_NINF -1 -+ -+#define yytable_value_is_error(Yytable_value) \ -+ 0 -+ -+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+static const yytype_int8 yypact[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 3, -- 4, 5, 0, 2, 4, 2, 3, 2, 2, 3, -- 4, 2, 9, 5, 2, 0, 2, 2, 3, 1, -- 2, 2, 2, 1, 1, 3, 1, 1, 5, 1, -- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, -- 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, -- 3, 3, 1, 3, 3, 3, 1, 1, 2, 2, -- 2, 0, 2, 2, 0, 2, 2, 2, 3, 2 -+ 37, 10, 24, 78, -41, 20, 9, -41, 8, 9, -+ 59, 9, -41, -41, -10, 8, -41, 60, 39, -41, -+ -10, -10, -10, -41, 51, -41, -7, 76, 50, 52, -+ 53, 49, 2, 65, 32, -1, -41, 66, -41, -41, -+ 67, 60, 60, -41, -41, -41, -41, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -41, 41, 68, -41, -+ -41, 76, 57, 50, 52, 53, 49, 2, 2, 65, -+ 65, 65, 65, 32, 32, -1, -1, -41, -41, -41, -+ 79, 80, -12, 41, -41, 70, 41, -41, -10, 74, -+ 75, -41, -41, -41, -41, -41, 77, -41, -41, -41, -+ -41, -41, 17, -2, -41, -41, -41, -41, 83, -41, -+ -41, -41, 71, -41, -41, 31, 69, 82, -4, -41, -+ -41, -41, -41, -41, 42, -41, -41, -41, 8, -41, -+ 72, 8, 73, -41 - }; - --/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -- Performed when YYTABLE doesn't specify something else to do. Zero -- means the default is an error. */ -+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE does not specify something else to do. Zero -+ means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 33, -- 34, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 67, 0, 36, 37, 39, 41, 43, 45, 47, 49, -- 52, 59, 62, 66, 0, 12, 7, 0, 0, 0, -- 68, 69, 70, 35, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -+ 0, 5, 35, 36, 0, 0, 8, 0, 2, 6, -+ 0, 0, 0, 69, 0, 38, 39, 41, 43, 45, -+ 47, 49, 51, 54, 61, 64, 68, 0, 14, 9, -+ 0, 0, 0, 70, 71, 72, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 5, 74, 0, 9, 8, 40, 0, -- 42, 44, 46, 48, 50, 51, 55, 56, 54, 53, -- 57, 58, 60, 61, 64, 63, 65, 0, 0, 0, -- 0, 13, 0, 74, 10, 0, 0, 0, 15, 25, -- 77, 17, 79, 0, 76, 75, 38, 16, 78, 0, -- 0, 11, 24, 14, 26, 0, 18, 27, 21, 0, -- 71, 29, 0, 0, 0, 0, 32, 31, 19, 30, -- 28, 0, 72, 73, 20, 0, 23, 0, 0, 0, -- 22 -+ 0, 0, 0, 0, 0, 0, 7, 76, 0, 11, -+ 10, 42, 0, 44, 46, 48, 50, 52, 53, 57, -+ 58, 56, 55, 59, 60, 62, 63, 66, 65, 67, -+ 0, 0, 0, 0, 15, 0, 76, 12, 0, 0, -+ 0, 17, 27, 79, 19, 81, 0, 78, 77, 40, -+ 18, 80, 0, 0, 13, 26, 16, 28, 0, 20, -+ 29, 23, 0, 73, 31, 0, 0, 0, 0, 34, -+ 33, 21, 32, 30, 0, 74, 75, 22, 0, 25, -+ 0, 0, 0, 24 - }; - --/* YYDEFGOTO[NTERM-NUM]. */ --static const yytype_int8 yydefgoto[] = -+ /* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = - { -- -1, 2, 7, 8, 15, 36, 64, 91, 109, 110, -- 122, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 125, 92, 93 -+ -41, -41, -41, 96, 100, -41, -40, -41, -23, -41, -+ -41, -41, -8, 62, 13, -41, 81, 63, 64, 84, -+ 61, 25, 11, 21, 22, -17, -41, 19, 23 - }; - --/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -- STATE-NUM. */ --#define YYPACT_NINF -78 --static const yytype_int8 yypact[] = -+ /* YYDEFGOTO[NTERM-NUM]. */ -+static const yytype_int16 yydefgoto[] = - { -- 22, 11, 51, 10, -78, 23, 10, 2, 10, -78, -- -78, -9, 23, -78, 30, 38, -78, -9, -9, -9, -- -78, 35, -78, -6, 52, 29, 48, 49, 33, 3, -- 71, 36, 0, -78, 64, -78, -78, 68, 30, 30, -- -78, -78, -78, -78, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -78, 44, 67, -78, -78, 52, 55, -- 29, 48, 49, 33, 3, 3, 71, 71, 71, 71, -- 36, 36, 0, 0, -78, -78, -78, 78, 79, 42, -- 44, -78, 69, 44, -78, -9, 73, 74, -78, -78, -- -78, -78, -78, 75, -78, -78, -78, -78, -78, -7, -- -1, -78, -78, -78, -78, 84, -78, -78, -78, 63, -- -78, -78, 32, 66, 82, -3, -78, -78, -78, -78, -- -78, 46, -78, -78, -78, 23, -78, 70, 23, 72, -- -78 -+ -1, 2, 6, 10, 11, 18, 39, 67, 94, 112, -+ 113, 125, 23, 24, 25, 26, 27, 28, 29, 30, -+ 31, 32, 33, 34, 35, 36, 128, 95, 96 - }; - --/* YYPGOTO[NTERM-NUM]. */ --static const yytype_int8 yypgoto[] = -+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule whose -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+static const yytype_uint8 yytable[] = - { -- -78, -78, 97, 100, -78, -37, -78, -77, -78, -78, -- -78, -5, 65, 13, -78, 76, 77, 62, 80, 83, -- 34, 20, 26, 28, -14, -78, 18, 24 -+ 15, 69, 70, 43, 44, 45, 47, 37, 12, 13, -+ 55, 56, 118, 101, 8, 38, 135, 102, 136, 119, -+ 120, 121, 122, 14, 4, 63, 12, 13, 137, 123, -+ 48, 9, 57, 20, 124, 3, 21, 22, 58, 115, -+ 1, 14, 116, 64, 65, 7, 87, 88, 89, 12, -+ 13, 117, 103, 129, 130, 40, 90, 91, 92, 53, -+ 54, 131, 41, 93, 14, 42, 79, 80, 81, 82, -+ 104, 59, 60, 107, 61, 62, 138, 139, 77, 78, -+ 83, 84, 5, 85, 86, 17, 46, 38, 49, 50, -+ 68, 66, 51, 97, 52, 98, 99, 100, 106, 110, -+ 111, 126, 114, 134, 127, 133, 141, 19, 143, 16, -+ 72, 109, 73, 76, 74, 108, 105, 132, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, -+ 140, 0, 0, 142, 0, 75 - }; - --/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -- positive, shift that token. If negative, reduce the rule which -- number is the opposite. If YYTABLE_NINF, syntax error. */ --#define YYTABLE_NINF -1 --static const yytype_uint8 yytable[] = -+static const yytype_int16 yycheck[] = - { -- 12, 66, 67, 40, 41, 42, 44, 34, 9, 10, -- 52, 53, 115, 101, 5, 112, 104, 132, 113, 133, -- 116, 117, 118, 119, 11, 1, 60, 114, 14, 134, -- 120, 45, 6, 54, 17, 121, 3, 18, 19, 55, -- 9, 10, 50, 51, 61, 62, 84, 85, 86, 9, -- 10, 4, 100, 37, 126, 127, 11, 35, 87, 88, -- 89, 38, 128, 46, 39, 11, 90, 98, 47, 35, -- 43, 99, 76, 77, 78, 79, 56, 57, 58, 59, -- 135, 136, 80, 81, 74, 75, 82, 83, 48, 63, -- 49, 65, 94, 95, 96, 97, 124, 103, 107, 108, -- 111, 123, 130, 131, 138, 16, 13, 140, 106, 71, -- 69, 105, 0, 0, 102, 0, 0, 129, 0, 0, -- 68, 0, 0, 70, 0, 0, 0, 0, 72, 0, -- 137, 0, 73, 139 -+ 8, 41, 42, 20, 21, 22, 13, 15, 18, 19, -+ 8, 9, 14, 25, 5, 27, 20, 29, 22, 21, -+ 22, 23, 24, 33, 0, 26, 18, 19, 32, 31, -+ 37, 22, 30, 43, 36, 25, 46, 47, 36, 22, -+ 3, 33, 25, 44, 45, 25, 63, 64, 65, 18, -+ 19, 34, 92, 22, 23, 16, 15, 16, 17, 10, -+ 11, 30, 23, 22, 33, 26, 55, 56, 57, 58, -+ 93, 6, 7, 96, 42, 43, 34, 35, 53, 54, -+ 59, 60, 4, 61, 62, 26, 35, 27, 12, 39, -+ 23, 25, 40, 25, 41, 38, 17, 17, 28, 25, -+ 25, 18, 25, 21, 33, 36, 34, 11, 35, 9, -+ 48, 98, 49, 52, 50, 96, 93, 125, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1, 47, -1, -+ 138, -1, -1, 141, -1, 51 - }; - --#define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-78))) -- --#define yytable_value_is_error(Yytable_value) \ -- YYID (0) -+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = -+{ -+ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -+ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -+ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -+ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -+ 16, 23, 26, 73, 73, 73, 35, 13, 37, 12, -+ 39, 40, 41, 10, 11, 8, 9, 30, 36, 6, -+ 7, 42, 43, 26, 44, 45, 25, 55, 23, 54, -+ 54, 64, 61, 65, 66, 67, 68, 69, 69, 70, -+ 70, 70, 70, 71, 71, 72, 72, 73, 73, 73, -+ 15, 16, 17, 22, 56, 75, 76, 25, 38, 17, -+ 17, 25, 29, 54, 56, 76, 28, 56, 75, 62, -+ 25, 25, 57, 58, 25, 22, 25, 34, 14, 21, -+ 22, 23, 24, 31, 36, 59, 18, 33, 74, 22, -+ 23, 30, 60, 36, 21, 20, 22, 32, 34, 35, -+ 60, 34, 60, 35 -+}; - --static const yytype_int16 yycheck[] = -+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = - { -- 5, 38, 39, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 13, 90, 4, 22, 93, 20, 25, 22, -- 21, 22, 23, 24, 33, 3, 26, 34, 26, 32, -- 31, 37, 22, 30, 43, 36, 25, 46, 47, 36, -- 17, 18, 9, 10, 44, 45, 60, 61, 62, 17, -- 18, 0, 89, 15, 22, 23, 33, 27, 14, 15, -- 16, 23, 30, 11, 26, 33, 22, 25, 39, 27, -- 35, 29, 52, 53, 54, 55, 5, 6, 42, 43, -- 34, 35, 56, 57, 50, 51, 58, 59, 40, 25, -- 41, 23, 25, 38, 16, 16, 33, 28, 25, 25, -- 25, 17, 36, 21, 34, 8, 6, 35, 95, 47, -- 45, 93, -1, -1, 90, -1, -1, 122, -1, -1, -- 44, -1, -1, 46, -1, -1, -1, -1, 48, -1, -- 135, -1, 49, 138 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 53, 53, 54, 55, 55, 56, 56, 56, 56, -+ 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, -+ 59, 59, 59, 59, 59, 60, 60, 60, 61, 62, -+ 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, -+ 67, 68, 68, 68, 69, 69, 69, 69, 69, 70, -+ 70, 70, 71, 71, 71, 72, 72, 72, 72, 73, -+ 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, -+ 76, 76 - }; - --/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -- symbol of state STATE-NUM. */ --static const yytype_uint8 yystos[] = -+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = - { -- 0, 3, 49, 25, 0, 4, 22, 50, 51, 17, -- 18, 33, 59, 51, 26, 52, 50, 43, 46, 47, -- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, -- 69, 70, 71, 72, 59, 27, 53, 15, 23, 26, -- 72, 72, 72, 35, 12, 37, 11, 39, 40, 41, -- 9, 10, 7, 8, 30, 36, 5, 6, 42, 43, -- 26, 44, 45, 25, 54, 23, 53, 53, 63, 60, -- 64, 65, 66, 67, 68, 68, 69, 69, 69, 69, -- 70, 70, 71, 71, 72, 72, 72, 14, 15, 16, -- 22, 55, 74, 75, 25, 38, 16, 16, 25, 29, -- 53, 55, 75, 28, 55, 74, 61, 25, 25, 56, -- 57, 25, 22, 25, 34, 13, 21, 22, 23, 24, -- 31, 36, 58, 17, 33, 73, 22, 23, 30, 59, -- 36, 21, 20, 22, 32, 34, 35, 59, 34, 59, -- 35 -+ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -+ 3, 3, 4, 5, 0, 2, 4, 2, 3, 2, -+ 2, 3, 4, 2, 9, 5, 2, 0, 2, 2, -+ 3, 1, 2, 2, 2, 1, 1, 3, 1, 1, -+ 5, 1, 3, 1, 3, 1, 3, 1, 3, 1, -+ 3, 1, 3, 3, 1, 3, 3, 3, 3, 3, -+ 3, 1, 3, 3, 1, 3, 3, 3, 1, 1, -+ 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, -+ 3, 2 - }; - --#define yyerrok (yyerrstatus = 0) --#define yyclearin (yychar = YYEMPTY) --#define YYEMPTY (-2) --#define YYEOF 0 -- --#define YYACCEPT goto yyacceptlab --#define YYABORT goto yyabortlab --#define YYERROR goto yyerrorlab -- -- --/* Like YYERROR except do call yyerror. This remains here temporarily -- to ease the transition to the new meaning of YYERROR, for GCC. -- Once GCC version 2 has supplanted version 1, this can go. However, -- YYFAIL appears to be in use. Nevertheless, it is formally deprecated -- in Bison 2.4.2's NEWS entry, where a plan to phase it out is -- discussed. */ -- --#define YYFAIL goto yyerrlab --#if defined YYFAIL -- /* This is here to suppress warnings from the GCC cpp's -- -Wunused-macros. Normally we don't worry about that warning, but -- some users do, and we want to make it easy for users to remove -- YYFAIL uses, which will produce warnings from Bison 2.5. */ --#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ - - #define YYRECOVERING() (!!yyerrstatus) - -@@ -768,27 +725,41 @@ do \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ -- YYERROR; \ -- } \ --while (YYID (0)) -+ YYERROR; \ -+ } \ -+while (0) - - /* Error token number */ --#define YYTERROR 1 --#define YYERRCODE 256 -- -- --/* This macro is provided for backward compatibility. */ --#ifndef YY_LOCATION_PRINT --# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) - #endif - -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - --/* YYLEX -- calling `yylex' with the right arguments. */ --#ifdef YYLEX_PARAM --# define YYLEX yylex (YYLEX_PARAM) --#else --# define YYLEX yylex () --#endif - - /* Enable debugging if requested. */ - #if YYDEBUG -@@ -798,50 +769,84 @@ while (YYID (0)) - # define YYFPRINTF fprintf - # endif - --# define YYDPRINTF(Args) \ --do { \ -- if (yydebug) \ -- YYFPRINTF Args; \ --} while (YYID (0)) -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) - --# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ --do { \ -- if (yydebug) \ -- { \ -- YYFPRINTF (stderr, "%s ", Title); \ -- yy_symbol_print (stderr, \ -- Type, Value); \ -- YYFPRINTF (stderr, "\n"); \ -- } \ --} while (YYID (0)) - -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ - --/*--------------------------------. --| Print this symbol on YYOUTPUT. | --`--------------------------------*/ -+#ifndef YY_LOCATION_PRINT -+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static void --yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) --#else --static void --yy_symbol_value_print (yyoutput, yytype, yyvaluep) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; -+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ -+ -+YY_ATTRIBUTE_UNUSED -+static unsigned -+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -+{ -+ unsigned res = 0; -+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; -+ if (0 <= yylocp->first_line) -+ { -+ res += YYFPRINTF (yyo, "%d", yylocp->first_line); -+ if (0 <= yylocp->first_column) -+ res += YYFPRINTF (yyo, ".%d", yylocp->first_column); -+ } -+ if (0 <= yylocp->last_line) -+ { -+ if (yylocp->first_line < yylocp->last_line) -+ { -+ res += YYFPRINTF (yyo, "-%d", yylocp->last_line); -+ if (0 <= end_col) -+ res += YYFPRINTF (yyo, ".%d", end_col); -+ } -+ else if (0 <= end_col && yylocp->first_column < end_col) -+ res += YYFPRINTF (yyo, "-%d", end_col); -+ } -+ return res; -+ } -+ -+# define YY_LOCATION_PRINT(File, Loc) \ -+ yy_location_print_ (File, &(Loc)) -+ -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif - #endif -+ -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+ -+/*----------------------------------------. -+| Print this symbol's value on YYOUTPUT. | -+`----------------------------------------*/ -+ -+static void -+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) - { - FILE *yyo = yyoutput; - YYUSE (yyo); -+ YYUSE (yylocationp); - if (!yyvaluep) - return; - # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); --# else -- YYUSE (yyoutput); - # endif - YYUSE (yytype); - } -@@ -851,24 +856,15 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static void --yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) --#else - static void --yy_symbol_print (yyoutput, yytype, yyvaluep) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; --#endif -+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) - { -- if (yytype < YYNTOKENS) -- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -- else -- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ YYFPRINTF (yyoutput, "%s %s (", -+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - -- yy_symbol_value_print (yyoutput, yytype, yyvaluep); -+ YY_LOCATION_PRINT (yyoutput, *yylocationp); -+ YYFPRINTF (yyoutput, ": "); -+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); - YYFPRINTF (yyoutput, ")"); - } - -@@ -877,16 +873,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) - | TOP (included). | - `------------------------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) --#else --static void --yy_stack_print (yybottom, yytop) -- yytype_int16 *yybottom; -- yytype_int16 *yytop; --#endif - { - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) -@@ -897,49 +885,42 @@ yy_stack_print (yybottom, yytop) - YYFPRINTF (stderr, "\n"); - } - --# define YY_STACK_PRINT(Bottom, Top) \ --do { \ -- if (yydebug) \ -- yy_stack_print ((Bottom), (Top)); \ --} while (YYID (0)) -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) - - - /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - `------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void --yy_reduce_print (YYSTYPE *yyvsp, int yyrule) --#else --static void --yy_reduce_print (yyvsp, yyrule) -- YYSTYPE *yyvsp; -- int yyrule; --#endif -+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) - { -+ unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; -- unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -- yyrule - 1, yylno); -+ yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); -- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -- &(yyvsp[(yyi + 1) - (yynrhs)]) -- ); -+ yy_symbol_print (stderr, -+ yystos[yyssp[yyi + 1 - yynrhs]], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } - } - --# define YY_REDUCE_PRINT(Rule) \ --do { \ -- if (yydebug) \ -- yy_reduce_print (yyvsp, Rule); \ --} while (YYID (0)) -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ -+} while (0) - - /* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -@@ -953,7 +934,7 @@ int yydebug; - - - /* YYINITDEPTH -- initial size of the parser's stacks. */ --#ifndef YYINITDEPTH -+#ifndef YYINITDEPTH - # define YYINITDEPTH 200 - #endif - -@@ -976,15 +957,8 @@ int yydebug; - # define yystrlen strlen - # else - /* Return the length of YYSTR. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static YYSIZE_T - yystrlen (const char *yystr) --#else --static YYSIZE_T --yystrlen (yystr) -- const char *yystr; --#endif - { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) -@@ -1000,16 +974,8 @@ yystrlen (yystr) - # else - /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static char * - yystpcpy (char *yydest, const char *yysrc) --#else --static char * --yystpcpy (yydest, yysrc) -- char *yydest; -- const char *yysrc; --#endif - { - char *yyd = yydest; - const char *yys = yysrc; -@@ -1039,27 +1005,27 @@ yytnamerr (char *yyres, const char *yystr) - char const *yyp = yystr; - - for (;;) -- switch (*++yyp) -- { -- case '\'': -- case ',': -- goto do_not_strip_quotes; -- -- case '\\': -- if (*++yyp != '\\') -- goto do_not_strip_quotes; -- /* Fall through. */ -- default: -- if (yyres) -- yyres[yyn] = *yyp; -- yyn++; -- break; -- -- case '"': -- if (yyres) -- yyres[yyn] = '\0'; -- return yyn; -- } -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } - do_not_strip_quotes: ; - } - -@@ -1082,11 +1048,11 @@ static int - yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) - { -- YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); -+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ -- const char *yyformat = YY_NULL; -+ const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per -@@ -1094,10 +1060,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - int yycount = 0; - - /* There are many possibilities here to consider: -- - Assume YYFAIL is not used. It's too flawed to consider. See -- -- for details. YYERROR is fine as it does not invoke this -- function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected -@@ -1147,7 +1109,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - } - yyarg[yycount++] = yytname[yyx]; - { -- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); -+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; -@@ -1214,26 +1176,18 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - | Release the memory associated to this symbol. | - `-----------------------------------------------*/ - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void --yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) --#else --static void --yydestruct (yymsg, yytype, yyvaluep) -- const char *yymsg; -- int yytype; -- YYSTYPE *yyvaluep; --#endif -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) - { - YYUSE (yyvaluep); -- -+ YYUSE (yylocationp); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - } - - -@@ -1242,18 +1196,14 @@ yydestruct (yymsg, yytype, yyvaluep) - /* The lookahead symbol. */ - int yychar; - -- --#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_END --#endif --#ifndef YY_INITIAL_VALUE --# define YY_INITIAL_VALUE(Value) /* Nothing. */ --#endif -- - /* The semantic value of the lookahead symbol. */ --YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); -- -+YYSTYPE yylval; -+/* Location data for the lookahead symbol. */ -+YYLTYPE yylloc -+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+ = { 1, 1, 1, 1 } -+# endif -+; - /* Number of syntax errors so far. */ - int yynerrs; - -@@ -1262,35 +1212,17 @@ int yynerrs; - | yyparse. | - `----------*/ - --#ifdef YYPARSE_PARAM --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --int --yyparse (void *YYPARSE_PARAM) --#else --int --yyparse (YYPARSE_PARAM) -- void *YYPARSE_PARAM; --#endif --#else /* ! YYPARSE_PARAM */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - int - yyparse (void) --#else --int --yyparse () -- --#endif --#endif - { - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: -- `yyss': related to states. -- `yyvs': related to semantic values. -+ 'yyss': related to states. -+ 'yyvs': related to semantic values. -+ 'yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ -@@ -1305,6 +1237,14 @@ yyparse () - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - -+ /* The location stack. */ -+ YYLTYPE yylsa[YYINITDEPTH]; -+ YYLTYPE *yyls; -+ YYLTYPE *yylsp; -+ -+ /* The locations where the error started and ended. */ -+ YYLTYPE yyerror_range[3]; -+ - YYSIZE_T yystacksize; - - int yyn; -@@ -1314,6 +1254,7 @@ yyparse () - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -+ YYLTYPE yyloc; - - #if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ -@@ -1322,7 +1263,7 @@ yyparse () - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; - #endif - --#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) -+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ -@@ -1330,6 +1271,7 @@ yyparse () - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; -+ yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); -@@ -1338,6 +1280,7 @@ yyparse () - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ -+ yylsp[0] = yylloc; - goto yysetstate; - - /*------------------------------------------------------------. -@@ -1358,23 +1301,26 @@ yyparse () - - #ifdef yyoverflow - { -- /* Give user a chance to reallocate the stack. Use copies of -- these so that the &'s don't force the real ones into -- memory. */ -- YYSTYPE *yyvs1 = yyvs; -- yytype_int16 *yyss1 = yyss; -- -- /* Each stack pointer address is followed by the size of the -- data in use in that stack, in bytes. This used to be a -- conditional around just the two extra args, but that might -- be undefined if yyoverflow is a macro. */ -- yyoverflow (YY_("memory exhausted"), -- &yyss1, yysize * sizeof (*yyssp), -- &yyvs1, yysize * sizeof (*yyvsp), -- &yystacksize); -- -- yyss = yyss1; -- yyvs = yyvs1; -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; - } - #else /* no yyoverflow */ - # ifndef YYSTACK_RELOCATE -@@ -1382,34 +1328,36 @@ yyparse () - # else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) -- goto yyexhaustedlab; -+ goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) -- yystacksize = YYMAXDEPTH; -+ yystacksize = YYMAXDEPTH; - - { -- yytype_int16 *yyss1 = yyss; -- union yyalloc *yyptr = -- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -- if (! yyptr) -- goto yyexhaustedlab; -- YYSTACK_RELOCATE (yyss_alloc, yyss); -- YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ YYSTACK_RELOCATE (yyls_alloc, yyls); - # undef YYSTACK_RELOCATE -- if (yyss1 != yyssa) -- YYSTACK_FREE (yyss1); -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); - } - # endif - #endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; -+ yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", -- (unsigned long int) yystacksize)); -+ (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) -- YYABORT; -+ YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -@@ -1438,7 +1386,7 @@ yybackup: - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); -- yychar = YYLEX; -+ yychar = yylex (); - } - - if (yychar <= YYEOF) -@@ -1481,7 +1429,7 @@ yybackup: - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END -- -+ *++yylsp = yylloc; - goto yynewstate; - - -@@ -1503,7 +1451,7 @@ yyreduce: - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: -- `$$ = $1'. -+ '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison -@@ -1512,287 +1460,306 @@ yyreduce: - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - -- -+ /* Default location. */ -+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: --/* Line 1787 of yacc.c */ --#line 110 "dtc-parser.y" -+#line 109 "dtc-parser.y" /* yacc.c:1646 */ - { -- the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), -- guess_boot_cpuid((yyvsp[(4) - (4)].node))); -+ (yyvsp[0].node)->is_plugin = (yyvsp[-2].is_plugin); -+ (yyvsp[0].node)->is_root = 1; -+ the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -+ guess_boot_cpuid((yyvsp[0].node))); - } -+#line 1477 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --/* Line 1787 of yacc.c */ --#line 118 "dtc-parser.y" -+#line 119 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.is_plugin) = 0; - } -+#line 1485 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --/* Line 1787 of yacc.c */ --#line 122 "dtc-parser.y" -+#line 123 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); -+ (yyval.is_plugin) = 1; - } -+#line 1493 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: --/* Line 1787 of yacc.c */ --#line 129 "dtc-parser.y" -+#line 130 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); -+ (yyval.re) = NULL; - } -+#line 1501 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: --/* Line 1787 of yacc.c */ --#line 133 "dtc-parser.y" -+#line 134 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.re) = (yyvsp[(2) - (2)].re); -+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } -+#line 1509 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: --/* Line 1787 of yacc.c */ --#line 141 "dtc-parser.y" -+#line 141 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); -+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } -+#line 1517 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: --/* Line 1787 of yacc.c */ --#line 145 "dtc-parser.y" -+#line 145 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); -+ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); -+ (yyval.re) = (yyvsp[0].re); - } -+#line 1526 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: --/* Line 1787 of yacc.c */ --#line 149 "dtc-parser.y" -+#line 153 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); -- -- if (target) -- merge_nodes(target, (yyvsp[(3) - (3)].node)); -- else -- print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); -- (yyval.node) = (yyvsp[(1) - (3)].node); -+ (yyval.node) = name_node((yyvsp[0].node), ""); - } -+#line 1534 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: --/* Line 1787 of yacc.c */ --#line 159 "dtc-parser.y" -+#line 157 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -- -- if (!target) -- print_error("label or path, '%s', not found", (yyvsp[(3) - (4)].labelref)); -- else -- delete_node(target); -- -- (yyval.node) = (yyvsp[(1) - (4)].node); -+ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } -+#line 1542 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: --/* Line 1787 of yacc.c */ --#line 173 "dtc-parser.y" -+#line 161 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); -+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); -+ -+ if (target) -+ merge_nodes(target, (yyvsp[0].node)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-2].node); - } -+#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: --/* Line 1787 of yacc.c */ --#line 180 "dtc-parser.y" -+#line 171 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = NULL; -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ -+ if (target) -+ delete_node(target); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ -+ -+ (yyval.node) = (yyvsp[-3].node); - } -+#line 1572 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: --/* Line 1787 of yacc.c */ --#line 184 "dtc-parser.y" -+#line 186 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); -+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } -+#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: --/* Line 1787 of yacc.c */ --#line 191 "dtc-parser.y" -+#line 193 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); -+ (yyval.proplist) = NULL; - } -+#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: --/* Line 1787 of yacc.c */ --#line 195 "dtc-parser.y" -+#line 197 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); -+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } -+#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: --/* Line 1787 of yacc.c */ --#line 199 "dtc-parser.y" -+#line 204 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); -+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } -+#line 1604 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: --/* Line 1787 of yacc.c */ --#line 203 "dtc-parser.y" -+#line 208 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.prop) = (yyvsp[(2) - (2)].prop); -+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } -+#line 1612 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: --/* Line 1787 of yacc.c */ --#line 211 "dtc-parser.y" -+#line 212 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); -+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } -+#line 1620 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: --/* Line 1787 of yacc.c */ --#line 215 "dtc-parser.y" -+#line 216 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); -+ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); -+ (yyval.prop) = (yyvsp[0].prop); - } -+#line 1629 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: --/* Line 1787 of yacc.c */ --#line 219 "dtc-parser.y" -+#line 224 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -+ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } -+#line 1637 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: --/* Line 1787 of yacc.c */ --#line 223 "dtc-parser.y" -+#line 228 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } -+#line 1645 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: --/* Line 1787 of yacc.c */ --#line 227 "dtc-parser.y" -+#line 232 "dtc-parser.y" /* yacc.c:1646 */ - { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); -+ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); -+ } -+#line 1653 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 23: -+#line 236 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); -+ } -+#line 1661 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 24: -+#line 240 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; - -- if ((yyvsp[(6) - (9)].integer) != 0) -- if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) -- print_error("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)(yyvsp[(6) - (9)].integer), -- (yyvsp[(4) - (9)].data).val, -- strerror(errno)); -+ if ((yyvsp[-3].integer) != 0) -+ if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) -+ die("Couldn't seek to offset %llu in \"%s\": %s", -+ (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, -+ strerror(errno)); - -- d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); -+ d = data_copy_file(f, (yyvsp[-1].integer)); - -- (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); -+ (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } -+#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 23: --/* Line 1787 of yacc.c */ --#line 244 "dtc-parser.y" -+ case 25: -+#line 256 "dtc-parser.y" /* yacc.c:1646 */ - { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - -- (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); -+ (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } -+#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --/* Line 1787 of yacc.c */ --#line 254 "dtc-parser.y" -+ case 26: -+#line 266 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1703 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --/* Line 1787 of yacc.c */ --#line 261 "dtc-parser.y" -+ case 27: -+#line 273 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } -+#line 1711 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --/* Line 1787 of yacc.c */ --#line 265 "dtc-parser.y" -+ case 28: -+#line 277 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = (yyvsp[(1) - (2)].data); -+ (yyval.data) = (yyvsp[-1].data); - } -+#line 1719 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --/* Line 1787 of yacc.c */ --#line 269 "dtc-parser.y" -+ case 29: -+#line 281 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1727 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --/* Line 1787 of yacc.c */ --#line 276 "dtc-parser.y" -+ case 30: -+#line 288 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.array).data = empty_data; -- (yyval.array).bits = eval_literal((yyvsp[(2) - (3)].literal), 0, 7); -- -- if (((yyval.array).bits != 8) && -- ((yyval.array).bits != 16) && -- ((yyval.array).bits != 32) && -- ((yyval.array).bits != 64)) -- { -- print_error("Only 8, 16, 32 and 64-bit elements" -- " are currently supported"); -- (yyval.array).bits = 32; -+ unsigned long long bits; -+ -+ bits = (yyvsp[-1].integer); -+ -+ if ((bits != 8) && (bits != 16) && -+ (bits != 32) && (bits != 64)) { -+ ERROR(&(yylsp[-1]), "Array elements must be" -+ " 8, 16, 32 or 64-bits"); -+ bits = 32; - } -+ -+ (yyval.array).data = empty_data; -+ (yyval.array).bits = bits; - } -+#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --/* Line 1787 of yacc.c */ --#line 291 "dtc-parser.y" -+ case 31: -+#line 304 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } -+#line 1756 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --/* Line 1787 of yacc.c */ --#line 296 "dtc-parser.y" -+ case 32: -+#line 309 "dtc-parser.y" /* yacc.c:1646 */ - { -- if ((yyvsp[(1) - (2)].array).bits < 64) { -- uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; -+ if ((yyvsp[-1].array).bits < 64) { -+ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one -@@ -1801,275 +1768,258 @@ yyreduce: - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ -- if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) -- print_error( -- "integer value out of range " -- "%016lx (%d bits)", (yyvsp[(1) - (2)].array).bits); -+ if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) -+ ERROR(&(yylsp[0]), "Value out of range for" -+ " %d-bit array element", (yyvsp[-1].array).bits); - } - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } -+#line 1779 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --/* Line 1787 of yacc.c */ --#line 316 "dtc-parser.y" -+ case 33: -+#line 328 "dtc-parser.y" /* yacc.c:1646 */ - { -- uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); -+ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -- if ((yyvsp[(1) - (2)].array).bits == 32) -- (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, -+ if ((yyvsp[-1].array).bits == 32) -+ (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, - REF_PHANDLE, -- (yyvsp[(2) - (2)].labelref)); -+ (yyvsp[0].labelref)); - else -- print_error("References are only allowed in " -+ ERROR(&(yylsp[0]), "References are only allowed in " - "arrays with 32-bit elements."); - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); -- } -- break; -- -- case 32: --/* Line 1787 of yacc.c */ --#line 330 "dtc-parser.y" -- { -- (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); -- } -- break; -- -- case 33: --/* Line 1787 of yacc.c */ --#line 337 "dtc-parser.y" -- { -- (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } -+#line 1797 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 34: --/* Line 1787 of yacc.c */ --#line 341 "dtc-parser.y" -+#line 342 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal)); -+ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } -+#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 35: --/* Line 1787 of yacc.c */ --#line 345 "dtc-parser.y" -+ case 37: -+#line 351 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.integer) = (yyvsp[(2) - (3)].integer); -+ (yyval.integer) = (yyvsp[-1].integer); - } -- break; -- -- case 38: --/* Line 1787 of yacc.c */ --#line 356 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } -+#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 40: --/* Line 1787 of yacc.c */ --#line 361 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } -+#line 362 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } -+#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 42: --/* Line 1787 of yacc.c */ --#line 366 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } -+#line 367 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } -+#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 44: --/* Line 1787 of yacc.c */ --#line 371 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } -+#line 372 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } -+#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 46: --/* Line 1787 of yacc.c */ --#line 376 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } -+#line 377 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } -+#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 48: --/* Line 1787 of yacc.c */ --#line 381 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } -+#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } -+#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 50: --/* Line 1787 of yacc.c */ --#line 386 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } -+#line 387 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } -+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 51: --/* Line 1787 of yacc.c */ --#line 387 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } -+ case 52: -+#line 392 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } -+#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 53: --/* Line 1787 of yacc.c */ --#line 392 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } -- break; -- -- case 54: --/* Line 1787 of yacc.c */ --#line 393 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } -+#line 393 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } -+#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 55: --/* Line 1787 of yacc.c */ --#line 394 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } -+#line 398 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } -+#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 56: --/* Line 1787 of yacc.c */ --#line 395 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } -+#line 399 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } -+#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 57: --/* Line 1787 of yacc.c */ --#line 399 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } -+#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } -+#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 58: --/* Line 1787 of yacc.c */ --#line 400 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } -+#line 401 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } -+#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 60: --/* Line 1787 of yacc.c */ --#line 405 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } -+ case 59: -+#line 405 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } -+#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 61: --/* Line 1787 of yacc.c */ --#line 406 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } -+ case 60: -+#line 406 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } -+#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 63: --/* Line 1787 of yacc.c */ --#line 411 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } -+ case 62: -+#line 411 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } -+#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 64: --/* Line 1787 of yacc.c */ --#line 412 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } -+ case 63: -+#line 412 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } -+#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 65: --/* Line 1787 of yacc.c */ --#line 413 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } -+#line 417 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } -+#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 68: --/* Line 1787 of yacc.c */ --#line 419 "dtc-parser.y" -- { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } -+ case 66: -+#line 418 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } -+#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 69: --/* Line 1787 of yacc.c */ --#line 420 "dtc-parser.y" -- { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } -+ case 67: -+#line 419 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } -+#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 70: --/* Line 1787 of yacc.c */ --#line 421 "dtc-parser.y" -- { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } -+#line 425 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = -(yyvsp[0].integer); } -+#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 71: --/* Line 1787 of yacc.c */ --#line 426 "dtc-parser.y" -- { -- (yyval.data) = empty_data; -- } -+#line 426 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = ~(yyvsp[0].integer); } -+#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 72: --/* Line 1787 of yacc.c */ --#line 430 "dtc-parser.y" -- { -- (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); -- } -+#line 427 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = !(yyvsp[0].integer); } -+#line 1945 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 73: --/* Line 1787 of yacc.c */ --#line 434 "dtc-parser.y" -+#line 432 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = empty_data; - } -+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 74: --/* Line 1787 of yacc.c */ --#line 441 "dtc-parser.y" -+#line 436 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = NULL; -+ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); - } -+#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: --/* Line 1787 of yacc.c */ --#line 445 "dtc-parser.y" -+#line 440 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: --/* Line 1787 of yacc.c */ --#line 449 "dtc-parser.y" -+#line 447 "dtc-parser.y" /* yacc.c:1646 */ - { -- print_error("syntax error: properties must precede subnodes"); -- YYERROR; -+ (yyval.nodelist) = NULL; - } -+#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: --/* Line 1787 of yacc.c */ --#line 457 "dtc-parser.y" -+#line 451 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); -+ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } -+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: --/* Line 1787 of yacc.c */ --#line 461 "dtc-parser.y" -+#line 455 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); -+ ERROR(&(yylsp[0]), "Properties must precede subnodes"); -+ YYERROR; - } -+#line 1994 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: --/* Line 1787 of yacc.c */ --#line 465 "dtc-parser.y" -+#line 463 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.node) = (yyvsp[(2) - (2)].node); -+ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } -+#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -+ case 80: -+#line 467 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); -+ } -+#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1787 of yacc.c */ --#line 2073 "dtc-parser.tab.c" -+ case 81: -+#line 471 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[0].node); -+ } -+#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ -+#line 2023 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2090,8 +2040,9 @@ yyreduce: - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; -+ *++yylsp = yyloc; - -- /* Now `shift' the result of the reduction. Determine what state -+ /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - -@@ -2106,9 +2057,9 @@ yyreduce: - goto yynewstate; - - --/*------------------------------------. --| yyerrlab -- here on detecting error | --`------------------------------------*/ -+/*--------------------------------------. -+| yyerrlab -- here on detecting error. | -+`--------------------------------------*/ - yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ -@@ -2154,25 +2105,25 @@ yyerrlab: - #endif - } - -- -+ yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an -- error, discard it. */ -+ error, discard it. */ - - if (yychar <= YYEOF) -- { -- /* Return failure if at end of input. */ -- if (yychar == YYEOF) -- YYABORT; -- } -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } - else -- { -- yydestruct ("Error: discarding", -- yytoken, &yylval); -- yychar = YYEMPTY; -- } -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } - } - - /* Else will try to reuse lookahead token after shifting the error -@@ -2191,7 +2142,8 @@ yyerrorlab: - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - -- /* Do not reclaim the symbols of the rule which action triggered -+ yyerror_range[1] = yylsp[1-yylen]; -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; -@@ -2204,29 +2156,29 @@ yyerrorlab: - | yyerrlab1 -- common code for both syntax error and YYERROR. | - `-------------------------------------------------------------*/ - yyerrlab1: -- yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) -- { -- yyn += YYTERROR; -- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -- { -- yyn = yytable[yyn]; -- if (0 < yyn) -- break; -- } -- } -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) -- YYABORT; -- -+ YYABORT; - -+ yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", -- yystos[yystate], yyvsp); -+ yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); -@@ -2236,6 +2188,11 @@ yyerrlab1: - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - -+ yyerror_range[2] = yylloc; -+ /* Using YYLLOC is tempting, but would change the location of -+ the lookahead. YYLOC is available though. */ -+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2); -+ *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -@@ -2275,16 +2232,16 @@ yyreturn: - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", -- yytoken, &yylval); -+ yytoken, &yylval, &yylloc); - } -- /* Do not reclaim the symbols of the rule which action triggered -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", -- yystos[*yyssp], yyvsp); -+ yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } - #ifndef yyoverflow -@@ -2295,72 +2252,12 @@ yyreturn: - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - #endif -- /* Make sure YYID is used. */ -- return YYID (yyresult); -+ return yyresult; - } -+#line 477 "dtc-parser.y" /* yacc.c:1906 */ - - --/* Line 2050 of yacc.c */ --#line 471 "dtc-parser.y" -- -- --void print_error(char const *fmt, ...) --{ -- va_list va; -- -- va_start(va, fmt); -- srcpos_verror(&yylloc, fmt, va); -- va_end(va); -- -- treesource_error = 1; --} -- --void yyerror(char const *s) { -- print_error("%s", s); --} -- --static unsigned long long eval_literal(const char *s, int base, int bits) --{ -- unsigned long long val; -- char *e; -- -- errno = 0; -- val = strtoull(s, &e, base); -- if (*e) { -- size_t uls = strspn(e, "UL"); -- if (e[uls]) -- print_error("bad characters in literal"); -- } -- if ((errno == ERANGE) -- || ((bits < 64) && (val >= (1ULL << bits)))) -- print_error("literal out of range"); -- else if (errno != 0) -- print_error("bad literal"); -- return val; --} -- --static unsigned char eval_char_literal(const char *s) -+void yyerror(char const *s) - { -- int i = 1; -- char c = s[0]; -- -- if (c == '\0') -- { -- print_error("empty character literal"); -- return 0; -- } -- -- /* -- * If the first character in the character literal is a \ then process -- * the remaining characters as an escape encoding. If the first -- * character is neither an escape or a terminator it should be the only -- * character in the literal and will be returned. -- */ -- if (c == '\\') -- c = get_escape_char(s, &i); -- -- if (s[i] != '\0') -- print_error("malformed character literal"); -- -- return c; -+ ERROR(&yylloc, "%s", s); - } -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index b2e7a86..b497956 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.7.12-4996. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison interface for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,13 +26,13 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - #ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED - # define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Enabling traces. */ -+/* Debug traces. */ - #ifndef YYDEBUG - # define YYDEBUG 0 - #endif -@@ -40,48 +40,45 @@ - extern int yydebug; - #endif - --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BASE = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { --/* Line 2053 of yacc.c */ --#line 40 "dtc-parser.y" -+#line 39 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; -- char *literal; - char *labelref; -- unsigned int cbase; - uint8_t byte; - struct data data; - -@@ -96,30 +93,31 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - -- --/* Line 2053 of yacc.c */ --#line 103 "dtc-parser.tab.h" --} YYSTYPE; -+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --extern YYSTYPE yylval; -- --#ifdef YYPARSE_PARAM --#if defined __STDC__ || defined __cplusplus --int yyparse (void *YYPARSE_PARAM); --#else --int yyparse (); -+/* Location type. */ -+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE -+{ -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+}; -+# define YYLTYPE_IS_DECLARED 1 -+# define YYLTYPE_IS_TRIVIAL 1 - #endif --#else /* ! YYPARSE_PARAM */ --#if defined __STDC__ || defined __cplusplus -+ -+ -+extern YYSTYPE yylval; -+extern YYLTYPE yylloc; - int yyparse (void); --#else --int yyparse (); --#endif --#endif /* ! YYPARSE_PARAM */ - - #endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index f412460..687ccad 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -17,31 +17,28 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -- - %{ - #include -+#include - - #include "dtc.h" - #include "srcpos.h" - --YYLTYPE yylloc; -- - extern int yylex(void); --extern void print_error(char const *fmt, ...); - extern void yyerror(char const *s); -+#define ERROR(loc, ...) \ -+ do { \ -+ srcpos_error((loc), "Error", __VA_ARGS__); \ -+ treesource_error = true; \ -+ } while (0) - - extern struct boot_info *the_boot_info; --extern int treesource_error; -- --static unsigned long long eval_literal(const char *s, int base, int bits); --static unsigned char eval_char_literal(const char *s); -+extern bool treesource_error; - %} - - %union { - char *propnodename; -- char *literal; - char *labelref; -- unsigned int cbase; - uint8_t byte; - struct data data; - -@@ -56,18 +53,19 @@ static unsigned char eval_char_literal(const char *s); - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS - %token DT_DEL_PROP - %token DT_DEL_NODE - %token DT_PROPNODENAME --%token DT_LITERAL --%token DT_CHAR_LITERAL --%token DT_BASE -+%token DT_LITERAL -+%token DT_CHAR_LITERAL - %token DT_BYTE - %token DT_STRING - %token DT_LABEL -@@ -76,6 +74,7 @@ static unsigned char eval_char_literal(const char *s); - - %type propdata - %type propdataprefix -+%type plugindecl - %type memreserve - %type memreserves - %type arrayprefix -@@ -106,10 +105,23 @@ static unsigned char eval_char_literal(const char *s); - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ DT_V1 ';' plugindecl memreserves devicetree -+ { -+ $5->is_plugin = $3; -+ $5->is_root = 1; -+ the_boot_info = build_boot_info($4, $5, -+ guess_boot_cpuid($5)); -+ } -+ ; -+ -+plugindecl: -+ /* empty */ -+ { -+ $$ = 0; -+ } -+ | DT_PLUGIN ';' - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ $$ = 1; - } - ; - -@@ -152,17 +164,18 @@ devicetree: - if (target) - merge_nodes(target, $3); - else -- print_error("label or path, '%s', not found", $2); -+ ERROR(&@2, "Label or path %s not found", $2); - $$ = $1; - } - | devicetree DT_DEL_NODE DT_REF ';' - { - struct node *target = get_node_by_ref($1, $3); - -- if (!target) -- print_error("label or path, '%s', not found", $3); -- else -+ if (target) - delete_node(target); -+ else -+ ERROR(&@3, "Label or path %s not found", $3); -+ - - $$ = $1; - } -@@ -230,10 +243,9 @@ propdata: - - if ($6 != 0) - if (fseek(f, $6, SEEK_SET) != 0) -- print_error("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)$6, -- $4.val, -- strerror(errno)); -+ die("Couldn't seek to offset %llu in \"%s\": %s", -+ (unsigned long long)$6, $4.val, -+ strerror(errno)); - - d = data_copy_file(f, $8); - -@@ -274,18 +286,19 @@ propdataprefix: - arrayprefix: - DT_BITS DT_LITERAL '<' - { -- $$.data = empty_data; -- $$.bits = eval_literal($2, 0, 7); -- -- if (($$.bits != 8) && -- ($$.bits != 16) && -- ($$.bits != 32) && -- ($$.bits != 64)) -- { -- print_error("Only 8, 16, 32 and 64-bit elements" -- " are currently supported"); -- $$.bits = 32; -+ unsigned long long bits; -+ -+ bits = $2; -+ -+ if ((bits != 8) && (bits != 16) && -+ (bits != 32) && (bits != 64)) { -+ ERROR(&@2, "Array elements must be" -+ " 8, 16, 32 or 64-bits"); -+ bits = 32; - } -+ -+ $$.data = empty_data; -+ $$.bits = bits; - } - | '<' - { -@@ -305,9 +318,8 @@ arrayprefix: - * mask), all bits are one. - */ - if (($2 > mask) && (($2 | mask) != -1ULL)) -- print_error( -- "integer value out of range " -- "%016lx (%d bits)", $1.bits); -+ ERROR(&@2, "Value out of range for" -+ " %d-bit array element", $1.bits); - } - - $$.data = data_append_integer($1.data, $2, $1.bits); -@@ -321,7 +333,7 @@ arrayprefix: - REF_PHANDLE, - $2); - else -- print_error("References are only allowed in " -+ ERROR(&@2, "References are only allowed in " - "arrays with 32-bit elements."); - - $$.data = data_append_integer($1.data, val, $1.bits); -@@ -334,13 +346,7 @@ arrayprefix: - - integer_prim: - DT_LITERAL -- { -- $$ = eval_literal($1, 0, 64); -- } - | DT_CHAR_LITERAL -- { -- $$ = eval_char_literal($1); -- } - | '(' integer_expr ')' - { - $$ = $2; -@@ -447,7 +453,7 @@ subnodes: - } - | subnode propdef - { -- print_error("syntax error: properties must precede subnodes"); -+ ERROR(&@2, "Properties must precede subnodes"); - YYERROR; - } - ; -@@ -470,63 +476,7 @@ subnode: - - %% - --void print_error(char const *fmt, ...) --{ -- va_list va; -- -- va_start(va, fmt); -- srcpos_verror(&yylloc, fmt, va); -- va_end(va); -- -- treesource_error = 1; --} -- --void yyerror(char const *s) { -- print_error("%s", s); --} -- --static unsigned long long eval_literal(const char *s, int base, int bits) --{ -- unsigned long long val; -- char *e; -- -- errno = 0; -- val = strtoull(s, &e, base); -- if (*e) { -- size_t uls = strspn(e, "UL"); -- if (e[uls]) -- print_error("bad characters in literal"); -- } -- if ((errno == ERANGE) -- || ((bits < 64) && (val >= (1ULL << bits)))) -- print_error("literal out of range"); -- else if (errno != 0) -- print_error("bad literal"); -- return val; --} -- --static unsigned char eval_char_literal(const char *s) -+void yyerror(char const *s) - { -- int i = 1; -- char c = s[0]; -- -- if (c == '\0') -- { -- print_error("empty character literal"); -- return 0; -- } -- -- /* -- * If the first character in the character literal is a \ then process -- * the remaining characters as an escape encoding. If the first -- * character is neither an escape or a terminator it should be the only -- * character in the literal and will be returned. -- */ -- if (c == '\\') -- c = get_escape_char(s, &i); -- -- if (s[i] != '\0') -- print_error("malformed character literal"); -- -- return c; -+ ERROR(&yylloc, "%s", s); - } -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index e3c9653..0cbb14c 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -48,8 +49,10 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - } - - /* Usage related data. */ -+#define FDT_VERSION(version) _FDT_VERSION(version) -+#define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -67,6 +70,7 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", a_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -82,9 +86,9 @@ static const char * const usage_opts_help[] = { - "\t\tdts - device tree source text\n" - "\t\tdtb - device tree blob\n" - "\t\tasm - assembler source", -- "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); -+ "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", - "\n\tOutput dependency file", -- "\n\ttMake space for reserve map entries (for dtb and asm output)", -+ "\n\tMake space for reserve map entries (for dtb and asm output)", - "\n\tMake the blob at least long (extra space)", - "\n\tAdd padding to the blob of long (extra space)", - "\n\tSet the physical boot cpu", -@@ -97,6 +101,7 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tSymbols and Fixups support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -109,7 +114,7 @@ int main(int argc, char *argv[]) - const char *outform = "dts"; - const char *outname = "-"; - const char *depname = NULL; -- int force = 0, sort = 0; -+ bool force = false, sort = false; - const char *arg; - int opt; - FILE *outf = NULL; -@@ -148,7 +153,7 @@ int main(int argc, char *argv[]) - padsize = strtol(optarg, NULL, 0); - break; - case 'f': -- force = 1; -+ force = true; - break; - case 'q': - quiet++; -@@ -174,7 +179,7 @@ int main(int argc, char *argv[]) - break; - - case 's': -- sort = 1; -+ sort = true; - break; - - case 'W': -@@ -184,7 +189,9 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- -+ case '@': -+ symbol_fixup_support = 1; -+ break; - case 'h': - usage(NULL); - default: -@@ -237,7 +244,7 @@ int main(int argc, char *argv[]) - if (streq(outname, "-")) { - outf = stdout; - } else { -- outf = fopen(outname, "w"); -+ outf = fopen(outname, "wb"); - if (! outf) - die("Couldn't open output file %s: %s\n", - outname, strerror(errno)); -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 264a20c..fe45748 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -38,9 +38,9 @@ - #include "util.h" - - #ifdef DEBUG --#define debug(fmt,args...) printf(fmt, ##args) -+#define debug(...) printf(__VA_ARGS__) - #else --#define debug(fmt,args...) -+#define debug(...) - #endif - - -@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -88,7 +89,7 @@ struct data { - }; - - --#define empty_data ((struct data){ /* all .members = 0 or NULL */ }) -+#define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ }) - - #define for_each_marker(m) \ - for (; (m); (m) = (m)->next) -@@ -118,7 +119,7 @@ struct data data_append_align(struct data d, int align); - - struct data data_add_marker(struct data d, enum markertype type, char *ref); - --int data_is_one_string(struct data d); -+bool data_is_one_string(struct data d); - - /* DT constraints */ - -@@ -127,13 +128,32 @@ int data_is_one_string(struct data d); - - /* Live trees */ - struct label { -- int deleted; -+ bool deleted; - char *label; - struct label *next; - }; - -+struct fixup_entry { -+ int offset; -+ struct node *node; -+ struct property *prop; -+ struct fixup_entry *next; -+}; -+ -+struct fixup { -+ char *ref; -+ struct fixup_entry *entries; -+ struct fixup *next; -+}; -+ -+struct symbol { -+ struct label *label; -+ struct node *node; -+ struct symbol *next; -+}; -+ - struct property { -- int deleted; -+ bool deleted; - char *name; - struct data val; - -@@ -143,7 +163,7 @@ struct property { - }; - - struct node { -- int deleted; -+ bool deleted; - char *name; - struct property *proplist; - struct node *children; -@@ -158,6 +178,12 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -+ -+ int is_root; -+ int is_plugin; -+ struct fixup *fixups; -+ struct symbol *symbols; -+ struct fixup_entry *local_fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -181,6 +207,18 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - -+#define for_each_fixup(n, f) \ -+ for ((f) = (n)->fixups; (f); (f) = (f)->next) -+ -+#define for_each_fixup_entry(f, fe) \ -+ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -+ -+#define for_each_symbol(n, s) \ -+ for ((s) = (n)->symbols; (s); (s) = (s)->next) -+ -+#define for_each_local_fixup_entry(n, fe) \ -+ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -+ - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -@@ -247,8 +285,8 @@ void sort_tree(struct boot_info *bi); - - /* Checks */ - --void parse_checks_option(bool warn, bool error, const char *optarg); --void process_checks(int force, struct boot_info *bi); -+void parse_checks_option(bool warn, bool error, const char *arg); -+void process_checks(bool force, struct boot_info *bi); - - /* Flattened trees */ - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index 665dad7..f439b40 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -261,7 +261,13 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - { - struct property *prop; - struct node *child; -- int seen_name_prop = 0; -+ bool seen_name_prop = false; -+ struct symbol *sym; -+ struct fixup *f; -+ struct fixup_entry *fe; -+ char *name, *s; -+ const char *fullpath; -+ int namesz, nameoff, vallen; - - if (tree->deleted) - return; -@@ -276,10 +282,8 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - emit->align(etarget, sizeof(cell_t)); - - for_each_property(tree, prop) { -- int nameoff; -- - if (streq(prop->name, "name")) -- seen_name_prop = 1; -+ seen_name_prop = true; - - nameoff = stringtable_insert(strbuf, prop->name); - -@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -+ if (!symbol_fixup_support) -+ goto no_symbols; -+ -+ /* add the symbol nodes (if any) */ -+ if (tree->symbols) { -+ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__symbols__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_symbol(tree, sym) { -+ -+ vallen = strlen(sym->node->fullpath); -+ -+ nameoff = stringtable_insert(strbuf, sym->label->label); -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, sym->node->fullpath, -+ strlen(sym->node->fullpath)); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ emit->endnode(etarget, NULL); -+ } -+ -+ /* add the fixup nodes */ -+ if (tree->fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_fixup(tree, f) { -+ -+ namesz = 0; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, -+ fe->prop->name, fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, f->ref); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ } -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+ /* add the local fixup property */ -+ if (tree->local_fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__local_fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ namesz = 0; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, fe->prop->name, -+ fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, "fixup"); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+no_symbols: - emit->endnode(etarget, tree->labels); - } - -diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c -index e464727c..6e5878a 100644 ---- a/scripts/dtc/fstree.c -+++ b/scripts/dtc/fstree.c -@@ -37,26 +37,26 @@ static struct node *read_fstree(const char *dirname) - tree = build_node(NULL, NULL); - - while ((de = readdir(d)) != NULL) { -- char *tmpnam; -+ char *tmpname; - - if (streq(de->d_name, ".") - || streq(de->d_name, "..")) - continue; - -- tmpnam = join_path(dirname, de->d_name); -+ tmpname = join_path(dirname, de->d_name); - -- if (lstat(tmpnam, &st) < 0) -- die("stat(%s): %s\n", tmpnam, strerror(errno)); -+ if (lstat(tmpname, &st) < 0) -+ die("stat(%s): %s\n", tmpname, strerror(errno)); - - if (S_ISREG(st.st_mode)) { - struct property *prop; - FILE *pfile; - -- pfile = fopen(tmpnam, "r"); -+ pfile = fopen(tmpname, "rb"); - if (! pfile) { - fprintf(stderr, - "WARNING: Cannot open %s: %s\n", -- tmpnam, strerror(errno)); -+ tmpname, strerror(errno)); - } else { - prop = build_property(xstrdup(de->d_name), - data_copy_file(pfile, -@@ -67,12 +67,12 @@ static struct node *read_fstree(const char *dirname) - } else if (S_ISDIR(st.st_mode)) { - struct node *newchild; - -- newchild = read_fstree(tmpnam); -+ newchild = read_fstree(tmpname); - newchild = name_node(newchild, xstrdup(de->d_name)); - add_child(tree, newchild); - } - -- free(tmpnam); -+ free(tmpname); - } - - closedir(d); -diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c -index b61465f..e229b84 100644 ---- a/scripts/dtc/livetree.c -+++ b/scripts/dtc/livetree.c -@@ -511,7 +511,9 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) - - struct node *get_node_by_ref(struct node *tree, const char *ref) - { -- if (ref[0] == '/') -+ if (streq(ref, "/")) -+ return tree; -+ else if (ref[0] == '/') - return get_node_by_path(tree, ref); - else - return get_node_by_label(tree, ref); -diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c -index c20bc531..f534c22 100644 ---- a/scripts/dtc/srcpos.c -+++ b/scripts/dtc/srcpos.c -@@ -34,7 +34,7 @@ struct search_path { - static struct search_path *search_path_head, **search_path_tail; - - --static char *dirname(const char *path) -+static char *get_dirname(const char *path) - { - const char *slash = strrchr(path, '/'); - -@@ -77,7 +77,7 @@ static char *try_open(const char *dirname, const char *fname, FILE **fp) - else - fullname = join_path(dirname, fname); - -- *fp = fopen(fullname, "r"); -+ *fp = fopen(fullname, "rb"); - if (!*fp) { - free(fullname); - fullname = NULL; -@@ -150,7 +150,7 @@ void srcfile_push(const char *fname) - srcfile = xmalloc(sizeof(*srcfile)); - - srcfile->f = srcfile_relative_open(fname, &srcfile->name); -- srcfile->dir = dirname(srcfile->name); -+ srcfile->dir = get_dirname(srcfile->name); - srcfile->prev = current_srcfile; - - srcfile->lineno = 1; -@@ -159,7 +159,7 @@ void srcfile_push(const char *fname) - current_srcfile = srcfile; - } - --int srcfile_pop(void) -+bool srcfile_pop(void) - { - struct srcfile_state *srcfile = current_srcfile; - -@@ -177,7 +177,7 @@ int srcfile_pop(void) - * fix this we could either allocate all the files from a - * table, or use a pool allocator. */ - -- return current_srcfile ? 1 : 0; -+ return current_srcfile ? true : false; - } - - void srcfile_add_search_path(const char *dirname) -@@ -290,42 +290,27 @@ srcpos_string(struct srcpos *pos) - return pos_str; - } - --void --srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) -+void srcpos_verror(struct srcpos *pos, const char *prefix, -+ const char *fmt, va_list va) - { -- const char *srcstr; -- -- srcstr = srcpos_string(pos); -+ char *srcstr; - -- fprintf(stderr, "Error: %s ", srcstr); -- vfprintf(stderr, fmt, va); -- fprintf(stderr, "\n"); --} -+ srcstr = srcpos_string(pos); - --void --srcpos_error(struct srcpos *pos, char const *fmt, ...) --{ -- va_list va; -+ fprintf(stderr, "%s: %s ", prefix, srcstr); -+ vfprintf(stderr, fmt, va); -+ fprintf(stderr, "\n"); - -- va_start(va, fmt); -- srcpos_verror(pos, fmt, va); -- va_end(va); -+ free(srcstr); - } - -- --void --srcpos_warn(struct srcpos *pos, char const *fmt, ...) -+void srcpos_error(struct srcpos *pos, const char *prefix, -+ const char *fmt, ...) - { -- const char *srcstr; - va_list va; -- va_start(va, fmt); -- -- srcstr = srcpos_string(pos); -- -- fprintf(stderr, "Warning: %s ", srcstr); -- vfprintf(stderr, fmt, va); -- fprintf(stderr, "\n"); - -+ va_start(va, fmt); -+ srcpos_verror(pos, prefix, fmt, va); - va_end(va); - } - -diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h -index 93a2712..f81827b 100644 ---- a/scripts/dtc/srcpos.h -+++ b/scripts/dtc/srcpos.h -@@ -21,6 +21,7 @@ - #define _SRCPOS_H_ - - #include -+#include - - struct srcfile_state { - FILE *f; -@@ -55,7 +56,7 @@ extern struct srcfile_state *current_srcfile; /* = NULL */ - FILE *srcfile_relative_open(const char *fname, char **fullnamep); - - void srcfile_push(const char *fname); --int srcfile_pop(void); -+bool srcfile_pop(void); - - /** - * Add a new directory to the search path for input files -@@ -106,12 +107,12 @@ extern struct srcpos *srcpos_copy(struct srcpos *pos); - extern char *srcpos_string(struct srcpos *pos); - extern void srcpos_dump(struct srcpos *pos); - --extern void srcpos_verror(struct srcpos *pos, char const *, va_list va) -- __attribute__((format(printf, 2, 0))); --extern void srcpos_error(struct srcpos *pos, char const *, ...) -- __attribute__((format(printf, 2, 3))); --extern void srcpos_warn(struct srcpos *pos, char const *, ...) -- __attribute__((format(printf, 2, 3))); -+extern void srcpos_verror(struct srcpos *pos, const char *prefix, -+ const char *fmt, va_list va) -+ __attribute__((format(printf, 3, 0))); -+extern void srcpos_error(struct srcpos *pos, const char *prefix, -+ const char *fmt, ...) -+ __attribute__((format(printf, 3, 4))); - - extern void srcpos_set_line(char *f, int l); - -diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c -index 5740e69..a146f2d 100644 ---- a/scripts/dtc/treesource.c -+++ b/scripts/dtc/treesource.c -@@ -26,12 +26,12 @@ extern int yyparse(void); - extern YYLTYPE yylloc; - - struct boot_info *the_boot_info; --int treesource_error; -+bool treesource_error; - - struct boot_info *dt_from_source(const char *fname) - { - the_boot_info = NULL; -- treesource_error = 0; -+ treesource_error = false; - - srcfile_push(fname); - yyin = current_srcfile->f; -@@ -54,9 +54,9 @@ static void write_prefix(FILE *f, int level) - fputc('\t', f); - } - --static int isstring(char c) -+static bool isstring(char c) - { -- return (isprint(c) -+ return (isprint((unsigned char)c) - || (c == '\0') - || strchr("\a\b\t\n\v\f\r", c)); - } -@@ -109,7 +109,7 @@ static void write_propval_string(FILE *f, struct data val) - break; - case '\0': - fprintf(f, "\", "); -- while (m && (m->offset < i)) { -+ while (m && (m->offset <= (i + 1))) { - if (m->type == LABEL) { - assert(m->offset == (i+1)); - fprintf(f, "%s: ", m->ref); -@@ -119,7 +119,7 @@ static void write_propval_string(FILE *f, struct data val) - fprintf(f, "\""); - break; - default: -- if (isprint(c)) -+ if (isprint((unsigned char)c)) - fprintf(f, "%c", c); - else - fprintf(f, "\\x%02hhx", c); -@@ -178,7 +178,7 @@ static void write_propval_bytes(FILE *f, struct data val) - m = m->next; - } - -- fprintf(f, "%02hhx", *bp++); -+ fprintf(f, "%02hhx", (unsigned char)(*bp++)); - if ((const void *)bp >= propend) - break; - fprintf(f, " "); -diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c -index 3055c16..9d65226 100644 ---- a/scripts/dtc/util.c -+++ b/scripts/dtc/util.c -@@ -39,11 +39,11 @@ - char *xstrdup(const char *s) - { - int len = strlen(s) + 1; -- char *dup = xmalloc(len); -+ char *d = xmalloc(len); - -- memcpy(dup, s, len); -+ memcpy(d, s, len); - -- return dup; -+ return d; - } - - char *join_path(const char *path, const char *name) -@@ -70,7 +70,7 @@ char *join_path(const char *path, const char *name) - return str; - } - --int util_is_printable_string(const void *data, int len) -+bool util_is_printable_string(const void *data, int len) - { - const char *s = data; - const char *ss, *se; -@@ -87,7 +87,7 @@ int util_is_printable_string(const void *data, int len) - - while (s < se) { - ss = s; -- while (s < se && *s && isprint(*s)) -+ while (s < se && *s && isprint((unsigned char)*s)) - s++; - - /* not zero, or not done yet */ -@@ -219,10 +219,6 @@ int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len) - if (offset == bufsize) { - bufsize *= 2; - buf = xrealloc(buf, bufsize); -- if (!buf) { -- ret = ENOMEM; -- break; -- } - } - - ret = read(fd, &buf[offset], bufsize - offset); -@@ -375,9 +371,9 @@ void utilfdt_print_data(const char *data, int len) - const uint32_t *cell = (const uint32_t *)data; - - printf(" = <"); -- for (i = 0; i < len; i += 4) -+ for (i = 0, len /= 4; i < len; i++) - printf("0x%08x%s", fdt32_to_cpu(cell[i]), -- i < (len - 4) ? " " : ""); -+ i < (len - 1) ? " " : ""); - printf(">"); - } else { - printf(" = ["); -diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h -index 8f40b44..f800b60 100644 ---- a/scripts/dtc/util.h -+++ b/scripts/dtc/util.h -@@ -2,6 +2,7 @@ - #define _UTIL_H - - #include -+#include - #include - - /* -@@ -33,6 +34,7 @@ static inline void __attribute__((noreturn)) die(const char *str, ...) - va_start(ap, str); - fprintf(stderr, "FATAL ERROR: "); - vfprintf(stderr, str, ap); -+ va_end(ap); - exit(1); - } - -@@ -68,7 +70,7 @@ extern char *join_path(const char *path, const char *name); - * @param len The string length including terminator - * @return 1 if a valid printable string, 0 if not - */ --int util_is_printable_string(const void *data, int len); -+bool util_is_printable_string(const void *data, int len); - - /* - * Parse an escaped character starting at index i in string s. The resulting -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 54d4e904..d644002 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.0-dirty" -+#define DTC_VERSION "DTC 1.4.1-g36c70742" - -From 8bddbe464074570457bca032ebee779eb9814d13 Mon Sep 17 00:00:00 2001 +From fe1969c34a172ced7b6091b8d1870e0e69848a24 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 023/204] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 039/113] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to @@ -118008,20 +117166,20 @@ index 0000000..3dff948 + return (($val eq 'y') || ($val eq '1')); +} -From febe480850daa451009a87a3b86278f3d7dbaa10 Mon Sep 17 00:00:00 2001 +From 227f14d8caaaab948771eaafbce7b7f1427f0fe1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 024/204] fdt: Add support for the CONFIG_CMDLINE_EXTEND option +Subject: [PATCH 040/113] fdt: Add support for the CONFIG_CMDLINE_EXTEND option --- drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index d91f721..02feb00 100644 +index 6e82bc42..9d65291 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c -@@ -933,19 +933,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, +@@ -945,19 +945,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, /* Retrieve command line */ p = of_get_flat_dt_prop(node, "bootargs", &l); @@ -118066,10 +117224,10 @@ index d91f721..02feb00 100644 pr_debug("Command line is: %s\n", (char*)data); -From 35658cc32f834e0bad12e6206b7ffb6af9eddbe6 Mon Sep 17 00:00:00 2001 +From 72bc21bd8680d70ebb7bd48303e035bf2b2a63d0 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 025/204] BCM2708: Add core Device Tree support +Subject: [PATCH 041/113] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. @@ -118084,53 +117242,71 @@ but since this is part of an upstreaming effort, the name is changed. Signed-off-by: Noralf Tronnes notro@tronnes.org BCM2708_DT: Correct length of the peripheral space + +Use dts-dirs feature for overlays. + +The kernel makefiles have a dts-dirs target that is for vendor subdirectories. + +Using this fixes the install_dtbs target, which previously did not install the overlays. --- - arch/arm/boot/dts/Makefile | 27 ++ - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 140 ++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 130 ++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 18 + - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 51 +++ - arch/arm/boot/dts/bcm2708.dtsi | 19 + - arch/arm/boot/dts/bcm2708_common.dtsi | 230 ++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 140 ++++++ - arch/arm/boot/dts/bcm2709.dtsi | 70 +++ - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 45 +- - arch/arm/boot/dts/bcm2835-rpi-b.dts | 29 +- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 97 +++- - arch/arm/boot/dts/bcm2835.dtsi | 45 +- - arch/arm/boot/dts/overlays/Makefile | 57 +++ - arch/arm/boot/dts/overlays/README | 493 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 ++++ + arch/arm/boot/dts/Makefile | 30 + + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 134 +++++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 124 ++++ + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 98 +++ + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 30 + + arch/arm/boot/dts/bcm2708.dtsi | 36 ++ + arch/arm/boot/dts/bcm2708_common.dtsi | 321 ++++++++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 134 +++++ + arch/arm/boot/dts/bcm2709.dtsi | 76 +++ + arch/arm/boot/dts/bcm2835-rpi-cm.dts | 93 +++ + arch/arm/boot/dts/bcm2835-rpi-cm.dtsi | 30 + + arch/arm/boot/dts/overlays/Makefile | 71 +++ + arch/arm/boot/dts/overlays/README | 658 +++++++++++++++++++++ + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 +++ .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 +++ + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 ++ + .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 ++ .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 ++++ - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 ++++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 49 ++ + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 +++ + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 +++++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 55 ++ arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 +++ + arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 ++ .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 +++ + .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 69 +++ arch/arm/boot/dts/overlays/mmc-overlay.dts | 19 + - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 109 +++++ - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 ++++ - .../dts/overlays/pitft28-resistive-overlay.dts | 115 +++++ + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 111 ++++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 +++ + .../dts/overlays/pitft28-resistive-overlay.dts | 115 ++++ arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ + arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 46 ++ + arch/arm/boot/dts/overlays/pwm-overlay.dts | 42 ++ + arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++ arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 ++++ + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 +++ + arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 17 + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 78 ++++ - arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 18 + + arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 ++ + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 56 ++ + arch/arm/boot/dts/overlays/sdio-overlay.dts | 29 + + arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + + arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 +++ + arch/arm/boot/dts/overlays/smi-overlay.dts | 37 ++ + arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 25 + arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts | 18 + - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++++ + .../boot/dts/overlays/spi-gpio35-39-overlay.dts | 31 + + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++ + arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 ++ + arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ - 45 files changed, 3316 insertions(+), 54 deletions(-) + 57 files changed, 4159 insertions(+) create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -118139,12 +117315,15 @@ BCM2708_DT: Correct length of the peripheral space create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts create mode 100644 arch/arm/boot/dts/bcm2709.dtsi + create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dts + create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dtsi create mode 100644 arch/arm/boot/dts/overlays/Makefile create mode 100644 arch/arm/boot/dts/overlays/README create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts @@ -118157,31 +117336,45 @@ BCM2708_DT: Correct length of the peripheral space create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 992736b..12de305 100644 +index bb8fa02..68b2c74 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,21 @@ +@@ -1,5 +1,25 @@ ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-cm.dtb +dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb + +# Raspberry Pi @@ -118194,14 +117387,17 @@ index 992736b..12de305 100644 +ifeq ($(CONFIG_ARCH_BCM2835),y) + RPI_DT_OVERLAYS=y +endif ++ifeq ($(RPI_DT_OVERLAYS),y) ++ dts-dirs += overlays ++endif + dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb dtb-$(CONFIG_MACH_ASM9260) += \ -@@ -660,7 +676,18 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt6592-evb.dtb \ +@@ -738,7 +758,17 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8127-moose.dtb \ mt8135-evbp1.dtb + dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb + +targets += dtbs dtbs_install +targets += $(dtb-y) @@ -118209,20 +117405,19 @@ index 992736b..12de305 100644 endif always := $(dtb-y) ++subdir-y := $(dts-dirs) clean-files := *.dtb + +# Enable fixups to support overlays on BCM2708 platforms +ifeq ($(RPI_DT_OVERLAYS),y) + DTC_FLAGS ?= -@ +endif -+ -+subdir-y += overlays diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts new file mode 100644 -index 0000000..0fa2210 +index 0000000..ffb7596 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -0,0 +1,140 @@ +@@ -0,0 +1,134 @@ +/dts-v1/; + +/include/ "bcm2708.dtsi" @@ -118230,33 +117425,19 @@ index 0000000..0fa2210 +/ { + compatible = "brcm,bcm2708"; + model = "Raspberry Pi Model B+"; -+ -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; +}; + +&gpio { + spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; ++ brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; @@ -118288,7 +117469,8 @@ index 0000000..0fa2210 + +&spi0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev@0{ + compatible = "spidev"; @@ -118319,6 +117501,10 @@ index 0000000..0fa2210 + clock-frequency = <100000>; +}; + ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; @@ -118347,8 +117533,11 @@ index 0000000..0fa2210 + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -118365,10 +117554,10 @@ index 0000000..0fa2210 +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts new file mode 100644 -index 0000000..3fd49d0 +index 0000000..8551159 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -0,0 +1,130 @@ +@@ -0,0 +1,124 @@ +/dts-v1/; + +/include/ "bcm2708.dtsi" @@ -118376,33 +117565,19 @@ index 0000000..3fd49d0 +/ { + compatible = "brcm,bcm2708"; + model = "Raspberry Pi Model B"; -+ -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; +}; + +&gpio { + spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; ++ brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; @@ -118415,7 +117590,7 @@ index 0000000..3fd49d0 + + i2s_pins: i2s { + brcm,pins = <28 29 30 31>; -+ brcm,function = <4>; /* alt0 */ ++ brcm,function = <6>; /* alt2 */ + }; +}; + @@ -118434,7 +117609,8 @@ index 0000000..3fd49d0 + +&spi0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev@0{ + compatible = "spidev"; @@ -118465,6 +117641,10 @@ index 0000000..3fd49d0 + clock-frequency = <100000>; +}; + ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; @@ -118487,8 +117667,11 @@ index 0000000..3fd49d0 + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -118501,10 +117684,10 @@ index 0000000..3fd49d0 +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts new file mode 100755 -index 0000000..238bd65 +index 0000000..1f7ec88 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -0,0 +1,18 @@ +@@ -0,0 +1,98 @@ +/dts-v1/; + +/include/ "bcm2708-rpi-cm.dtsi" @@ -118517,41 +117700,100 @@ index 0000000..238bd65 + status = "okay"; +}; + ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ +/ { + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi new file mode 100644 -index 0000000..3da7d3b +index 0000000..713e5a2 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -0,0 +1,51 @@ +@@ -0,0 +1,30 @@ +/include/ "bcm2708.dtsi" + -+/ { -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ +&leds { + act_led: act { + label = "led0"; @@ -118569,23 +117811,23 @@ index 0000000..3da7d3b + status = "okay"; +}; + -+&audio { -+ status = "okay"; -+}; -+ +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi new file mode 100644 -index 0000000..0d47427 +index 0000000..0bea715 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -0,0 +1,19 @@ +@@ -0,0 +1,36 @@ +/include/ "bcm2708_common.dtsi" + +/ { @@ -118600,22 +117842,65 @@ index 0000000..0d47427 + soc { + ranges = <0x7e000000 0x20000000 0x01000000>; + ++ timer@7e003000 { ++ compatible = "brcm,bcm2835-system-timer"; ++ reg = <0x7e003000 0x1000>; ++ interrupts = <1 0>, <1 1>, <1 2>, <1 3>; ++ clock-frequency = <1000000>; ++ }; ++ + arm-pmu { + compatible = "arm,arm1176-pmu"; + }; ++ ++ gpiomem { ++ compatible = "brcm,bcm2835-gpiomem"; ++ reg = <0x7e200000 0x1000>; ++ status = "okay"; ++ }; + }; +}; ++ ++&intc { ++ compatible = "brcm,bcm2835-armctrl-ic"; ++}; diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi new file mode 100644 -index 0000000..8caa234 +index 0000000..5d9081a --- /dev/null +++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -0,0 +1,230 @@ +@@ -0,0 +1,321 @@ +/include/ "skeleton.dtsi" + +/ { + interrupt-parent = <&intc>; + ++ aliases { ++ audio = &audio; ++ sound = &sound; ++ soc = &soc; ++ dma = &dma; ++ intc = &intc; ++ watchdog = &watchdog; ++ random = &random; ++ mailbox = &mailbox; ++ gpio = &gpio; ++ uart0 = &uart0; ++ i2s = &i2s; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ uart1 = &uart1; ++ mmc = &mmc; ++ i2c1 = &i2c1; ++ i2c2 = &i2c2; ++ usb = &usb; ++ leds = &leds; ++ fb = &fb; ++ vchiq = &vchiq; ++ thermal = &thermal; ++ clocks = &clocks; ++ }; ++ + /* Onboard audio */ + audio: audio { + compatible = "brcm,bcm2835-audio"; @@ -118623,6 +117908,10 @@ index 0000000..8caa234 + status = "disabled"; + }; + ++ /* External sound card */ ++ sound: sound { ++ }; ++ + soc: soc { + compatible = "simple-bus"; + #address-cells = <1>; @@ -118642,20 +117931,26 @@ index 0000000..8caa234 + <1 24>, + <1 25>, + <1 26>, -+ <1 27>, -+ <1 28>; ++ <1 27>; + + #dma-cells = <1>; -+ brcm,dma-channel-mask = <0x7f35>; ++ brcm,dma-channel-mask = <0x0f35>; + }; + -+ intc: interrupt-controller { ++ intc: interrupt-controller@7e00b200 { + compatible = "brcm,bcm2708-armctrl-ic"; + reg = <0x7e00b200 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2835-mbox"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ #mbox-cells = <0>; ++ }; ++ + watchdog: watchdog@7e100000 { + compatible = "brcm,bcm2835-pm-wdt"; + reg = <0x7e100000 0x28>; @@ -118668,13 +117963,7 @@ index 0000000..8caa234 + status = "disabled"; + }; + -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ -+ gpio: gpio { ++ gpio: gpio@7e200000 { + compatible = "brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; + interrupts = <2 17>, <2 18>; @@ -118686,17 +117975,6 @@ index 0000000..8caa234 + #interrupt-cells = <2>; + }; + -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ + uart0: uart@7e201000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201000 0x1000>; @@ -118710,8 +117988,8 @@ index 0000000..8caa234 + + i2s: i2s@7e203000 { + compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; ++ reg = <0x7e203000 0x24>, ++ <0x7e101098 0x08>; + + //dmas = <&dma 2>, + // <&dma 3>; @@ -118723,7 +118001,7 @@ index 0000000..8caa234 + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x1000>; + interrupts = <2 22>; -+ clocks = <&clk_spi>; ++ clocks = <&clk_core>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; @@ -118747,16 +118025,35 @@ index 0000000..8caa234 + status = "disabled"; + }; + ++ pwm: pwm@7e20c000 { ++ compatible = "brcm,bcm2835-pwm"; ++ reg = <0x7e20c000 0x28>; ++ clocks = <&clk_pwm>; ++ #pwm-cells = <2>; ++ status = "disabled"; ++ }; ++ + uart1: uart@7e215040 { + compatible = "brcm,bcm2835-aux-uart", "ns16550"; + reg = <0x7e215040 0x40>; + interrupts = <1 29>; -+ clock-frequency = <500000000>; ++ clocks = <&clk_uart1>; + reg-shift = <2>; + no-loopback-test; + status = "disabled"; + }; + ++ mmc: mmc@7e300000 { ++ compatible = "brcm,bcm2835-mmc"; ++ reg = <0x7e300000 0x100>; ++ interrupts = <2 30>; ++ clocks = <&clk_mmc>; ++ dmas = <&dma 11>, ++ <&dma 11>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ + i2c1: i2c@7e804000 { + compatible = "brcm,bcm2708-i2c"; + reg = <0x7e804000 0x1000>; @@ -118767,6 +118064,30 @@ index 0000000..8caa234 + status = "disabled"; + }; + ++ i2c2: i2c@7e805000 { ++ // Beware - this is shared with the HDMI module. ++ // Careless use may break (really) your display. ++ // Caveat emptor. ++ compatible = "brcm,bcm2708-i2c"; ++ reg = <0x7e805000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clk_i2c>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ smi: smi@7e600000 { ++ compatible = "brcm,bcm2835-smi"; ++ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; ++ interrupts = <2 16>; ++ brcm,smi-clock-source = <6>; ++ brcm,smi-clock-divisor = <4>; ++ dmas = <&dma 4>; ++ dma-names = "rx-tx"; ++ status = "disabled"; ++ }; ++ + usb: usb@7e980000 { + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000>, @@ -118775,12 +118096,18 @@ index 0000000..8caa234 + <1 9>; + }; + ++ firmware: firmware { ++ compatible = "raspberrypi,bcm2835-firmware"; ++ mboxes = <&mailbox>; ++ }; ++ + leds: leds { + compatible = "gpio-leds"; + }; + + fb: fb { + compatible = "brcm,bcm2708-fb"; ++ firmware = <&firmware>; + status = "disabled"; + }; + @@ -118788,10 +118115,13 @@ index 0000000..8caa234 + compatible = "brcm,bcm2835-vchiq"; + reg = <0x7e00b840 0xf>; + interrupts = <0 2>; ++ cache-line-size = <32>; ++ firmware = <&firmware>; + }; + + thermal: thermal { + compatible = "brcm,bcm2835-thermal"; ++ firmware = <&firmware>; + }; + }; + @@ -118816,11 +118146,11 @@ index 0000000..8caa234 + clock-frequency = <250000000>; + }; + -+ clk_spi: clock@2 { ++ clk_core: clock@2 { + compatible = "fixed-clock"; + reg = <2>; + #clock-cells = <0>; -+ clock-output-names = "spi"; ++ clock-output-names = "core"; + clock-frequency = <250000000>; + }; + @@ -118839,14 +118169,34 @@ index 0000000..8caa234 + clock-output-names = "apb_pclk"; + clock-frequency = <126000000>; + }; ++ ++ clk_pwm: clock@5 { ++ compatible = "fixed-clock"; ++ reg = <3>; ++ #clock-cells = <0>; ++ clock-output-names = "pwm"; ++ clock-frequency = <100000000>; ++ }; ++ ++ clk_uart1: clock@6 { ++ compatible = "fixed-factor-clock"; ++ clocks = <&clk_core>; ++ #clock-cells = <0>; ++ clock-div = <1>; ++ clock-mult = <2>; ++ }; ++ }; ++ ++ __overrides__ { ++ cache_line_size = <&vchiq>, "cache-line-size:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts new file mode 100644 -index 0000000..8aaaf1f +index 0000000..7a05dab5 --- /dev/null +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -0,0 +1,140 @@ +@@ -0,0 +1,134 @@ +/dts-v1/; + +/include/ "bcm2709.dtsi" @@ -118854,33 +118204,19 @@ index 0000000..8aaaf1f +/ { + compatible = "brcm,bcm2709"; + model = "Raspberry Pi 2 Model B"; -+ -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; +}; + +&gpio { + spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; ++ brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; @@ -118912,7 +118248,8 @@ index 0000000..8aaaf1f + +&spi0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev@0{ + compatible = "spidev"; @@ -118943,6 +118280,10 @@ index 0000000..8aaaf1f + clock-frequency = <100000>; +}; + ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; @@ -118971,8 +118312,11 @@ index 0000000..8aaaf1f + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -118989,10 +118333,10 @@ index 0000000..8aaaf1f +}; diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi new file mode 100644 -index 0000000..5e0b935 +index 0000000..811d825 --- /dev/null +++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -0,0 +1,70 @@ +@@ -0,0 +1,76 @@ +/include/ "bcm2708_common.dtsi" + +/ { @@ -119011,6 +118355,12 @@ index 0000000..5e0b935 + compatible = "arm,cortex-a7-pmu"; + interrupts = <3 9>; + }; ++ ++ gpiomem { ++ compatible = "brcm,bcm2835-gpiomem"; ++ reg = <0x7e200000 0x1000>; ++ status = "okay"; ++ }; + }; + + timer { @@ -119063,183 +118413,44 @@ index 0000000..5e0b935 + <&v7_cpu3>, "clock-frequency:0"; + }; +}; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index e479515..b0fb0e8 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -4,27 +4,40 @@ - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; - model = "Raspberry Pi Model B+"; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm.dts b/arch/arm/boot/dts/bcm2835-rpi-cm.dts +new file mode 100644 +index 0000000..c6e6860a +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2835-rpi-cm.dts +@@ -0,0 +1,93 @@ ++/dts-v1/; ++ ++#include "bcm2835-rpi-cm.dtsi" ++ ++/ { ++ model = "Raspberry Pi Compute Module"; ++}; ++ ++&uart0 { ++ status = "okay"; +}; + +&gpio { -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; - -- leds { -- act { -- gpios = <&gpio 47 0>; -- }; -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 47 0>; -+}; - -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; -+&leds { -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; - }; - }; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - -- /* I2S interface */ -- i2s_alt0: i2s_alt0 { -- brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index bafa46f..b867224 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -5,19 +5,28 @@ - compatible = "raspberrypi,model-b", "brcm,bcm2835"; - model = "Raspberry Pi Model B"; - -- leds { -- act { -- gpios = <&gpio 16 1>; -- }; -- }; - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; -- -- /* I2S interface */ -- i2s_alt2: i2s_alt2 { -+ i2s_pins: i2s { - brcm,pins = <28 29 30 31>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 16 1>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index c706448..466f02b 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -1,51 +1,112 @@ - /include/ "bcm2835.dtsi" - - / { -+ /* This is left here in case u-boot needs it */ - memory { - reg = <0 0x10000000>; - }; - -- leds { -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ sound = &sound; -+ }; -+ -+ leds: leds { - compatible = "gpio-leds"; - -- act { -- label = "ACT"; -- default-state = "keep"; -- linux,default-trigger = "heartbeat"; -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; - }; - }; -+ -+ /* Onboard audio */ -+ audio: audio { -+ compatible = "brcm,bcm2835-audio"; -+ brcm,pwm-channels = <8>; -+ status = "disabled"; -+ }; -+ -+ /* External sound card */ -+ sound: sound { -+ }; - }; - - &gpio { -- pinctrl-names = "default"; + spi0_pins: spi0_pins { + brcm,pins = <7 8 9 10 11>; + brcm,function = <4>; /* alt0 */ + }; - -- gpioout: gpioout { -- brcm,pins = <6>; -- brcm,function = <1>; /* GPIO out */ ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; - }; - -- alt0: alt0 { -- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; -- brcm,function = <4>; /* alt0 */ ++ }; ++ + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; +}; + +&spi0 { @@ -119252,39 +118463,75 @@ index c706448..466f02b 100644 + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <500000>; - }; - -- alt3: alt3 { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <7>; /* alt3 */ ++ }; ++ + spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <500000>; - }; - }; - - &i2c0 { -- status = "okay"; ++ }; ++}; ++ ++&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; - clock-frequency = <100000>; - }; - - &i2c1 { -- status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; - clock-frequency = <100000>; - }; - --&sdhci { ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1_clkrate = <&uart1>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm.dtsi +new file mode 100644 +index 0000000..9c4000f +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2835-rpi-cm.dtsi +@@ -0,0 +1,30 @@ ++#include "bcm2835.dtsi" ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++}; ++ +&mmc { - status = "okay"; - bus-width = <4>; - }; ++ status = "okay"; ++ bus-width = <4>; ++}; + +&fb { + status = "okay"; @@ -119292,144 +118539,21 @@ index c706448..466f02b 100644 + +/ { + __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; ++ + audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; +}; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 3342cb1..4b6dd65f 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -6,14 +6,15 @@ - interrupt-parent = <&intc>; - - chosen { -- bootargs = "earlyprintk console=ttyAMA0"; -+ bootargs = ""; - }; - -- soc { -+ soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x7e000000 0x20000000 0x02000000>; -+ dma-ranges = <0x40000000 0x00000000 0x20000000>; - - timer@7e003000 { - compatible = "brcm,bcm2835-system-timer"; -@@ -50,16 +51,22 @@ - #interrupt-cells = <2>; - }; - -- watchdog@7e100000 { -+ watchdog: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm-wdt"; - reg = <0x7e100000 0x28>; - }; - -- rng@7e104000 { -+ random: rng@7e104000 { - compatible = "brcm,bcm2835-rng"; - reg = <0x7e104000 0x10>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - gpio: gpio@7e200000 { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; -@@ -83,7 +90,7 @@ - #interrupt-cells = <2>; - }; - -- uart@7e201000 { -+ uart0: uart@7e201000 { - compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; - interrupts = <2 25>; -@@ -102,7 +109,7 @@ - status = "disabled"; - }; - -- spi: spi@7e204000 { -+ spi0: spi@7e204000 { - compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; -@@ -122,11 +129,14 @@ - status = "disabled"; - }; - -- sdhci: sdhci@7e300000 { -- compatible = "brcm,bcm2835-sdhci"; -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; - reg = <0x7e300000 0x100>; - interrupts = <2 30>; - clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; - status = "disabled"; - }; - -@@ -140,7 +150,7 @@ - status = "disabled"; - }; - -- usb@7e980000 { -+ usb: usb@7e980000 { - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; -@@ -149,6 +159,21 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ status = "disabled"; -+ }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ }; - }; - - clocks { -@@ -161,7 +186,7 @@ - reg = <0>; - #clock-cells = <0>; - clock-output-names = "mmc"; -- clock-frequency = <100000000>; -+ clock-frequency = <250000000>; - }; - - clk_i2c: clock@1 { diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile new file mode 100644 -index 0000000..6947556 +index 0000000..9411ec8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,57 @@ +@@ -0,0 +1,71 @@ +ifeq ($(CONFIG_OF),y) + +# Overlays for the Raspberry Pi platform @@ -119448,6 +118572,7 @@ index 0000000..6947556 +dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb @@ -119460,18 +118585,31 @@ index 0000000..6947556 +dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb + @@ -119489,10 +118627,10 @@ index 0000000..6947556 +endif diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README new file mode 100644 -index 0000000..3e08f98 +index 0000000..6a9b270 --- /dev/null +++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,493 @@ +@@ -0,0 +1,658 @@ +Introduction +============ + @@ -119569,11 +118707,15 @@ index 0000000..3e08f98 +The Overlay and Parameter Reference +=================================== + ++N.B. When editing this file, please preserve the indentation levels to make it simple to parse ++programmatically. NO HARD TABS. ++ ++ +Name: +Info: Configures the base Raspberry Pi hardware +Load: +Params: -+ audio Set to "on" to disable the onboard ALSA audio ++ audio Set to "on" to enable the onboard ALSA audio + interface (default "off") + + i2c_arm Set to "on" to enable the ARM's i2c interface @@ -119668,6 +118810,14 @@ index 0000000..3e08f98 +Params: + + ++Name: dht11 ++Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors ++ Also sometimes found with the part number(s) AM230x. ++Load: dtoverlay=dht11,= ++Params: gpiopin GPIO connected to the sensor's DATA output. ++ (default 4) ++ ++ +[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] + + @@ -119679,6 +118829,19 @@ index 0000000..3e08f98 + speed SPI bus speed (default 12000000) + + ++Name: gpio-poweroff ++Info: Drives a GPIO high or low on reboot ++Load: gpio-poweroff,= ++Params: gpiopin GPIO for signalling (default 26) ++ ++ active_low Set if the power control device requires a ++ high->low transition to trigger a power-down. ++ Note that this will require the support of a ++ custom dt-blob.bin to prevent a power-down ++ during the boot process, and that a reboot ++ will also cause the pin to go low. ++ ++ +Name: hifiberry-amp +Info: Configures the HifiBerry Amp and Amp+ audio cards +Load: dtoverlay=hifiberry-amp @@ -119748,6 +118911,8 @@ index 0000000..3e08f98 + + ds3231 Select the DS3231 device + ++ mcp7941x Select the MCP7941x device ++ + pcf2127 Select the PCF2127 device + + pcf8523 Select the PCF8523 device @@ -119755,6 +118920,12 @@ index 0000000..3e08f98 + pcf8563 Select the PCF8563 device + + ++Name: i2s-mmap ++Info: Enables mmap support in the bcm2708-i2s driver ++Load: dtoverlay=i2s-mmap ++Params: ++ ++ +Name: iqaudio-dac +Info: Configures the IQaudio DAC audio card +Load: dtoverlay=iqaudio-dac @@ -119779,8 +118950,8 @@ index 0000000..3e08f98 + (default "down") + + sense Override the IR receive auto-detection logic: -+ "1" = force active high -+ "0" = force active low ++ "0" = force active-high ++ "1" = force active-low + "-1" = use auto-detection + (default "-1") + @@ -119794,7 +118965,7 @@ index 0000000..3e08f98 + + +Name: mcp2515-can0 -+Info: Configures the MCP2515 CAN controller ++Info: Configures the MCP2515 CAN controller on spi0.0 +Load: dtoverlay=mcp2515-can0,= +Params: oscillator Clock frequency for the CAN controller (Hz) + @@ -119803,6 +118974,16 @@ index 0000000..3e08f98 + interrupt GPIO for interrupt signal + + ++Name: mcp2515-can1 ++Info: Configures the MCP2515 CAN controller on spi0.1 ++Load: dtoverlay=mcp2515-can1,= ++Params: oscillator Clock frequency for the CAN controller (Hz) ++ ++ spimaxfrequency Maximum SPI frequence (Hz) ++ ++ interrupt GPIO for interrupt signal ++ ++ +Name: mmc +Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock +Load: dtoverlay=mmc,= @@ -119820,6 +119001,8 @@ index 0000000..3e08f98 + + fps Delay between frame updates + ++ txbuflen Transmit buffer length (default 32768) ++ + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) @@ -119866,6 +119049,53 @@ index 0000000..3e08f98 +Params: gpiopin Input GPIO (default "18") + + ++Name: pwm ++Info: Configures a single PWM channel ++ Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++ 4) Currently the clock must have been enabled and configured ++ by other means. ++Load: dtoverlay=pwm-2chan,= ++Load: dtoverlay=pwm,= ++Params: pin Output pin (default 18) - see table ++ func Pin function (default 2 = Alt5) - see above ++ clock PWM clock frequency (informational) ++ ++ ++Name: pwm-2chan ++Info: Configures both PWM channels ++ Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++ 4) Currently the clock must have been enabled and configured ++ by other means. ++Load: dtoverlay=pwm-2chan,= ++Params: pin Output pin (default 18) - see table ++ pin2 Output pin for other channel (default 19) ++ func Pin function (default 2 = Alt5) - see above ++ func2 Function for pin2 (default 2 = Alt5) ++ clock PWM clock frequency (informational) ++ ++ ++Name: raspidac3 ++Info: Configures the RaspiDAV Rev.3x audio card ++Load: dtoverlay=raspidac3 ++Params: ++ ++ +Name: rpi-dac +Info: Configures the RPi DAC audio card +Load: dtoverlay=rpi-dac @@ -119886,18 +119116,69 @@ index 0000000..3e08f98 + xohms Touchpanel sensitivity (X-plate resistance) + + ++Name: rpi-ft5406 ++Info: Official Raspberry Pi display touchscreen ++Load: dtoverlay=rpi-ft5406 ++Params: ++ ++ +Name: rpi-proto +Info: Configures the RPi Proto audio card +Load: dtoverlay=rpi-proto +Params: + + ++Name: rpi-sense ++Info: Raspberry Pi Sense HAT ++Load: dtoverlay=rpi-sense ++Params: ++ ++ +Name: sdhost +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock +Load: dtoverlay=sdhost,= +Params: overclock_50 Clock (in MHz) to use when the MMC framework + requests 50MHz -+ force_pio Disable DMA support ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) ++ ++ ++Name: sdio ++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, ++ and enables SDIO via GPIOs 22-27. ++Load: dtoverlay=sdio,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) ++ ++ ++Name: smi ++Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! ++Load: dtoverlay=smi ++Params: ++ ++ ++Name: smi-dev ++Info: Enables the userspace interface for the SMI driver ++Load: dtoverlay=smi-dev ++Params: ++ ++ ++Name: smi-nand ++Info: Enables access to NAND flash via the SMI interface ++Load: dtoverlay=smi-nand ++Params: + + +Name: spi-bcm2708 @@ -119912,6 +119193,12 @@ index 0000000..3e08f98 +Params: + + ++Name: spi-gpio35-39 ++Info: move SPI function block to GPIO 35 to 39 ++Load: dtoverlay=spi-gpio35-39 ++Params: ++ ++ +Name: tinylcd35 +Info: 3.5" Color TFT Display by www.tinylcd.com + Options: Touch, RTC, keypad @@ -119943,6 +119230,22 @@ index 0000000..3e08f98 + dtoverlay=tinylcd35,touch,touchgpio=3 + + ++Name: uart1 ++Info: Enable uart1 in place of uart0 ++Load: dtoverlay=uart1,= ++Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) ++ ++ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) ++ ++ ++Name: vga666 ++Info: Overlay for the Fen Logic VGA666 board ++ This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds ++ after the kernel has started. ++Load: dtoverlay=vga666 ++Params: ++ ++ +Name: w1-gpio +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *don't* need a GPIO to drive an external pullup. @@ -120077,7 +119380,7 @@ index 0000000..6a92cd1 +}; diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts new file mode 100644 -index 0000000..b830bf2 +index 0000000..782b171 --- /dev/null +++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts @@ -0,0 +1,23 @@ @@ -120089,7 +119392,7 @@ index 0000000..b830bf2 + compatible = "brcm,bcm2708"; + + fragment@0 { -+ target = <&i2c1>; ++ target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; @@ -120205,6 +119508,46 @@ index 0000000..8fae869 + speed = <ð1>, "spi-max-frequency:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts +new file mode 100644 +index 0000000..ff8cb36 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts +@@ -0,0 +1,34 @@ ++// Definitions for gpio-poweroff module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ power_ctrl: power_ctrl { ++ compatible = "gpio-poweroff"; ++ gpios = <&gpio 26 0>; ++ force; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ power_ctrl_pins: power_ctrl_pins { ++ brcm,pins = <26>; ++ brcm,function = <1>; // out ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&power_ctrl>,"gpios:4", ++ <&power_ctrl_pins>,"brcm,pins:0"; ++ active_low = <&power_ctrl>,"gpios:8"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts new file mode 100644 index 0000000..2c81448 @@ -120623,10 +119966,10 @@ index 0000000..f774c4a +}; diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts new file mode 100644 -index 0000000..6bccfdc +index 0000000..fed4bd8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -0,0 +1,49 @@ +@@ -0,0 +1,55 @@ +// Definitions for several I2C based Real Time Clocks +/dts-v1/; +/plugin/; @@ -120635,7 +119978,7 @@ index 0000000..6bccfdc + compatible = "brcm,bcm2708"; + + fragment@0 { -+ target = <&i2c1>; ++ target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; @@ -120646,6 +119989,11 @@ index 0000000..6bccfdc + reg = <0x68>; + status = "disable"; + }; ++ mcp7941x: mcp7941x@6f { ++ compatible = "microchip,mcp7941x"; ++ reg = <0x6f>; ++ status = "disable"; ++ }; + ds3231: ds3231@68 { + compatible = "maxim,ds3231"; + reg = <0x68>; @@ -120671,6 +120019,7 @@ index 0000000..6bccfdc + __overrides__ { + ds1307 = <&ds1307>,"status"; + ds3231 = <&ds3231>,"status"; ++ mcp7941x = <&mcp7941x>,"status"; + pcf2127 = <&pcf2127>,"status"; + pcf8523 = <&pcf8523>,"status"; + pcf8563 = <&pcf8563>,"status"; @@ -120923,6 +120272,81 @@ index 0000000..398d59c + interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts +new file mode 100644 +index 0000000..6bef9ae +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts +@@ -0,0 +1,69 @@ ++/* ++ * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* disable spi-dev for spi0.1 */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ can1_pins: can1_pins { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* input */ ++ }; ++ }; ++ }; ++ ++ /* the clock/oscillator of the can-controller */ ++ fragment@2 { ++ target-path = "/clocks"; ++ __overlay__ { ++ /* external oscillator of mcp2515 on spi0.1 */ ++ can1_osc: can1_osc { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <16000000>; ++ }; ++ }; ++ }; ++ ++ /* the spi config of the can-controller itself binding everything together */ ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ can1: mcp2515@1 { ++ reg = <1>; ++ compatible = "microchip,mcp2515"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can1_pins>; ++ spi-max-frequency = <10000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 0x2>; ++ clocks = <&can1_osc>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ oscillator = <&can1_osc>,"clock-frequency:0"; ++ spimaxfrequency = <&can1>,"spi-max-frequency:0"; ++ interrupt = <&can1_pins>,"brcm,pins:0",<&can1>,"interrupts:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts new file mode 100644 index 0000000..0a37cf4 @@ -120950,10 +120374,10 @@ index 0000000..0a37cf4 +}; diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts new file mode 100644 -index 0000000..c06fe12 +index 0000000..9242a6e --- /dev/null +++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -0,0 +1,109 @@ +@@ -0,0 +1,111 @@ +/* + * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec + * @@ -121013,6 +120437,7 @@ index 0000000..c06fe12 + bgr; + fps = <30>; + buswidth = <8>; ++ txbuflen = <32768>; + + reset-gpios = <&gpio 15 0>; + dc-gpios = <&gpio 25 0>; @@ -121059,6 +120484,7 @@ index 0000000..c06fe12 + speed = <&mz61581>, "spi-max-frequency:0"; + rotate = <&mz61581>, "rotate:0"; + fps = <&mz61581>, "fps:0"; ++ txbuflen = <&mz61581>, "txbuflen:0"; + debug = <&mz61581>, "debug:0"; + xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; + }; @@ -121326,6 +120752,157 @@ index 0000000..40bf0e1 + <&pps_pins>,"brcm,pins:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts +new file mode 100644 +index 0000000..957e1a4 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts +@@ -0,0 +1,46 @@ ++/dts-v1/; ++/plugin/; ++ ++/* ++This is the 2-channel overlay - only use it if you need both channels. ++ ++Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ ++N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++*/ ++ ++/ { ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ pwm_pins: pwm_pins { ++ brcm,pins = <18 19>; ++ brcm,function = <2 2>; /* Alt5 */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ pin = <&pwm_pins>,"brcm,pins:0"; ++ pin2 = <&pwm_pins>,"brcm,pins:4"; ++ func = <&pwm_pins>,"brcm,function:0"; ++ func2 = <&pwm_pins>,"brcm,function:4"; ++ clock = <&clk_pwm>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts +new file mode 100644 +index 0000000..ddd67ff +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/* ++Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ ++N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++*/ ++ ++/ { ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ pwm_pins: pwm_pins { ++ brcm,pins = <18>; ++ brcm,function = <2>; /* Alt5 */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ pin = <&pwm_pins>,"brcm,pins:0"; ++ func = <&pwm_pins>,"brcm,function:0"; ++ clock = <&clk_pwm>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts +new file mode 100644 +index 0000000..1bd8054 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts +@@ -0,0 +1,45 @@ ++// Definitions for RaspiDACv3 ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "jg,raspidacv3"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ status = "okay"; ++ }; ++ ++ tpa6130a2: tpa6130a2@60 { ++ compatible = "ti,tpa6130a2"; ++ reg = <0x60>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts new file mode 100644 index 0000000..7fc6ac9 @@ -121454,6 +121031,29 @@ index 0000000..a8fa974 + xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts +new file mode 100644 +index 0000000..2e53a17 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts +@@ -0,0 +1,17 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ rpi_ft5406: rpi_ft5406 { ++ compatible = "rpi,rpi-ft5406"; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts new file mode 100644 index 0000000..2029930 @@ -121499,12 +121099,65 @@ index 0000000..2029930 + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +new file mode 100644 +index 0000000..2715324 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +@@ -0,0 +1,47 @@ ++// rpi-sense HAT ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ rpi-sense@46 { ++ compatible = "rpi,rpi-sense"; ++ reg = <0x46>; ++ keys-int-gpios = <&gpio 23 1>; ++ status = "okay"; ++ }; ++ ++ lsm9ds1-magn@1c { ++ compatible = "st,lsm9ds1-magn"; ++ reg = <0x1c>; ++ status = "okay"; ++ }; ++ ++ lsm9ds1-accel6a { ++ compatible = "st,lsm9ds1-accel"; ++ reg = <0x6a>; ++ status = "okay"; ++ }; ++ ++ lps25h-press@5c { ++ compatible = "st,lps25h-press"; ++ reg = <0x5c>; ++ status = "okay"; ++ }; ++ ++ hts221-humid@5f { ++ compatible = "st,hts221-humid"; ++ reg = <0x5f>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts new file mode 100644 -index 0000000..8fb28e9 +index 0000000..2da14a4 --- /dev/null +++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -0,0 +1,78 @@ +@@ -0,0 +1,56 @@ +/dts-v1/; +/plugin/; + @@ -121523,34 +121176,19 @@ index 0000000..8fb28e9 + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_pins>; + interrupts = <2 24>; -+ clocks = <&clk_sdhost>; ++ clocks = <&clk_core>; + dmas = <&dma 13>, + <&dma 13>; + dma-names = "tx", "rx"; + brcm,delay-after-stop = <0>; + brcm,overclock-50 = <0>; ++ brcm,pio-limit = <1>; + status = "okay"; + }; + }; + }; + + fragment@1 { -+ target = <&clocks>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_sdhost: sdhost { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { + target = <&gpio>; + __overlay__ { + sdhost_pins: sdhost_pins { @@ -121560,7 +121198,7 @@ index 0000000..8fb28e9 + }; + }; + -+ fragment@3 { ++ fragment@2 { + target = <&mmc>; + __overlay__ { + /* Find a way to disable the other driver */ @@ -121569,28 +121207,198 @@ index 0000000..8fb28e9 + }; + }; + -+ fragment@4 { -+ target-path = "/__overrides__"; ++ __overrides__ { ++ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; ++ force_pio = <&sdhost>,"brcm,force-pio?"; ++ pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ debug = <&sdhost>,"brcm,debug?"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts +new file mode 100644 +index 0000000..164f269 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts +@@ -0,0 +1,29 @@ ++/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ ++ ++/include/ "sdhost-overlay.dts" ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@3 { ++ target = <&mmc>; + __overlay__ { -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ compatible = "brcm,bcm2835-mmc"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ status = "okay"; + }; + }; + -+ __overrides__ { -+ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; -+ force_pio = <&sdhost>,"brcm,force-pio?"; -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ sdio_pins: sdio_pins { ++ brcm,pins = <22 23 24 25 26 27>; ++ brcm,function = <7 7 7 7 7 7>; /* ALT3 = SD1 */ ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/smi-dev-overlay.dts b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts +new file mode 100644 +index 0000000..b610d82 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts +@@ -0,0 +1,18 @@ ++// Description: Overlay to enable character device interface for SMI. ++// Author: Luke Wren ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ fragment@0 { ++ target = <&soc>; ++ __overlay__ { ++ smi_dev { ++ compatible = "brcm,bcm2835-smi-dev"; ++ smi_handle = <&smi>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/smi-nand-overlay.dts b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts +new file mode 100644 +index 0000000..13ce0b7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts +@@ -0,0 +1,69 @@ ++// Description: Overlay to enable NAND flash through ++// the secondary memory interface ++// Author: Luke Wren ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&smi>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&smi_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&soc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ nand: flash@0 { ++ compatible = "brcm,bcm2835-smi-nand"; ++ smi_handle = <&smi>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "okay"; ++ ++ partition@0 { ++ label = "stage2"; ++ // 128k ++ reg = <0 0x20000>; ++ read-only; ++ }; ++ partition@1 { ++ label = "firmware"; ++ // 16M ++ reg = <0x20000 0x1000000>; ++ read-only; ++ }; ++ partition@2 { ++ label = "root"; ++ // 2G (will need to use 64 bit for >=4G) ++ reg = <0x1020000 0x80000000>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ smi_pins: smi_pins { ++ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 ++ 12 13 14 15>; ++ /* Alt 1: SMI */ ++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 ++ 5 5 5 5 5>; ++ /* /CS, /WE and /OE are pulled high, as they are ++ generally active low signals */ ++ brcm,pull = <2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/smi-overlay.dts b/arch/arm/boot/dts/overlays/smi-overlay.dts +new file mode 100644 +index 0000000..095f52c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/smi-overlay.dts +@@ -0,0 +1,37 @@ ++// Description: Overlay to enable the secondary memory interface peripheral ++// Author: Luke Wren ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&smi>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&smi_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ smi_pins: smi_pins { ++ /* Don't configure the top two address bits, as ++ these are already used as ID_SD and ID_SC */ ++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 ++ 16 17 18 19 20 21 22 23 24 25>; ++ /* Alt 0: SMI */ ++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 ++ 5 5 5 5 5 5 5 5 5>; ++ /* /CS, /WE and /OE are pulled high, as they are ++ generally active low signals */ ++ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0>; ++ }; ++ }; + }; +}; diff --git a/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts new file mode 100644 -index 0000000..e378ef1 +index 0000000..688163e --- /dev/null +++ b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts -@@ -0,0 +1,18 @@ +@@ -0,0 +1,25 @@ +/* -+ * Device tree overlay for spi-bcm2835 ++ * Device tree overlay to use spi-bcm2708 + */ + +/dts-v1/; @@ -121606,6 +121414,13 @@ index 0000000..e378ef1 + compatible = "brcm,bcm2708-spi"; + }; + }; ++ ++ fragment@1 { ++ target = <&spi0_cs_pins>; ++ __overlay__ { ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; +}; diff --git a/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts new file mode 100644 @@ -121631,6 +121446,43 @@ index 0000000..fc1e39b + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts b/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts +new file mode 100644 +index 0000000..9648063 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts +@@ -0,0 +1,31 @@ ++/* ++ * Device tree overlay to move spi0 to gpio 35 to 39 on CM ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ cs-gpios = <&gpio 36 1>, <&gpio 35 1>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0_cs_pins>; ++ __overlay__ { ++ bcrm,pins = <36 35>; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0_pins>; ++ __overlay__ { ++ bcrm,pins = <37 38 39>; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts new file mode 100644 index 0000000..f7102c8 @@ -121853,6 +121705,86 @@ index 0000000..f7102c8 + keypad = <&keypad>,"status"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/uart1-overlay.dts b/arch/arm/boot/dts/overlays/uart1-overlay.dts +new file mode 100644 +index 0000000..fa73e1f +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/uart1-overlay.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ uart1_pins: uart1_pins { ++ brcm,pins = <14 15>; ++ brcm,function = <2>; /* alt5 */ ++ brcm,pull = <0 2>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/chosen"; ++ __overlay__ { ++ bootargs = "8250.nr_uarts=1"; ++ }; ++ }; ++ ++ __overrides__ { ++ txd1_pin = <&uart1_pins>,"brcm,pins:0"; ++ rxd1_pin = <&uart1_pins>,"brcm,pins:4"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/vga666-overlay.dts b/arch/arm/boot/dts/overlays/vga666-overlay.dts +new file mode 100644 +index 0000000..7fcab96 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/vga666-overlay.dts +@@ -0,0 +1,30 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ // There is no VGA driver module, but we need a platform device ++ // node (that doesn't already use pinctrl) to hang the pinctrl ++ // reference on - leds will do ++ ++ fragment@0 { ++ target = <&leds>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vga666_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ vga666_pins: vga666_pins { ++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 ++ 13 14 15 16 17 18 19 20 21>; ++ brcm,function = <6>; /* alt2 */ ++ brcm,pull = <0>; /* no pull */ ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts new file mode 100644 index 0000000..29a3b48 @@ -121946,10 +121878,518 @@ index 0000000..66a98f6 + }; +}; -From 7c4a63015f03594469922e65ae613bbc4e54c4cf Mon Sep 17 00:00:00 2001 +From 541b02ecaaf01ae1750f67762a52caa30e182f0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:47:07 +0200 +Subject: [PATCH 042/113] bcm2835: Match with BCM2708 Device Trees +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 132 ++++++++++++++++++++--- + arch/arm/boot/dts/bcm2835-rpi-b.dts | 117 ++++++++++++++++++-- + arch/arm/boot/dts/bcm2835.dtsi | 179 +++---------------------------- + 3 files changed, 234 insertions(+), 194 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +index 668442b..17e2443 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +@@ -1,30 +1,128 @@ + /dts-v1/; +-#include "bcm2835-rpi.dtsi" ++#include "bcm2835.dtsi" + + / { + compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; + model = "Raspberry Pi Model B+"; ++}; + +- leds { +- act { +- gpios = <&gpio 47 0>; +- }; ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; + +- pwr { +- label = "PWR"; +- gpios = <&gpio 35 0>; +- default-state = "keep"; +- linux,default-trigger = "default-on"; +- }; ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; + }; +-}; + +-&gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; + +- /* I2S interface */ +- i2s_alt0: i2s_alt0 { ++ i2s_pins: i2s { + brcm,pins = <18 19 20 21>; +- brcm,function = ; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&gpio 35 0>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1_clkrate = <&uart1>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts +index ee89b79..221d252 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts +@@ -1,23 +1,118 @@ + /dts-v1/; +-#include "bcm2835-rpi.dtsi" ++#include "bcm2835.dtsi" + + / { + compatible = "raspberrypi,model-b", "brcm,bcm2835"; + model = "Raspberry Pi Model B"; +- +- leds { +- act { +- gpios = <&gpio 16 1>; +- }; +- }; + }; + + &gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; + +- /* I2S interface */ +- i2s_alt2: i2s_alt2 { ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { + brcm,pins = <28 29 30 31>; +- brcm,function = ; ++ brcm,function = <6>; /* alt2 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 16 1>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1_clkrate = <&uart1>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index 440717c..3256bff 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -1,20 +1,15 @@ +-#include +-#include "skeleton.dtsi" ++#include "bcm2708_common.dtsi" + + / { + compatible = "brcm,bcm2835"; + model = "BCM2835"; +- interrupt-parent = <&intc>; + + chosen { +- bootargs = "earlyprintk console=ttyAMA0"; ++ bootargs = ""; + }; + + soc { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <1>; +- ranges = <0x7e000000 0x20000000 0x02000000>; ++ ranges = <0x7e000000 0x20000000 0x01000000>; + dma-ranges = <0x40000000 0x00000000 0x20000000>; + + timer@7e003000 { +@@ -24,169 +19,21 @@ + clock-frequency = <1000000>; + }; + +- dma: dma@7e007000 { +- compatible = "brcm,bcm2835-dma"; +- reg = <0x7e007000 0xf00>; +- interrupts = <1 16>, +- <1 17>, +- <1 18>, +- <1 19>, +- <1 20>, +- <1 21>, +- <1 22>, +- <1 23>, +- <1 24>, +- <1 25>, +- <1 26>, +- <1 27>, +- <1 28>; +- +- #dma-cells = <1>; +- brcm,dma-channel-mask = <0x7f35>; +- }; +- +- intc: interrupt-controller@7e00b200 { +- compatible = "brcm,bcm2835-armctrl-ic"; +- reg = <0x7e00b200 0x200>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- watchdog@7e100000 { +- compatible = "brcm,bcm2835-pm-wdt"; +- reg = <0x7e100000 0x28>; +- }; +- +- rng@7e104000 { +- compatible = "brcm,bcm2835-rng"; +- reg = <0x7e104000 0x10>; +- }; +- +- mailbox: mailbox@7e00b800 { +- compatible = "brcm,bcm2835-mbox"; +- reg = <0x7e00b880 0x40>; +- interrupts = <0 1>; +- #mbox-cells = <0>; +- }; +- +- gpio: gpio@7e200000 { +- compatible = "brcm,bcm2835-gpio"; +- reg = <0x7e200000 0xb4>; +- /* +- * The GPIO IP block is designed for 3 banks of GPIOs. +- * Each bank has a GPIO interrupt for itself. +- * There is an overall "any bank" interrupt. +- * In order, these are GIC interrupts 17, 18, 19, 20. +- * Since the BCM2835 only has 2 banks, the 2nd bank +- * interrupt output appears to be mirrored onto the +- * 3rd bank's interrupt signal. +- * So, a bank0 interrupt shows up on 17, 20, and +- * a bank1 interrupt shows up on 18, 19, 20! +- */ +- interrupts = <2 17>, <2 18>, <2 19>, <2 20>; +- +- gpio-controller; +- #gpio-cells = <2>; +- +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- uart@7e201000 { +- compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; +- reg = <0x7e201000 0x1000>; +- interrupts = <2 25>; +- clock-frequency = <3000000>; +- arm,primecell-periphid = <0x00241011>; +- }; +- +- i2s: i2s@7e203000 { +- compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x24>, +- <0x7e101098 0x08>; +- +- dmas = <&dma 2>, +- <&dma 3>; +- dma-names = "tx", "rx"; +- status = "disabled"; +- }; +- +- spi: spi@7e204000 { +- compatible = "brcm,bcm2835-spi"; +- reg = <0x7e204000 0x1000>; +- interrupts = <2 22>; +- clocks = <&clk_spi>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c0: i2c@7e205000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e205000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clk_i2c>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- sdhci: sdhci@7e300000 { +- compatible = "brcm,bcm2835-sdhci"; +- reg = <0x7e300000 0x100>; +- interrupts = <2 30>; +- clocks = <&clk_mmc>; +- status = "disabled"; +- }; +- +- i2c1: i2c@7e804000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e804000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clk_i2c>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- usb@7e980000 { +- compatible = "brcm,bcm2835-usb"; +- reg = <0x7e980000 0x10000>; +- interrupts = <1 9>; +- }; +- + arm-pmu { + compatible = "arm,arm1176-pmu"; + }; +- }; +- +- clocks { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <0>; + +- clk_mmc: clock@0 { +- compatible = "fixed-clock"; +- reg = <0>; +- #clock-cells = <0>; +- clock-output-names = "mmc"; +- clock-frequency = <100000000>; ++ aux_enable: aux_enable@0x7e215004 { ++ compatible = "bcrm,bcm2835-aux-enable"; ++ reg = <0x7e215004 0x04>; + }; ++ }; ++}; + +- clk_i2c: clock@1 { +- compatible = "fixed-clock"; +- reg = <1>; +- #clock-cells = <0>; +- clock-output-names = "i2c"; +- clock-frequency = <250000000>; +- }; ++&intc { ++ compatible = "brcm,bcm2835-armctrl-ic"; ++}; + +- clk_spi: clock@2 { +- compatible = "fixed-clock"; +- reg = <2>; +- #clock-cells = <0>; +- clock-output-names = "spi"; +- clock-frequency = <250000000>; +- }; +- }; ++&watchdog { ++ status = "okay"; + }; + +From 8e5d720e6c22fbc27f237c408ca9b3db2f182642 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 026/204] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 043/113] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -122042,10 +122482,10 @@ index fb795c3..fa72af0 100644 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ -From 4f1485790c96ee05b7fd08c23905f8957c8f2b61 Mon Sep 17 00:00:00 2001 +From e436037ad20fd0ef86290ad974e05c97a386a749 Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 029/204] Speed up console framebuffer imageblit function +Subject: [PATCH 046/113] Speed up console framebuffer imageblit function Especially on platforms with a slower CPU but a relatively high framebuffer fill bandwidth, like current ARM devices, the existing @@ -122254,10 +122694,10 @@ index a2bb276..436494f 100644 start_index, pitch_index); } else -From efd2fa9ef6e7848d0494f1a66d46e9280d507f4e Mon Sep 17 00:00:00 2001 +From 400e3b5c2e9b41c1d5f10446e1dfa6e02941c637 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 030/204] Allow mac address to be set in smsc95xx +Subject: [PATCH 047/113] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -122265,7 +122705,7 @@ Signed-off-by: popcornmix 1 file changed, 56 insertions(+) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 26423ad..e29a323 100644 +index 477b9c7..08a8a8c 100755 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -59,6 +59,7 @@ @@ -122276,7 +122716,7 @@ index 26423ad..e29a323 100644 struct smsc95xx_priv { u32 mac_cr; -@@ -74,6 +75,10 @@ static bool turbo_mode = true; +@@ -74,6 +75,10 @@ static bool turbo_mode = false; module_param(turbo_mode, bool, 0644); MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); @@ -122348,10 +122788,10 @@ index 26423ad..e29a323 100644 if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -From 625c18792c5c8272af5237599d44d852e0996bdf Mon Sep 17 00:00:00 2001 +From ffc945ed1ba5066ef8298a21ee1ad24d58bb3aa4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 031/204] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 048/113] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -122381,10 +122821,10 @@ w1-gpio: Sort out the pullup/parasitic power tangle 7 files changed, 157 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 26be516..55d2889 100644 +index 7dc0cc7..239ac46 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -36,6 +36,7 @@ +@@ -37,6 +37,7 @@ #include #include #include @@ -122392,7 +122832,7 @@ index 26be516..55d2889 100644 #include #include -@@ -77,12 +78,19 @@ +@@ -78,12 +79,19 @@ */ #define DMA_MASK_BITS_COMMON 32 @@ -122412,7 +122852,7 @@ index 26be516..55d2889 100644 static bool vc_i2c_override = false; static unsigned use_dt = 0; -@@ -303,6 +311,20 @@ static struct platform_device bcm2708_dmaengine_device = { +@@ -307,6 +315,20 @@ static struct platform_device bcm2708_dmaengine_device = { .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), }; @@ -122433,7 +122873,7 @@ index 26be516..55d2889 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -729,6 +751,11 @@ void __init bcm2708_init(void) +@@ -717,6 +739,11 @@ void __init bcm2708_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -122445,7 +122885,7 @@ index 26be516..55d2889 100644 bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); -@@ -942,5 +969,7 @@ module_param(uart_clock, uint, 0644); +@@ -927,5 +954,7 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); @@ -122454,7 +122894,7 @@ index 26be516..55d2889 100644 module_param(vc_i2c_override, bool, 0644); MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 50843df..0a5e4188 100644 +index 7d70eeb..b0b2186 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -36,6 +36,7 @@ @@ -122506,7 +122946,7 @@ index 50843df..0a5e4188 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -749,6 +771,11 @@ void __init bcm2709_init(void) +@@ -734,6 +756,11 @@ void __init bcm2709_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -122518,7 +122958,7 @@ index 50843df..0a5e4188 100644 bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); -@@ -1110,5 +1137,7 @@ module_param(uart_clock, uint, 0644); +@@ -1101,5 +1128,7 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); @@ -122749,10 +123189,35 @@ index d58594a..feae942 100644 unsigned int ext_pullup_enable_pin; unsigned int pullup_duration; -From 8b7527453528e339a4586eec937857f1b994daae Mon Sep 17 00:00:00 2001 +From c46444a0debf11dffd3a986deec638126701a0c0 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 3 Jul 2013 00:54:08 +0100 +Subject: [PATCH 049/113] Added Device IDs for August DVB-T 205 + +--- + drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +index 197a4f2..9d1a3d7 100644 +--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c ++++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +@@ -1898,6 +1898,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = { + &rtl28xxu_props, "Compro VideoMate U620F", NULL) }, + { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394, + &rtl28xxu_props, "MaxMedia HU394-T", NULL) }, ++ { DVB_USB_DEVICE(USB_VID_GTEK, 0xb803 /*USB_PID_AUGUST_DVBT205*/, ++ &rtl28xxu_props, "August DVB-T 205", NULL) }, ++ { DVB_USB_DEVICE(USB_VID_GTEK, 0xa803 /*USB_PID_AUGUST_DVBT205*/, ++ &rtl28xxu_props, "August DVB-T 205", NULL) }, + { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03, + &rtl28xxu_props, "Leadtek WinFast DTV Dongle mini", NULL) }, + { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A, + +From d19297b133390e93cd127767466826e9a55a8c5d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 033/204] config: Enable CONFIG_MEMCG, but leave it disabled +Subject: [PATCH 050/113] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- @@ -122761,10 +123226,10 @@ Subject: [PATCH 033/204] config: Enable CONFIG_MEMCG, but leave it disabled 2 files changed, 24 insertions(+) diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index 4d65b66..dd258ff 100644 +index 2c9eae6..4253b1c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5394,6 +5394,29 @@ static int __init cgroup_disable(char *str) +@@ -5551,6 +5551,29 @@ static int __init cgroup_disable(char *str) } __setup("cgroup_disable=", cgroup_disable); @@ -122795,10 +123260,10 @@ index 4d65b66..dd258ff 100644 { printk("cgroup: using legacy files on the default hierarchy\n"); diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 68dea90..6fd0c4f 100644 +index c57c442..32afce5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c -@@ -5389,6 +5389,7 @@ struct cgroup_subsys memory_cgrp_subsys = { +@@ -5226,6 +5226,7 @@ struct cgroup_subsys memory_cgrp_subsys = { .dfl_cftypes = memory_files, .legacy_cftypes = mem_cgroup_legacy_files, .early_init = 0, @@ -122807,10 +123272,10 @@ index 68dea90..6fd0c4f 100644 /** -From 727594aaa8ab739ea1c22eca69bf5400948af0d1 Mon Sep 17 00:00:00 2001 +From 391a663c1fa4ca5c3be13b04fa1c9db147bd1d95 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:33:38 +0100 -Subject: [PATCH 034/204] ASoC: Add support for BCM2708 +Subject: [PATCH 051/113] ASoC: Add support for BCM2708 This driver adds support for digital audio (I2S) for the BCM2708 SoC that is used by the @@ -123953,60 +124418,61 @@ index 0000000..6fdcbc1 + +#endif -From c0c7b62d38423b62ad3223b79f7f60802c6c1e5c Mon Sep 17 00:00:00 2001 +From ff45c8f704d2377bfc82b461cdc9ea2e7ba3f367 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 035/204] ASoC: Add support for PCM5102A codec +Subject: [PATCH 052/113] ASoC: Add support for PCM5102A codec Some definitions to support the PCM5102A codec by Texas Instruments. Signed-off-by: Florian Meier --- - sound/soc/codecs/Kconfig | 4 +++ + sound/soc/codecs/Kconfig | 5 ++++ sound/soc/codecs/Makefile | 2 ++ sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 69 insertions(+) + 3 files changed, 70 insertions(+) create mode 100644 sound/soc/codecs/pcm5102a.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 061c465..a3d70f9 100644 +index 0c9733e..f0b3e31 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -83,6 +83,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_I2C if I2C +@@ -87,6 +87,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM512x_SPI if SPI_MASTER select SND_SOC_RT286 if I2C + select SND_SOC_RT298 if I2C + select SND_SOC_PCM5102A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -511,6 +512,9 @@ config SND_SOC_RT286 +@@ -540,6 +541,10 @@ config SND_SOC_RT298 tristate depends on I2C +config SND_SOC_PCM5102A + tristate ++ depends on I2C + config SND_SOC_RT5631 tristate "Realtek ALC5631/RT5631 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index abe2d7e..a0fda52 100644 +index 4a32077..03cf632 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o +@@ -83,6 +83,7 @@ snd-soc-rl6231-objs := rl6231.o + snd-soc-rl6347a-objs := rl6347a.o snd-soc-rt286-objs := rt286.o + snd-soc-rt298-objs := rt298.o +snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o -@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o +@@ -275,6 +276,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o + obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o +obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o @@ -124081,10 +124547,10 @@ index 0000000..126f1e9 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 0f2fff9145ec3742650115b422b3fa4983002668 Mon Sep 17 00:00:00 2001 +From 3462291b4f4cdb89a8b69b113dc141b1160e5cd0 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:04:54 +0100 -Subject: [PATCH 036/204] BCM2708: Add I2S support to board file +Subject: [PATCH 053/113] BCM2708: Add I2S support to board file Adds the required initializations for I2S to the board file of mach-bcm2708. @@ -124098,16 +124564,18 @@ when some problems were found. Add the ability to enable this feature through Device Tree, using the i2s-mmap overlay. See: #1004 + +bcm2708-i2s: Don't use static pin configuration with DT --- arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ - sound/soc/bcm/bcm2708-i2s.c | 7 ++++++- - 2 files changed, 32 insertions(+), 1 deletion(-) + sound/soc/bcm/bcm2708-i2s.c | 11 ++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 55d2889..01f2de7 100644 +index 239ac46..c8e2550 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -616,6 +616,28 @@ static struct platform_device bcm2835_thermal_device = { +@@ -605,6 +605,28 @@ static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; @@ -124136,7 +124604,7 @@ index 55d2889..01f2de7 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -780,6 +802,10 @@ void __init bcm2708_init(void) +@@ -774,6 +796,10 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2835_thermal_device); @@ -124148,9 +124616,20 @@ index 55d2889..01f2de7 100644 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c -index a3b65dc..a515992 100644 +index a3b65dc..5e93cd6 100644 --- a/sound/soc/bcm/bcm2708-i2s.c +++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -409,8 +409,8 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, + if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) + return 0; + +- +- bcm2708_i2s_setup_gpio(); ++ if (!dev->dev->of_node) ++ bcm2708_i2s_setup_gpio(); + + /* + * Adjust the data length according to the format. @@ -874,7 +874,7 @@ static const struct snd_soc_component_driver bcm2708_i2s_component = { .name = "bcm2708-i2s-comp", }; @@ -124173,10 +124652,10 @@ index a3b65dc..a515992 100644 for (i = 0; i <= 1; i++) { void __iomem *base; -From b7db156b7135bd8023bc2e553fa802f10b33df21 Mon Sep 17 00:00:00 2001 +From 741d8118e27ad41b7b3909a106417a16b53c51f0 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 037/204] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 054/113] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -124325,24 +124804,32 @@ index 0000000..4b70b45 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From c48e1b97199c72f611b2f0937d36bc98a7169bba Mon Sep 17 00:00:00 2001 +From d660417bd278c6c6aa2653b7871663b5c6dfd3fa Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 038/204] BCM2708: Add HifiBerry DAC to board file +Subject: [PATCH 055/113] BCM2708: Add HifiBerry DAC to board file This adds the initalization of the HifiBerry DAC to the mach-bcm2708 board file. Signed-off-by: Florian Meier --- - arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) + arch/arm/mach-bcm2708/bcm2708.c | 38 ++++++++++++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/Kconfig | 9 ++++ + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ + 7 files changed, 217 insertions(+) + create mode 100644 sound/soc/bcm/rpi-dac.c + create mode 100644 sound/soc/codecs/pcm1794a.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 01f2de7..1d9b788 100644 +index c8e2550..639a921 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -638,6 +638,20 @@ static struct platform_device bcm2708_i2s_device = { +@@ -627,6 +627,34 @@ static struct platform_device bcm2708_i2s_device = { }; #endif @@ -124360,50 +124847,6 @@ index 01f2de7..1d9b788 100644 +}; +#endif + - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -806,6 +820,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2708_i2s_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_dac_device); -+ bcm_register_device_dt(&snd_pcm5102a_codec_device); -+#endif -+ - if (!use_dt) { - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - -From 46355bc118b045051f833c56844bba4b71b6b666 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 6 Dec 2013 20:50:28 +0100 -Subject: [PATCH 039/204] ASoC: BCM2708: Add support for RPi-DAC - -This adds a machine driver for the RPi-DAC. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ - sound/soc/codecs/Kconfig | 4 ++ - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ - 7 files changed, 193 insertions(+) - create mode 100644 sound/soc/bcm/rpi-dac.c - create mode 100644 sound/soc/codecs/pcm1794a.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 1d9b788..6d53beb 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - +#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) +static struct platform_device snd_rpi_dac_device = { + .name = "snd-rpi-dac", @@ -124421,10 +124864,15 @@ index 1d9b788..6d53beb 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -825,6 +839,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); +@@ -800,6 +828,16 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&bcm2708_i2s_device); #endif ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); ++#endif ++ +#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + bcm_register_device_dt(&snd_rpi_dac_device); + bcm_register_device_dt(&snd_pcm1794a_codec_device); @@ -124564,43 +125012,48 @@ index 0000000..6d6e0ba +MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index a3d70f9..dc3df1a 100644 +index f0b3e31..26eb019 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -84,6 +84,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_SPI if SPI_MASTER +@@ -88,6 +88,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_RT286 if I2C + select SND_SOC_RT298 if I2C select SND_SOC_PCM5102A if I2C + select SND_SOC_PCM1794A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -512,6 +513,9 @@ config SND_SOC_RT286 +@@ -541,6 +542,14 @@ config SND_SOC_RT298 tristate depends on I2C ++config SND_SOC_RT298 ++ tristate ++ depends on I2C ++ +config SND_SOC_PCM1794A + tristate ++ depends on I2C + config SND_SOC_PCM5102A tristate - + depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index a0fda52..c1f6ba6 100644 +index 03cf632..4e3c82c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o +@@ -83,6 +83,7 @@ snd-soc-rl6231-objs := rl6231.o + snd-soc-rl6347a-objs := rl6347a.o snd-soc-rt286-objs := rt286.o + snd-soc-rt298-objs := rt298.o +snd-soc-pcm1794a-objs := pcm1794a.o snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o -@@ -264,6 +265,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o +@@ -276,6 +277,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o + obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o +obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o @@ -124674,10 +125127,10 @@ index 0000000..b4eaa44 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 81991e83d009ef30b23b0f7190042479293aa418 Mon Sep 17 00:00:00 2001 +From a230f7f4f62b82120df5020e601ba11bd8ef47db Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 040/204] ASoC: wm8804: Implement MCLK configuration options, +Subject: [PATCH 056/113] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -124696,7 +125149,7 @@ Signed-off-by: Daniel Matuschek 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index 1e403f6..d4efa85 100644 +index 8d91470..5795fb1 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -304,6 +304,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream, @@ -124717,10 +125170,10 @@ index 1e403f6..d4efa85 100644 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ -From bf20cf45c9c208ff4a47465f3297196806b95da7 Mon Sep 17 00:00:00 2001 +From 09c44630d974be667f45b436501546dfe4fbbe0e Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 041/204] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 057/113] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -124985,10 +125438,10 @@ index 0000000..92e9e46 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From ebfceb0a7d6a4854618c00339d571421b7a18b68 Mon Sep 17 00:00:00 2001 +From fb0efafb4fd008c9e727e73d94824638551b81ef Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:26:08 +0100 -Subject: [PATCH 042/204] BCM2708: Added support for HiFiBerry Digi board Board +Subject: [PATCH 058/113] BCM2708: Added support for HiFiBerry Digi board Board initalization by I2C Signed-off-by: Daniel Matuschek @@ -124997,10 +125450,10 @@ Signed-off-by: Daniel Matuschek 1 file changed, 20 insertions(+) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6d53beb..a062d7f 100644 +index 639a921..2310319 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -652,6 +652,21 @@ static struct platform_device snd_pcm5102a_codec_device = { +@@ -641,6 +641,21 @@ static struct platform_device snd_pcm5102a_codec_device = { }; #endif @@ -125022,7 +125475,7 @@ index 6d53beb..a062d7f 100644 #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) static struct platform_device snd_rpi_dac_device = { .name = "snd-rpi-dac", -@@ -839,6 +854,11 @@ void __init bcm2708_init(void) +@@ -833,6 +848,11 @@ void __init bcm2708_init(void) bcm_register_device_dt(&snd_pcm5102a_codec_device); #endif @@ -125035,10 +125488,10 @@ index 6d53beb..a062d7f 100644 bcm_register_device_dt(&snd_rpi_dac_device); bcm_register_device_dt(&snd_pcm1794a_codec_device); -From b9597317ed9afa6fe3712758c0ad5d1b11766d60 Mon Sep 17 00:00:00 2001 +From 15928fd3c8fbfe8a384a345f42c7b4cfdb698433 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 043/204] ASoC: wm8804: Set idle_bias_off to false Idle bias +Subject: [PATCH 059/113] ASoC: wm8804: Set idle_bias_off to false Idle bias has been change to remove warning on driver startup Signed-off-by: Daniel Matuschek @@ -125047,7 +125500,7 @@ Signed-off-by: Daniel Matuschek 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index d4efa85..f3f26a2 100644 +index 5795fb1..c846716 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -544,7 +544,7 @@ static struct snd_soc_dai_driver wm8804_dai = { @@ -125060,10 +125513,10 @@ index d4efa85..f3f26a2 100644 .dapm_widgets = wm8804_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), -From 098e66a4235451ad64c8bc1349496fc68a0e16fc Mon Sep 17 00:00:00 2001 +From 9325f6c5023801d4d5786f96e8472039ca1720e3 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 044/204] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 060/113] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control @@ -125080,10 +125533,10 @@ limit of 0dB for this control. create mode 100644 sound/soc/bcm/iqaudio-dac.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a062d7f..a51a6168 100644 +index 2310319..6ed7299 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -681,6 +681,22 @@ static struct platform_device snd_pcm1794a_codec_device = { +@@ -670,6 +670,22 @@ static struct platform_device snd_pcm1794a_codec_device = { }; #endif @@ -125106,7 +125559,7 @@ index a062d7f..a51a6168 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -864,6 +880,11 @@ void __init bcm2708_init(void) +@@ -858,6 +874,11 @@ void __init bcm2708_init(void) bcm_register_device_dt(&snd_pcm1794a_codec_device); #endif @@ -125271,40 +125724,10 @@ index 0000000..aff7377 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From a2878cc4a414348ab3b5be3ad44f04ae8e77e3ab Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 045/204] vmstat: Workaround for issue where dirty page count - goes negative - -See: -https://github.com/raspberrypi/linux/issues/617 -http://www.spinics.net/lists/linux-mm/msg72236.html ---- - include/linux/vmstat.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 82e7db7..f87d16d 100644 ---- a/include/linux/vmstat.h -+++ b/include/linux/vmstat.h -@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) - static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) - { - atomic_long_dec(&zone->vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) -+ atomic_long_set(&zone->vm_stat[item], 0); - atomic_long_dec(&vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) -+ atomic_long_set(&vm_stat[item], 0); - } - - static inline void __inc_zone_page_state(struct page *page, - -From 0fb0113068c3d68d396dff09129369bd7719bb41 Mon Sep 17 00:00:00 2001 +From 559a146d1da68a1e9683f63056cec7fed3f4da33 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 046/204] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 061/113] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -125312,7 +125735,7 @@ Reduces overhead when using X 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c -index eab5bd6..ca47de9 100644 +index 36712e9..910fa89 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -49,7 +49,7 @@ @@ -125324,7 +125747,7 @@ index eab5bd6..ca47de9 100644 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -@@ -1090,8 +1090,12 @@ static int usbhid_start(struct hid_device *hid) +@@ -1091,8 +1091,12 @@ static int usbhid_start(struct hid_device *hid) } /* Change the polling interval of mice. */ @@ -125340,10 +125763,10 @@ index eab5bd6..ca47de9 100644 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From b5950dd391670c2090ca047af33ba1f5b330b272 Mon Sep 17 00:00:00 2001 +From f0502b1601d05a391735161c83200f95ea52e20c Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 047/204] Added support for HiFiBerry DAC+ +Subject: [PATCH 062/113] Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. @@ -125356,10 +125779,10 @@ a different codec chip (PCM5122), therefore a new driver is necessary. create mode 100644 sound/soc/bcm/hifiberry_dacplus.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a51a6168..d421a89 100644 +index 6ed7299..6c60e73 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { +@@ -641,6 +641,20 @@ static struct platform_device snd_pcm5102a_codec_device = { }; #endif @@ -125380,7 +125803,7 @@ index a51a6168..d421a89 100644 #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) static struct platform_device snd_hifiberry_digi_device = { .name = "snd-hifiberry-digi", -@@ -870,6 +884,11 @@ void __init bcm2708_init(void) +@@ -864,6 +878,11 @@ void __init bcm2708_init(void) bcm_register_device_dt(&snd_pcm5102a_codec_device); #endif @@ -125554,10 +125977,10 @@ index 0000000..c63387b +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); +MODULE_LICENSE("GPL v2"); -From 83ead1b240ffde9c9c592533b4b116ae721e6893 Mon Sep 17 00:00:00 2001 +From fa5f1fc1410ed46d94108f38a4288adb2e9e37a7 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 048/204] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 063/113] Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. @@ -125587,10 +126010,10 @@ Some code to load the driver based on device-tree-overlays was missing. This is create mode 100644 sound/soc/codecs/tas5713.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index d421a89..363b9c5 100644 +index 6c60e73..f1d853f 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -681,6 +681,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { +@@ -670,6 +670,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { #endif @@ -125611,7 +126034,7 @@ index d421a89..363b9c5 100644 #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) static struct platform_device snd_rpi_dac_device = { .name = "snd-rpi-dac", -@@ -894,6 +908,11 @@ void __init bcm2708_init(void) +@@ -888,6 +902,11 @@ void __init bcm2708_init(void) i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); #endif @@ -125793,10 +126216,10 @@ index 0000000..5903915 +MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index dc3df1a..8a9f07c 100644 +index 26eb019..097f006 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -109,6 +109,7 @@ config SND_SOC_ALL_CODECS +@@ -115,6 +115,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TFA9879 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER @@ -125804,7 +126227,7 @@ index dc3df1a..8a9f07c 100644 select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC31XX if I2C select SND_SOC_TLV320AIC32X4 if I2C -@@ -623,6 +624,9 @@ config SND_SOC_TFA9879 +@@ -665,6 +666,9 @@ config SND_SOC_TFA9879 tristate "NXP Semiconductors TFA9879 amplifier" depends on I2C @@ -125815,20 +126238,20 @@ index dc3df1a..8a9f07c 100644 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index c1f6ba6..8ebf7f1 100644 +index 4e3c82c..dc731db 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -109,6 +109,7 @@ snd-soc-sta529-objs := sta529.o - snd-soc-stac9766-objs := stac9766.o +@@ -116,6 +116,7 @@ snd-soc-sti-sas-objs := sti-sas.o snd-soc-tas5086-objs := tas5086.o + snd-soc-tas571x-objs := tas571x.o snd-soc-tfa9879-objs := tfa9879.o +snd-soc-tas5713-objs := tas5713.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o -@@ -293,6 +294,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o - obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o +@@ -307,6 +308,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o + obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o +obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o @@ -126426,10 +126849,10 @@ index 0000000..8f019e0 + +#endif /* _TAS5713_H */ -From d78d9b666c8a7fb477945825a161505701e11b28 Mon Sep 17 00:00:00 2001 +From ffd6c106bad201223f5cefd49c0db215b6b3205c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Apr 2015 19:14:18 +0100 -Subject: [PATCH 049/204] bcm2708: Allow option card devices to be configured +Subject: [PATCH 064/113] bcm2708: Allow option card devices to be configured via DT If the kernel is built with Device Tree support, and if a DT blob @@ -126442,7 +126865,7 @@ support code with each new device. 1 file changed, 1 insertion(+) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 03fa1cb..c816526 100644 +index 8c435be..5a75f4b 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { @@ -126451,13 +126874,13 @@ index 03fa1cb..c816526 100644 }; +MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); - static struct platform_driver bcm2835_i2s_driver = { - .probe = bcm2835_i2s_probe, + MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); + -From 0cf6cbc05769deca2546837472623fc4e7b56c11 Mon Sep 17 00:00:00 2001 +From 946e47edf2f42b7dea5f19b618c4985eed389597 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 18:45:39 +0100 -Subject: [PATCH 050/204] Adding Device Tree support for some RPi audio cards +Subject: [PATCH 065/113] Adding Device Tree support for some RPi audio cards --- arch/arm/mach-bcm2709/bcm2709.c | 143 ++++++++++++++++++++++++++++++++++++++ @@ -126469,10 +126892,10 @@ Subject: [PATCH 050/204] Adding Device Tree support for some RPi audio cards 6 files changed, 232 insertions(+) diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 0a5e4188..57e1f3d 100644 +index b0b2186..184b6a1 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -636,6 +636,115 @@ static struct platform_device bcm2835_thermal_device = { +@@ -621,6 +621,115 @@ static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; @@ -126588,7 +127011,7 @@ index 0a5e4188..57e1f3d 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -800,6 +909,40 @@ void __init bcm2709_init(void) +@@ -791,6 +900,40 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2835_thermal_device); @@ -126820,10 +127243,10 @@ index 126f1e9..7c6598e 100644 }; -From 1548b70b26d3607e2f51c46f98c09f704911e4ae Mon Sep 17 00:00:00 2001 +From 048b22df06862e17f9472e03385f6b83ba3238a8 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Wed, 29 Oct 2014 23:30:30 -0700 -Subject: [PATCH 051/204] Added support to reserve/enable a GPIO pin to be used +Subject: [PATCH 066/113] Added support to reserve/enable a GPIO pin to be used from pps-gpio module (LinuxPPS). Enable PPS modules in default config for RPi. @@ -126833,10 +127256,10 @@ Subject: [PATCH 051/204] Added support to reserve/enable a GPIO pin to be used 2 files changed, 54 insertions(+) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 363b9c5..74ec578 100644 +index f1d853f..df8cd0b 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -37,6 +37,7 @@ +@@ -38,6 +38,7 @@ #include #include #include @@ -126844,7 +127267,7 @@ index 363b9c5..74ec578 100644 #include #include -@@ -92,6 +93,7 @@ static unsigned reboot_part = 0; +@@ -93,6 +94,7 @@ static unsigned reboot_part = 0; static unsigned w1_gpio_pin = W1_GPIO; static unsigned w1_gpio_pullup = W1_PULLUP; static bool vc_i2c_override = false; @@ -126852,7 +127275,7 @@ index 363b9c5..74ec578 100644 static unsigned use_dt = 0; -@@ -325,6 +327,19 @@ static struct platform_device w1_device = { +@@ -329,6 +331,19 @@ static struct platform_device w1_device = { }; #endif @@ -126872,7 +127295,7 @@ index 363b9c5..74ec578 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -860,6 +875,16 @@ void __init bcm2708_init(void) +@@ -848,6 +863,16 @@ void __init bcm2708_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -126889,14 +127312,14 @@ index 363b9c5..74ec578 100644 #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) w1_gpio_pdata.pin = w1_gpio_pin; w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1116,3 +1141,5 @@ module_param(w1_gpio_pin, uint, 0644); +@@ -1101,3 +1126,5 @@ module_param(w1_gpio_pin, uint, 0644); module_param(w1_gpio_pullup, uint, 0644); module_param(vc_i2c_override, bool, 0644); MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +module_param(pps_gpio_pin, int, 0644); +MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 57e1f3d..721559b 100644 +index 184b6a1..ea3b689 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -37,6 +37,7 @@ @@ -126935,7 +127358,7 @@ index 57e1f3d..721559b 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -880,6 +895,16 @@ void __init bcm2709_init(void) +@@ -865,6 +880,16 @@ void __init bcm2709_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -126952,17 +127375,17 @@ index 57e1f3d..721559b 100644 #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) w1_gpio_pdata.pin = w1_gpio_pin; w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1284,3 +1309,5 @@ module_param(w1_gpio_pin, uint, 0644); +@@ -1275,3 +1300,5 @@ module_param(w1_gpio_pin, uint, 0644); module_param(w1_gpio_pullup, uint, 0644); module_param(vc_i2c_override, bool, 0644); MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +module_param(pps_gpio_pin, int, 0644); +MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -From c7e1fd615565779916e66d987595521dcefc691c Mon Sep 17 00:00:00 2001 +From ff740f0194549736ce50e6db372a3738df2c9cab Mon Sep 17 00:00:00 2001 From: Ryan Coe Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 052/204] Update ds1307 driver for device-tree support +Subject: [PATCH 067/113] Update ds1307 driver for device-tree support Signed-off-by: Ryan Coe --- @@ -126970,10 +127393,10 @@ Signed-off-by: Ryan Coe 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index 4ffabb3..c6789a7 100644 +index a705e64..c14c823 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c -@@ -1242,6 +1242,14 @@ static int ds1307_remove(struct i2c_client *client) +@@ -1235,6 +1235,14 @@ static int ds1307_remove(struct i2c_client *client) return 0; } @@ -126989,25 +127412,90 @@ index 4ffabb3..c6789a7 100644 .driver = { .name = "rtc-ds1307", -From 5d7ba67c43373946a8b3c8bed5f2e6e23090a09d Mon Sep 17 00:00:00 2001 +From c5999ebe205cbacdf554e871a53e53ac5875764d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 053/204] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 068/113] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support the Raspberry Pi PWR LED, which is driven by external hardware in normal use. N.B. pwr_led is not available on Model A or B boards. + +leds-gpio: Implement the brightness_get method + +The power LED uses some clever logic that means it is driven +by a voltage measuring circuit when configured as input, otherwise +it is driven by the GPIO output value. This patch wires up the +brightness_get method for leds-gpio so that user-space can monitor +the LED value via /sys/class/gpio/led1/brightness. Using the input +trigger this returns an indication of the system power health, +otherwise it is just whatever value the trigger has written most +recently. + +See: https://github.com/raspberrypi/linux/issues/1064 --- - drivers/leds/trigger/Kconfig | 7 ++++ + drivers/leds/leds-gpio.c | 18 +++++++++++- + drivers/leds/trigger/Kconfig | 7 +++++ drivers/leds/trigger/Makefile | 1 + - drivers/leds/trigger/ledtrig-input.c | 65 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 73 insertions(+) + drivers/leds/trigger/ledtrig-input.c | 54 ++++++++++++++++++++++++++++++++++++ + include/linux/leds.h | 3 ++ + 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 drivers/leds/trigger/ledtrig-input.c +diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c +index af1876a..7da6d05 100644 +--- a/drivers/leds/leds-gpio.c ++++ b/drivers/leds/leds-gpio.c +@@ -42,6 +42,13 @@ static void gpio_led_work(struct work_struct *work) + led_dat->platform_gpio_blink_set(led_dat->gpiod, + led_dat->new_level, NULL, NULL); + led_dat->blinking = 0; ++ } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { ++ gpiod_direction_input(led_dat->gpiod); ++ led_dat->cdev.flags &= ~SET_GPIO_INPUT; ++ } ++ else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { ++ gpiod_direction_output(led_dat->gpiod, led_dat->new_level); ++ led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; + } else + gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); + } +@@ -62,7 +69,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, + * seem to have a reliable way to know if we're already in one; so + * let's just assume the worst. + */ +- if (led_dat->can_sleep) { ++ if (led_dat->can_sleep || ++ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) { + led_dat->new_level = level; + schedule_work(&led_dat->work); + } else { +@@ -75,6 +83,13 @@ static void gpio_led_set(struct led_classdev *led_cdev, + } + } + ++static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) ++{ ++ struct gpio_led_data *led_dat = ++ container_of(led_cdev, struct gpio_led_data, cdev); ++ return gpiod_get_value_cansleep(led_dat->gpiod) ? LED_FULL : LED_OFF; ++} ++ + static int gpio_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, unsigned long *delay_off) + { +@@ -131,6 +146,7 @@ static int create_gpio_led(const struct gpio_led *template, + led_dat->cdev.blink_set = gpio_blink_set; + } + led_dat->cdev.brightness_set = gpio_led_set; ++ led_dat->cdev.brightness_get = gpio_led_get; + if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) + state = !!gpiod_get_value_cansleep(led_dat->gpiod); + else diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig -index 49794b4..640756b 100644 +index 5bda6a9..eb98cca 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig @@ -108,4 +108,11 @@ config LEDS_TRIGGER_CAMERA @@ -127033,10 +127521,10 @@ index 1abf48d..c03afdc 100644 +obj-$(CONFIG_LEDS_TRIGGER_INPUT) += ledtrig-input.o diff --git a/drivers/leds/trigger/ledtrig-input.c b/drivers/leds/trigger/ledtrig-input.c new file mode 100644 -index 0000000..2ca2b98 +index 0000000..07d1219 --- /dev/null +++ b/drivers/leds/trigger/ledtrig-input.c -@@ -0,0 +1,65 @@ +@@ -0,0 +1,54 @@ +/* + * Set LED GPIO to Input "Trigger" + * @@ -127057,27 +127545,16 @@ index 0000000..2ca2b98 +#include +#include "../leds.h" + -+/* This is a hack to get at the private 'gpio' member */ -+ -+struct gpio_led_data { -+ struct led_classdev cdev; -+ unsigned gpio; -+}; -+ +static void input_trig_activate(struct led_classdev *led_cdev) +{ -+ struct gpio_led_data *led_dat = -+ container_of(led_cdev, struct gpio_led_data, cdev); -+ if (gpio_is_valid(led_dat->gpio)) -+ gpio_direction_input(led_dat->gpio); ++ led_cdev->flags |= SET_GPIO_INPUT; ++ led_set_brightness_async(led_cdev, 0); +} + +static void input_trig_deactivate(struct led_classdev *led_cdev) +{ -+ struct gpio_led_data *led_dat = -+ container_of(led_cdev, struct gpio_led_data, cdev); -+ if (gpio_is_valid(led_dat->gpio)) -+ gpio_direction_output(led_dat->gpio, 0); ++ led_cdev->flags |= SET_GPIO_OUTPUT; ++ led_set_brightness_async(led_cdev, 0); +} + +static struct led_trigger input_led_trigger = { @@ -127102,11 +127579,25 @@ index 0000000..2ca2b98 +MODULE_AUTHOR("Phil Elwell "); +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); +diff --git a/include/linux/leds.h b/include/linux/leds.h +index b122eea..0b23990 100644 +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -48,6 +48,9 @@ struct led_classdev { + #define SET_BRIGHTNESS_ASYNC (1 << 21) + #define SET_BRIGHTNESS_SYNC (1 << 22) + #define LED_DEV_CAP_FLASH (1 << 23) ++ /* Additions for Raspberry Pi PWR LED */ ++#define SET_GPIO_INPUT (1 << 30) ++#define SET_GPIO_OUTPUT (1 << 31) + + /* Set LED brightness level */ + /* Must not sleep, use a workqueue if needed */ -From dfc29014435e46cbc28a4cdcdf1bff215964e13b Mon Sep 17 00:00:00 2001 +From 15b8e6fd3a6dcb183a65361dc845d06a1f031e1c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 20 Jun 2014 17:19:27 +0100 -Subject: [PATCH 054/204] bcm2709: Simplify and strip down IRQ handler +Subject: [PATCH 069/113] bcm2709: Simplify and strip down IRQ handler --- arch/arm/include/asm/entry-macro-multi.S | 2 + @@ -127114,7 +127605,7 @@ Subject: [PATCH 054/204] bcm2709: Simplify and strip down IRQ handler 2 files changed, 87 insertions(+), 88 deletions(-) diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S -index 469a2b3..9c0a7eb 100644 +index 609184f..693cc1f 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S @@ -1,5 +1,6 @@ @@ -127133,7 +127624,7 @@ index 469a2b3..9c0a7eb 100644 .macro arch_irq_handler, symbol_name .align 5 diff --git a/arch/arm/mach-bcm2709/include/mach/entry-macro.S b/arch/arm/mach-bcm2709/include/mach/entry-macro.S -index d08591b..08d184c 100644 +index d08591b..2e9f458 100644 --- a/arch/arm/mach-bcm2709/include/mach/entry-macro.S +++ b/arch/arm/mach-bcm2709/include/mach/entry-macro.S @@ -22,102 +22,99 @@ @@ -127189,7 +127680,7 @@ index d08591b..08d184c 100644 + str \tmp, [\irqstat] @ clear interrupt source + dsb + mov r1, sp -+ adr lr, BSYM(1b) ++ badr lr, 1b + b do_IPI +#endif +1030: @@ -127293,7 +127784,7 @@ index d08591b..08d184c 100644 + @ + @ routine called with r0 = irq number, r1 = struct pt_regs * + @ -+ adr lr, BSYM(1b) ++ badr lr, 1b + b asm_do_IRQ - .endm @@ -127325,100 +127816,10 @@ index d08591b..08d184c 100644 +1: get_irqnr_and_base r0, r2, r6, lr + .endm -From ee705807744ab8001d5ae997102c0c8c9785dafe Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 12 Feb 2015 11:17:53 +0000 -Subject: [PATCH 055/204] Fix LED "input" trigger implementation for 3.19 - ---- - drivers/leds/leds-gpio.c | 10 +++++++++- - drivers/leds/trigger/ledtrig-input.c | 19 ++++--------------- - include/linux/leds.h | 3 +++ - 3 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 15eb3f8..3cfbd6a 100644 ---- a/drivers/leds/leds-gpio.c -+++ b/drivers/leds/leds-gpio.c -@@ -41,6 +41,13 @@ static void gpio_led_work(struct work_struct *work) - led_dat->platform_gpio_blink_set(led_dat->gpiod, - led_dat->new_level, NULL, NULL); - led_dat->blinking = 0; -+ } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { -+ gpiod_direction_input(led_dat->gpiod); -+ led_dat->cdev.flags &= ~SET_GPIO_INPUT; -+ } -+ else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { -+ gpiod_direction_output(led_dat->gpiod, led_dat->new_level); -+ led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; - } else - gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); - } -@@ -61,7 +68,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, - * seem to have a reliable way to know if we're already in one; so - * let's just assume the worst. - */ -- if (led_dat->can_sleep) { -+ if (led_dat->can_sleep || -+ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) { - led_dat->new_level = level; - schedule_work(&led_dat->work); - } else { -diff --git a/drivers/leds/trigger/ledtrig-input.c b/drivers/leds/trigger/ledtrig-input.c -index 2ca2b98..07d1219 100644 ---- a/drivers/leds/trigger/ledtrig-input.c -+++ b/drivers/leds/trigger/ledtrig-input.c -@@ -18,27 +18,16 @@ - #include - #include "../leds.h" - --/* This is a hack to get at the private 'gpio' member */ -- --struct gpio_led_data { -- struct led_classdev cdev; -- unsigned gpio; --}; -- - static void input_trig_activate(struct led_classdev *led_cdev) - { -- struct gpio_led_data *led_dat = -- container_of(led_cdev, struct gpio_led_data, cdev); -- if (gpio_is_valid(led_dat->gpio)) -- gpio_direction_input(led_dat->gpio); -+ led_cdev->flags |= SET_GPIO_INPUT; -+ led_set_brightness_async(led_cdev, 0); - } - - static void input_trig_deactivate(struct led_classdev *led_cdev) - { -- struct gpio_led_data *led_dat = -- container_of(led_cdev, struct gpio_led_data, cdev); -- if (gpio_is_valid(led_dat->gpio)) -- gpio_direction_output(led_dat->gpio, 0); -+ led_cdev->flags |= SET_GPIO_OUTPUT; -+ led_set_brightness_async(led_cdev, 0); - } - - static struct led_trigger input_led_trigger = { -diff --git a/include/linux/leds.h b/include/linux/leds.h -index 9a2b000..60accc5 100644 ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -47,6 +47,9 @@ struct led_classdev { - #define SET_BRIGHTNESS_ASYNC (1 << 21) - #define SET_BRIGHTNESS_SYNC (1 << 22) - #define LED_DEV_CAP_FLASH (1 << 23) -+ /* Additions for Raspberry Pi PWR LED */ -+#define SET_GPIO_INPUT (1 << 30) -+#define SET_GPIO_OUTPUT (1 << 31) - - /* Set LED brightness level */ - /* Must not sleep, use a workqueue if needed */ - -From 27e98ca305c67ee354c42983a43f09b2e59ce5b5 Mon Sep 17 00:00:00 2001 +From 5a4e33549393b09c042a71a22b425d4367101827 Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 056/204] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 070/113] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes @@ -127427,7 +127828,7 @@ Signed-off-by: Noralf Tronnes 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 8d908e3..7a1900d 100644 +index 8efa235..04646672 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { @@ -127440,10 +127841,10 @@ index 8d908e3..7a1900d 100644 .can_sleep = false, }; -From e4022c2c7ada3dc69da92db183132c86cdc7d730 Mon Sep 17 00:00:00 2001 +From 325b7cc3bbc22776d12da10692d7008c619c4b85 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 4 Feb 2015 10:02:24 +0000 -Subject: [PATCH 057/204] pinctrl-bcm2835: bcm2835_gpio_direction_output must +Subject: [PATCH 071/113] pinctrl-bcm2835: bcm2835_gpio_direction_output must set the value --- @@ -127451,7 +127852,7 @@ Subject: [PATCH 057/204] pinctrl-bcm2835: bcm2835_gpio_direction_output must 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 7a1900d..62f85aa 100644 +index 04646672..f6de89e 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -355,7 +355,14 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -127471,10 +127872,10 @@ index 7a1900d..62f85aa 100644 static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -From d1c711959d41518b10f7c2797cac744c543468ad Mon Sep 17 00:00:00 2001 +From 0b206abf34d3ab8663d5b4b829e0e1d76af236cc Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Feb 2015 13:40:50 +0000 -Subject: [PATCH 058/204] pinctrl-bcm2835: Fix interrupt handling for GPIOs +Subject: [PATCH 072/113] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 and 46-53 Contrary to the documentation, the BCM2835 GPIO controller actually has @@ -127495,7 +127896,7 @@ the pins are often used for I2S instead. 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 62f85aa..c7cf266 100644 +index f6de89e..b5dedd78 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -47,6 +47,7 @@ @@ -127584,7 +127985,7 @@ index 62f85aa..c7cf266 100644 } static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, -@@ -1000,8 +1023,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1001,8 +1024,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for (i = 0; i < BCM2835_NUM_BANKS; i++) { unsigned long events; unsigned offset; @@ -127593,7 +127994,7 @@ index 62f85aa..c7cf266 100644 /* clear event detection flags */ bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0); -@@ -1016,10 +1037,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1017,10 +1038,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for_each_set_bit(offset, &events, 32) bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); @@ -127611,7 +128012,7 @@ index 62f85aa..c7cf266 100644 len = strlen(dev_name(pc->dev)) + 16; name = devm_kzalloc(pc->dev, len, GFP_KERNEL); -@@ -1077,6 +1103,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { +@@ -1078,6 +1104,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { .remove = bcm2835_pinctrl_remove, .driver = { .name = MODULE_NAME, @@ -127620,10 +128021,10 @@ index 62f85aa..c7cf266 100644 }, }; -From 3c62244d144a37b12b9af16a34eb67b4b7cf48ba Mon Sep 17 00:00:00 2001 +From 6c698f0d97ad6050f5c130108e5ccd15da46600d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 059/204] pinctrl-bcm2835: Only request the interrupts listed +Subject: [PATCH 073/113] pinctrl-bcm2835: Only request the interrupts listed in the DTB Although the GPIO controller can generate three interrupts (four counting @@ -127637,10 +128038,10 @@ interface, is unlikely to be a problem. 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index c7cf266..986779a 100644 +index b5dedd78..bee7c86 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -@@ -1044,6 +1044,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1045,6 +1045,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) int len; char *name; pc->irq[i] = irq_of_parse_and_map(np, i); @@ -127650,10 +128051,10 @@ index c7cf266..986779a 100644 pc->irq_data[i].irqgroup = i; -From f8391406e17d282f010b8deebe0ccd26f8ea2e49 Mon Sep 17 00:00:00 2001 +From c6a0e04c3aa39f40c0bbe5ceb14b2b1d8a105112 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Feb 2015 15:10:24 +0000 -Subject: [PATCH 060/204] enc28j60: Add device tree compatible string and an +Subject: [PATCH 074/113] enc28j60: Add device tree compatible string and an overlay --- @@ -127687,10 +128088,10 @@ index b1b5f66..c6b6e1a 100644 .probe = enc28j60_probe, .remove = enc28j60_remove, -From eb2703ff418ab3b72d09375f7c2aa49aee9f4a0e Mon Sep 17 00:00:00 2001 +From b58e541e5be30031e5f37132188ed6368be87bf6 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 061/204] Add driver for rpi-proto +Subject: [PATCH 075/113] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x @@ -127905,10 +128306,10 @@ index 0000000..c6e45a0 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From d3d38e562e57db9c529f93aedfe9fca8b5c70a38 Mon Sep 17 00:00:00 2001 +From b6f020bcccef5499dd127a7f9805863610dd56e5 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Thu, 2 Apr 2015 12:22:55 +0100 -Subject: [PATCH 062/204] Add Device Tree support for RPi-DAC. +Subject: [PATCH 076/113] Add Device Tree support for RPi-DAC. --- sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++ @@ -127983,24 +128384,24 @@ index b4eaa44..afe1b41 100644 }; -From b15b358e11a817bcc7c3d8354c8a2f6f7d30a806 Mon Sep 17 00:00:00 2001 +From 997d60065e6eaa8aa93c4abe4c3cbd421da1f99f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 063/204] config: Add default configs +Subject: [PATCH 077/113] config: Add default configs --- - arch/arm/configs/bcm2709_defconfig | 1204 ++++++++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 1199 +++++++++++++++++++++++++++++++++++ - 2 files changed, 2403 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1244 ++++++++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 1240 +++++++++++++++++++++++++++++++++++ + 2 files changed, 2484 insertions(+) create mode 100644 arch/arm/configs/bcm2709_defconfig create mode 100644 arch/arm/configs/bcmrpi_defconfig diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig new file mode 100644 -index 0000000..a3067bf +index 0000000..66a1c1399 --- /dev/null +++ b/arch/arm/configs/bcm2709_defconfig -@@ -0,0 +1,1204 @@ +@@ -0,0 +1,1244 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +CONFIG_LOCALVERSION="-v7" @@ -128020,6 +128421,7 @@ index 0000000..a3067bf +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y ++CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y @@ -128052,6 +128454,8 @@ index 0000000..a3067bf +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_SECCOMP=y +CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -128392,6 +128796,12 @@ index 0000000..a3067bf +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_UBI=m ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m @@ -128400,6 +128810,7 @@ index 0000000..a3067bf +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y @@ -128416,6 +128827,7 @@ index 0000000..a3067bf +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m @@ -128514,6 +128926,8 @@ index 0000000..a3067bf +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_WL_MEDIATEK=y ++CONFIG_MT7601U=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_MWIFIEX=m @@ -128531,9 +128945,11 @@ index 0000000..a3067bf +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y @@ -128552,19 +128968,27 @@ index 0000000..a3067bf +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_BCM2708=m @@ -128597,7 +129021,11 @@ index 0000000..a3067bf +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_BATTERY_DS2760=m -+# CONFIG_HWMON is not set ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_HWMON=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHTC1=m +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y @@ -128776,6 +129204,7 @@ index 0000000..a3067bf +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -128811,6 +129240,9 @@ index 0000000..a3067bf +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SOUND_PRIME=m +CONFIG_HIDRAW=y @@ -129060,7 +129492,7 @@ index 0000000..a3067bf +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y ++CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m @@ -129069,6 +129501,8 @@ index 0000000..a3067bf +CONFIG_IIO_BUFFER_CB=y +CONFIG_IIO_KFIFO_BUF=m +CONFIG_DHT11=m ++CONFIG_PWM_BCM2835=m ++CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -129089,12 +129523,14 @@ index 0000000..a3067bf +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y @@ -129114,11 +129550,13 @@ index 0000000..a3067bf +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y @@ -129133,6 +129571,10 @@ index 0000000..a3067bf +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_SMB2=y ++CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" @@ -129194,23 +129636,22 @@ index 0000000..a3067bf +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_SHA512_ARM_NEON=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig new file mode 100644 -index 0000000..6a41231 +index 0000000..3e1ac5a --- /dev/null +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,1199 @@ +@@ -0,0 +1,1240 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +# CONFIG_LOCALVERSION_AUTO is not set @@ -129229,6 +129670,7 @@ index 0000000..6a41231 +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y ++CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y @@ -129257,6 +129699,8 @@ index 0000000..6a41231 +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_SECCOMP=y +CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -129595,6 +130039,12 @@ index 0000000..6a41231 +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_UBI=m ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m @@ -129603,6 +130053,7 @@ index 0000000..6a41231 +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y @@ -129619,6 +130070,7 @@ index 0000000..6a41231 +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m @@ -129717,6 +130169,8 @@ index 0000000..6a41231 +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_WL_MEDIATEK=y ++CONFIG_MT7601U=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_MWIFIEX=m @@ -129734,9 +130188,11 @@ index 0000000..6a41231 +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y @@ -129755,19 +130211,27 @@ index 0000000..6a41231 +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_BCM2708=m @@ -129800,7 +130264,11 @@ index 0000000..6a41231 +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_BATTERY_DS2760=m -+# CONFIG_HWMON is not set ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_HWMON=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHTC1=m +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y @@ -129979,6 +130447,7 @@ index 0000000..6a41231 +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -130014,6 +130483,9 @@ index 0000000..6a41231 +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SOUND_PRIME=m +CONFIG_HIDRAW=y @@ -130263,7 +130735,7 @@ index 0000000..6a41231 +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y ++CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m @@ -130272,6 +130744,8 @@ index 0000000..6a41231 +CONFIG_IIO_BUFFER_CB=y +CONFIG_IIO_KFIFO_BUF=m +CONFIG_DHT11=m ++CONFIG_PWM_BCM2835=m ++CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -130292,12 +130766,14 @@ index 0000000..6a41231 +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y @@ -130317,11 +130793,13 @@ index 0000000..6a41231 +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y @@ -130336,6 +130814,10 @@ index 0000000..6a41231 +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_SMB2=y ++CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" @@ -130399,169 +130881,22 @@ index 0000000..6a41231 +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 97b84b787de84ad70a3a3a2d7faa9c898c89077c Mon Sep 17 00:00:00 2001 -From: Steve Glendinning -Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 064/204] smsx95xx: fix crimes against truesize - -smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. - -This patch stops smsc95xx from changing truesize. - -Signed-off-by: Steve Glendinning ---- - drivers/net/usb/smsc95xx.c | 2 -- - 1 file changed, 2 deletions(-) - mode change 100644 => 100755 drivers/net/usb/smsc95xx.c - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -old mode 100644 -new mode 100755 -index e29a323..aff63dc ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -1841,7 +1841,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(skb); - skb_trim(skb, skb->len - 4); /* remove fcs */ -- skb->truesize = size + sizeof(struct sk_buff); - - return 1; - } -@@ -1859,7 +1858,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(ax_skb); - skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ -- ax_skb->truesize = size + sizeof(struct sk_buff); - - usbnet_skb_return(dev, ax_skb); - } - -From f00f1c85db60369955c57b255c2588ff56d59fa7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 17 Apr 2015 16:58:45 +0100 -Subject: [PATCH 065/204] smsc95xx: Disable turbo mode by default - ---- - drivers/net/usb/smsc95xx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index aff63dc..08a8a8c 100755 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -71,7 +71,7 @@ struct smsc95xx_priv { - u8 suspend_flags; - }; - --static bool turbo_mode = true; -+static bool turbo_mode = false; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - - -From 122b539270dc7e0d8ee3b6926c77f5aedb06fb67 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 17 Apr 2015 19:30:22 +0100 -Subject: [PATCH 066/204] Add blk_pos parameter to mmc multi_io_quirk callback - ---- - drivers/mmc/card/block.c | 1 + - drivers/mmc/host/omap_hsmmc.c | 4 +++- - drivers/mmc/host/sh_mobile_sdhi.c | 4 +++- - drivers/mmc/host/tmio_mmc_pio.c | 4 +++- - include/linux/mmc/host.h | 4 +++- - 5 files changed, 13 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index 31d2627..8484ec9 100644 ---- a/drivers/mmc/card/block.c -+++ b/drivers/mmc/card/block.c -@@ -1415,6 +1415,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, - brq->data.blocks = card->host->ops->multi_io_quirk(card, - (rq_data_dir(req) == READ) ? - MMC_DATA_READ : MMC_DATA_WRITE, -+ blk_rq_pos(req), - brq->data.blocks); - } - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index d0abdffb..ebb6bf4 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1749,7 +1749,9 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) - } - - static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, int blk_size) -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size) - { - /* This controller can't do multiblock reads due to hw bugs */ - if (direction == MMC_DATA_READ) -diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c -index 354f4f3..4f1ccf3 100644 ---- a/drivers/mmc/host/sh_mobile_sdhi.c -+++ b/drivers/mmc/host/sh_mobile_sdhi.c -@@ -170,7 +170,9 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) - } - - static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, int blk_size) -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size) - { - /* - * In Renesas controllers, when performing a -diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c -index dba7e1c..0c87f4f 100644 ---- a/drivers/mmc/host/tmio_mmc_pio.c -+++ b/drivers/mmc/host/tmio_mmc_pio.c -@@ -1001,7 +1001,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) - } - - static int tmio_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, int blk_size) -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size) - { - struct tmio_mmc_host *host = mmc_priv(card->host); - -diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index b0258e8..d3cdad9 100644 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -140,7 +140,9 @@ struct mmc_host_ops { - * I/O. Returns the number of supported blocks for the request. - */ - int (*multi_io_quirk)(struct mmc_card *card, -- unsigned int direction, int blk_size); -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size); - }; - - struct mmc_card; - -From ec8a45bdc3e0afbf5ab8ba7735608e7ca11feca7 Mon Sep 17 00:00:00 2001 +From 2e2c297b30fc0f436fe743209a782b3b377c38c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 29 Apr 2015 17:24:02 +0200 -Subject: [PATCH 067/204] bcm2835: bcm2835_defconfig +Subject: [PATCH 078/113] bcm2835: bcm2835_defconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -130634,16 +130969,79 @@ rm merge.cfg filter filtered.cfg added.cfg defconfig ARCH=arm make bcm2835_defconfig ARCH=arm make oldconfig +Signed-off-by: Noralf Trønnes + +configs: Incorporate v4.1 dependency changes + +Commit 78e9b7de78bb53e8bc7f4c4a60ebacb250c0c190 added a +dependency on TI_ST instead of selecting it, disabling: +CONFIG_BT_WILINK=m +CONFIG_RADIO_WL128X=m + +Commit 652ccae5cc4e1305fb0a4619947f9ee89d8c7f5a added a +depency on ARM_CRYPTO, disabling: +CONFIG_CRYPTO_SHA*_ARM*=m +CONFIG_CRYPTO_AES_ARM*=m + +Signed-off-by: Noralf Trønnes + +Conflicts: + arch/arm/configs/bcm2709_defconfig + +bcm2835: Sync bcm2835_defconfig with bcmrpi_defconfig + +These commands where used to make this commit: + +: Get changed and new config values from a merge +./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg + +: Remove these options +cat << EOF > filter +CONFIG_ARCH_BCM2708 +CONFIG_BCM2708_DT +CONFIG_ARM_PATCH_PHYS_VIRT +CONFIG_PHYS_OFFSET +CONFIG_CMDLINE +CONFIG_BCM2708_WDT +CONFIG_HW_RANDOM_BCM2708 +CONFIG_SPI_BCM2708 +EOF + +: Apply filter +grep -F -v -f filter merge.cfg > filtered.cfg + +: Add these options +: watchdog contains the restart/poweroff code. +cat << EOF > added.cfg +CONFIG_WATCHDOG=y +CONFIG_BCM2835_WDT=y +CONFIG_MISC_FILESYSTEMS=y +CONFIG_I2C_BCM2835=m +CONFIG_SND_BCM2835_SOC_I2S=m +EOF + +: Create new config +ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg +: Verify +ARCH=arm make oldconfig + +: Update bcm2835_defconfig +ARCH=arm make savedefconfig +cp defconfig arch/arm/configs/bcm2835_defconfig + +: Clean up +rm merge.cfg filter filtered.cfg added.cfg defconfig + Signed-off-by: Noralf Trønnes --- - arch/arm/configs/bcm2835_defconfig | 1132 +++++++++++++++++++++++++++++++++++- - 1 file changed, 1107 insertions(+), 25 deletions(-) + arch/arm/configs/bcm2835_defconfig | 1165 +++++++++++++++++++++++++++++++++++- + 1 file changed, 1139 insertions(+), 26 deletions(-) diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 31cb073..2e8a95a 100644 +index 31cb073..5b391a5 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig -@@ -1,105 +1,1071 @@ +@@ -1,105 +1,1102 @@ # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y @@ -130707,6 +131105,8 @@ index 31cb073..2e8a95a 100644 CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_SECCOMP=y -CONFIG_CC_STACKPROTECTOR=y @@ -131052,6 +131452,8 @@ index 31cb073..2e8a95a 100644 # CONFIG_STANDALONE is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m @@ -131060,6 +131462,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y @@ -131179,6 +131582,8 @@ index 31cb073..2e8a95a 100644 +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_WL_MEDIATEK=y ++CONFIG_MT7601U=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_MWIFIEX=m @@ -131196,9 +131601,11 @@ index 31cb073..2e8a95a 100644 +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y @@ -131217,22 +131624,32 @@ index 31cb073..2e8a95a 100644 +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y +-CONFIG_I2C_BCM2835=y +CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2835=y ++CONFIG_I2C_BCM2708=m ++CONFIG_I2C_BCM2835=m CONFIG_SPI=y -CONFIG_SPI_BCM2835=y +CONFIG_SPI_BCM2835=m @@ -131262,6 +131679,8 @@ index 31cb073..2e8a95a 100644 +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_BATTERY_DS2760=m ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y # CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y @@ -131441,6 +131860,7 @@ index 31cb073..2e8a95a 100644 -CONFIG_FB_SIMPLE=y +CONFIG_FB_BCM2708=y +CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m CONFIG_FRAMEBUFFER_CONSOLE=y @@ -131470,6 +131890,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_SOC=m +CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m @@ -131477,6 +131898,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SOUND_PRIME=m +CONFIG_HIDRAW=y @@ -131531,6 +131953,7 @@ index 31cb073..2e8a95a 100644 CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y +CONFIG_USB_PRINTER=m CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m @@ -131699,6 +132122,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_STAGING_MEDIA=y +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_IMON=m ++CONFIG_LIRC_RPI=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_FB_TFT=m @@ -131730,14 +132154,20 @@ index 31cb073..2e8a95a 100644 +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y ++CONFIG_BCM2835_MBOX=y # CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_DHT11=m ++CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y -@@ -107,18 +1073,110 @@ CONFIG_EXT3_FS=y +@@ -107,18 +1104,110 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y @@ -131759,6 +132189,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m @@ -131789,7 +132220,6 @@ index 31cb073..2e8a95a 100644 +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y CONFIG_NFS_FS=y -CONFIG_NFSD=y +CONFIG_NFS_V3_ACL=y @@ -131851,7 +132281,7 @@ index 31cb073..2e8a95a 100644 CONFIG_PRINTK_TIME=y CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y -@@ -128,14 +1186,38 @@ CONFIG_DEBUG_INFO=y +@@ -128,14 +1217,38 @@ CONFIG_DEBUG_INFO=y CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_LOCKUP_DETECTOR=y @@ -131877,88 +132307,46 @@ index 31cb073..2e8a95a 100644 +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y # CONFIG_XZ_DEC_ARM is not set # CONFIG_XZ_DEC_ARMTHUMB is not set -From af1868e02b629a2e2092bf358540d6ca4dcdff6c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 23:00:15 +0200 -Subject: [PATCH 068/204] BCM270x_DT: Add mailbox bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add bcm2708-vcio to Device Tree and don't add the -platform device when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 74ec578..5527d5c 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -870,7 +870,7 @@ void __init bcm2708_init(void) - bcm2708_dt_init(); - - bcm_register_device_dt(&bcm2708_dmaengine_device); -- bcm_register_device(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vcio_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 721559b..4a00561 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -890,7 +890,7 @@ void __init bcm2709_init(void) - bcm2709_dt_init(); - - bcm_register_device_dt(&bcm2708_dmaengine_device); -- bcm_register_device(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vcio_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - -From ab35f5a7f3921cd9d5d9f09f4bd82675822048dc Mon Sep 17 00:00:00 2001 +From 6d2eae30176f1d49a63f6834f218448c0e91e41f Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 069/204] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 079/113] rpi-ft5406: Add touchscreen driver for pi LCD display +Fix driver detection failure Check that the buffer response is non-zero meaning the touchscreen was detected + +rpi-ft5406: Use firmware API --- - drivers/input/touchscreen/Kconfig | 7 + - drivers/input/touchscreen/Makefile | 1 + - drivers/input/touchscreen/rpi-ft5406.c | 258 ++++++++++++++++++++++++++ - include/linux/platform_data/mailbox-bcm2708.h | 1 + - 4 files changed, 267 insertions(+) + drivers/input/touchscreen/Kconfig | 7 + + drivers/input/touchscreen/Makefile | 1 + + drivers/input/touchscreen/rpi-ft5406.c | 246 +++++++++++++++++++++++++++++++++ + 3 files changed, 254 insertions(+) create mode 100644 drivers/input/touchscreen/rpi-ft5406.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 80f6386..5848562 100644 +index 600dcce..5bfc087 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -583,6 +583,13 @@ config TOUCHSCREEN_EDT_FT5X06 +@@ -595,6 +595,13 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. +config TOUCHSCREEN_RPI_FT5406 + tristate "Raspberry Pi FT5406 driver" -+ depends on ARCH_BCM2708 || ARCH_BCM2709 ++ depends on RASPBERRYPI_FIRMWARE + help + Say Y here to enable the Raspberry Pi memory based FT5406 device + @@ -131967,7 +132355,7 @@ index 80f6386..5848562 100644 tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index 44deea7..a1be09f 100644 +index 1b79cc0..a0f77b2 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o @@ -131980,10 +132368,10 @@ index 44deea7..a1be09f 100644 obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c new file mode 100644 -index 0000000..f55151b +index 0000000..c08817e --- /dev/null +++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -0,0 +1,258 @@ +@@ -0,0 +1,246 @@ +/* + * Driver for memory based ft5406 touchscreen + * @@ -132007,7 +132395,7 @@ index 0000000..f55151b +#include +#include +#include -+#include ++#include + +#define MAXIMUM_SUPPORTED_POINTS 10 +struct ft5406_regs { @@ -132035,23 +132423,6 @@ index 0000000..f55151b + struct task_struct * thread; +}; + -+ -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the message id */ -+ uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -+ uint32_t data_size; /* amount of data being sent or received */ -+ uint32_t val; /* data buffer */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ +/* Thread to poll for touchscreen events + * + * This thread polls the memory based register copy of the ft5406 registers @@ -132122,11 +132493,37 @@ index 0000000..f55151b +{ + int ret; + struct input_dev * input_dev = input_allocate_device(); -+ struct vc_msg request; + struct ft5406 * ts; ++ struct device_node *fw_node; ++ struct rpi_firmware *fw; ++ u32 touchbuf; + + dev_info(&pdev->dev, "Probing device\n"); + ++ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++ if (!fw_node) { ++ dev_err(&pdev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++ ++ fw = rpi_firmware_get(fw_node); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF, ++ &touchbuf, sizeof(touchbuf)); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to get touch buffer\n"); ++ return ret; ++ } ++ ++ if (!touchbuf) { ++ dev_err(&pdev->dev, "Touchscreen not detected\n"); ++ return -ENODEV; ++ } ++ ++ dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", touchbuf); ++ + ts = kzalloc(sizeof(struct ft5406), GFP_KERNEL); + + if (!ts || !input_dev) { @@ -132160,36 +132557,15 @@ index 0000000..f55151b + return ret; + } + -+ memset(&request, 0, sizeof request); -+ -+ request.msg_size = sizeof request; -+ request.request_code = VCMSG_PROCESS_REQUEST; -+ request.tag.tag_id = VCMSG_GET_TOUCHBUF; -+ request.tag.buffer_size = 4; -+ request.tag.data_size = 4; -+ -+ bcm_mailbox_property(&request, sizeof(request)); -+ -+ if(request.request_code == VCMSG_REQUEST_SUCCESSFUL) -+ { -+ dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", request.tag.val); -+ } -+ else -+ { -+ input_unregister_device(input_dev); -+ kzfree(ts); -+ return -1; -+ } -+ + // mmap the physical memory -+ request.tag.val &= ~0xc0000000; -+ ts->ts_base = ioremap(request.tag.val, sizeof(*ts->regs)); ++ touchbuf &= ~0xc0000000; ++ ts->ts_base = ioremap(touchbuf, sizeof(*ts->regs)); + if(ts->ts_base == NULL) + { + dev_err(&pdev->dev, "Failed to map physical address\n"); + input_unregister_device(input_dev); + kzfree(ts); -+ return -1; ++ return -ENOMEM; + } + + ts->regs = (struct ft5406_regs *) ts->ts_base; @@ -132242,41 +132618,33 @@ index 0000000..f55151b +MODULE_AUTHOR("Gordon Hollingworth"); +MODULE_DESCRIPTION("Touchscreen driver for memory based FT5406"); +MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -index cc284ed..d3ea839 100644 ---- a/include/linux/platform_data/mailbox-bcm2708.h -+++ b/include/linux/platform_data/mailbox-bcm2708.h -@@ -115,6 +115,7 @@ enum { - VCMSG_SET_TRANSFORM = 0x0004800d, - VCMSG_TST_VSYNC = 0x0004400e, - VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_GET_TOUCHBUF = 0x0004000f, - VCMSG_SET_CURSOR_INFO = 0x00008010, - VCMSG_SET_CURSOR_STATE = 0x00008011, - }; -From f12bdfa033dd3c639b037c3acefc6df99e51936d Mon Sep 17 00:00:00 2001 +From 484967db8542a54000019550f8e45266b9d49a67 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 070/204] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 080/113] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use optimised memcpy/memmove/memcmp/memset implementations. + +arch/arm: Add mmiocpy/set aliases for memcpy/set + +See: https://github.com/raspberrypi/linux/issues/1082 --- arch/arm/include/asm/string.h | 5 + - arch/arm/include/asm/uaccess.h | 1 + + arch/arm/include/asm/uaccess.h | 3 + arch/arm/lib/Makefile | 15 +- arch/arm/lib/arm-mem.h | 159 ++++++++++++ arch/arm/lib/copy_from_user.S | 4 +- arch/arm/lib/exports_rpi.c | 37 +++ arch/arm/lib/memcmp_rpi.S | 285 +++++++++++++++++++++ - arch/arm/lib/memcpy_rpi.S | 59 +++++ + arch/arm/lib/memcpy_rpi.S | 61 +++++ arch/arm/lib/memcpymove.h | 506 +++++++++++++++++++++++++++++++++++++ arch/arm/lib/memmove_rpi.S | 61 +++++ - arch/arm/lib/memset_rpi.S | 121 +++++++++ + arch/arm/lib/memset_rpi.S | 123 +++++++++ arch/arm/lib/uaccess_with_memcpy.c | 112 +++++++- - 12 files changed, 1359 insertions(+), 6 deletions(-) + 12 files changed, 1365 insertions(+), 6 deletions(-) create mode 100644 arch/arm/lib/arm-mem.h create mode 100644 arch/arm/lib/exports_rpi.c create mode 100644 arch/arm/lib/memcmp_rpi.S @@ -132302,17 +132670,19 @@ index cf4f3aa..9fe7780 100644 #define memset(p,v,n) \ diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h -index 74b17d0..f4ad0a1 100644 +index 8cc85a4..21ec2fc 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h -@@ -475,6 +475,7 @@ do { \ +@@ -493,6 +493,9 @@ do { \ + extern unsigned long __must_check + arm_copy_from_user(void *to, const void __user *from, unsigned long n); - #ifdef CONFIG_MMU - extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); -+extern unsigned long __must_check __copy_from_user_std(void *to, const void __user *from, unsigned long n); - extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); - extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n); - extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); ++extern unsigned long __must_check ++__copy_from_user_std(void *to, const void __user *from, unsigned long n); ++ + static inline unsigned long __must_check + __copy_from_user(void *to, const void __user *from, unsigned long n) + { diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d8a7807..9c7dc5b 100644 --- a/arch/arm/lib/Makefile @@ -132512,20 +132882,20 @@ index 0000000..5d4bda1 +92: +.endm diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S -index 7a235b9..8aff879 100644 +index 1512beb..3da60dd 100644 --- a/arch/arm/lib/copy_from_user.S +++ b/arch/arm/lib/copy_from_user.S @@ -89,11 +89,13 @@ .text --ENTRY(__copy_from_user) +-ENTRY(arm_copy_from_user) +ENTRY(__copy_from_user_std) -+WEAK(__copy_from_user) ++WEAK(arm_copy_from_user) #include "copy_template.S" - ENDPROC(__copy_from_user) + ENDPROC(arm_copy_from_user) +ENDPROC(__copy_from_user_std) .pushsection .fixup,"ax" @@ -132866,10 +133236,10 @@ index 0000000..bf6e4ed +ENDPROC(memcmp) diff --git a/arch/arm/lib/memcpy_rpi.S b/arch/arm/lib/memcpy_rpi.S new file mode 100644 -index 0000000..15ff2bd +index 0000000..30f8a90 --- /dev/null +++ b/arch/arm/lib/memcpy_rpi.S -@@ -0,0 +1,59 @@ +@@ -0,0 +1,61 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd @@ -132926,9 +133296,11 @@ index 0000000..15ff2bd + +.set prefetch_distance, 3 + ++ENTRY(mmiocpy) +ENTRY(memcpy) + memcpy 0 +ENDPROC(memcpy) ++ENDPROC(mmiocpy) diff --git a/arch/arm/lib/memcpymove.h b/arch/arm/lib/memcpymove.h new file mode 100644 index 0000000..d8be584 @@ -133510,10 +133882,10 @@ index 0000000..8b0760c +ENDPROC(memmove) diff --git a/arch/arm/lib/memset_rpi.S b/arch/arm/lib/memset_rpi.S new file mode 100644 -index 0000000..2cde883 +index 0000000..7067415 --- /dev/null +++ b/arch/arm/lib/memset_rpi.S -@@ -0,0 +1,121 @@ +@@ -0,0 +1,123 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd @@ -133566,6 +133938,7 @@ index 0000000..2cde883 + * On exit: + * a1 preserved + */ ++ENTRY(mmioset) +ENTRY(memset) + S .req a1 + DAT0 .req a2 @@ -133635,8 +134008,9 @@ index 0000000..2cde883 + .unreq DAT2 + .unreq DAT3 +ENDPROC(memset) ++ENDPROC(mmioset) diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c -index 3e58d71..0622891 100644 +index d72b909..a6d8276 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -22,6 +22,14 @@ @@ -133753,9 +134127,9 @@ index 3e58d71..0622891 100644 +} + unsigned long - __copy_to_user(void __user *to, const void *from, unsigned long n) + arm_copy_to_user(void __user *to, const void *from, unsigned long n) { -@@ -145,10 +238,25 @@ __copy_to_user(void __user *to, const void *from, unsigned long n) +@@ -145,10 +238,25 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) * With frame pointer disabled, tail call optimization kicks in * as well making this test almost invisible. */ @@ -133765,8 +134139,8 @@ index 3e58d71..0622891 100644 return __copy_to_user_memcpy(to, from, n); } + -+unsigned long -+__copy_from_user(void *to, const void __user *from, unsigned long n) ++unsigned long __must_check ++arm_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + /* + * This test is stubbed out of the main function above to keep @@ -133783,67 +134157,10 @@ index 3e58d71..0622891 100644 static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From b52da83347f05007471699518545f3c8827d762a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 27 May 2015 17:22:15 +0100 -Subject: [PATCH 071/204] bcm2835-audio: Create the platform device if the DT - node is disabled - -For backwards compatibility, allow the built-in ALSA driver to be enabled -either by loading the module from /etc/modules or by enabling the "/audio" -node in DT. ---- - arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- - 2 files changed, 16 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5527d5c..937c2d3 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -898,8 +898,14 @@ void __init bcm2708_init(void) - #endif - bcm2708_init_led(); - bcm2708_init_uart1(); -- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ -+ /* Only create the platform devices for the ALSA driver in the -+ absence of an enabled "audio" DT node */ -+ if (!use_dt || -+ !of_device_is_available(of_find_node_by_path("/audio"))) { -+ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); -+ } - - bcm_register_device_dt(&bcm2708_spi_device); - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 4a00561..dec8043 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -918,8 +918,14 @@ void __init bcm2709_init(void) - #endif - bcm2709_init_led(); - bcm2709_init_uart1(); -- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ -+ /* Only create the platform devices for the ALSA driver in the -+ absence of an enabled "audio" DT node */ -+ if (!use_dt || -+ !of_device_is_available(of_find_node_by_path("/audio"))) { -+ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); -+ } - - bcm_register_device_dt(&bcm2708_spi_device); - - -From 1b9a56248747ddcba15df7f60cf739eea2977349 Mon Sep 17 00:00:00 2001 +From 8da3450f9b95ba374f1458c9b920ee94e2cac869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 072/204] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 081/113] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -133868,10 +134185,10 @@ Signed-off-by: Noralf Trønnes 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c -index 70f2f39..f7fdacd 100644 +index 0f7b9ea..1e6f1cf9 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c -@@ -18,6 +18,7 @@ +@@ -17,12 +17,16 @@ #include #include #include @@ -133879,7 +134196,6 @@ index 70f2f39..f7fdacd 100644 #include #include -@@ -107,6 +108,9 @@ static void __init bcm2835_map_io(void) static void __init bcm2835_init(void) { @@ -133888,8 +134204,8 @@ index 70f2f39..f7fdacd 100644 + u64 val64; int ret; - bcm2835_setup_restart(); -@@ -121,6 +125,11 @@ static void __init bcm2835_init(void) + bcm2835_init_clocks(); +@@ -33,6 +37,11 @@ static void __init bcm2835_init(void) pr_err("of_platform_populate failed: %d\n", ret); BUG(); } @@ -133902,10 +134218,10 @@ index 70f2f39..f7fdacd 100644 static const char * const bcm2835_compat[] = { -From 6c1d2a6d20e29c2fb1809297925045701d8a4a2a Mon Sep 17 00:00:00 2001 +From 7684b7ce5c5c05c123d66d06b565a17326b19c42 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 16 Jun 2015 17:47:27 +0100 -Subject: [PATCH 073/204] platform: Add force_core command line setting to boot +Subject: [PATCH 082/113] platform: Add force_core command line setting to boot from a different core number --- @@ -133914,7 +134230,7 @@ Subject: [PATCH 073/204] platform: Add force_core command line setting to boot 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c -index a366275..90805a6 100644 +index c6f68b4..fb82f7d 100644 --- a/arch/arm/mach-bcm2709/armctrl.c +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -45,6 +45,8 @@ static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { @@ -133956,7 +134272,7 @@ index a366275..90805a6 100644 writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); } else if (d->irq == INTERRUPT_ARM_LOCAL_PMU_FAST) { diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index dec8043..fe71c50 100644 +index ea3b689..ad4993f5 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -96,6 +96,7 @@ static unsigned w1_gpio_pin = W1_GPIO; @@ -133967,7 +134283,7 @@ index dec8043..fe71c50 100644 static unsigned use_dt = 0; -@@ -1305,6 +1306,7 @@ MACHINE_START(BCM2708, "BCM2709") +@@ -1290,6 +1291,7 @@ MACHINE_START(BCM2708, "BCM2709") .dt_compat = bcm2709_compat, MACHINE_END @@ -133976,20 +134292,20 @@ index dec8043..fe71c50 100644 module_param(serial, uint, 0644); module_param(uart_clock, uint, 0644); -From fbedbf309c2ee139e3eace31eb388fc0c8c75301 Mon Sep 17 00:00:00 2001 +From 9a2d16a38a17ceb644ffaf913c75ffca38958c2e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 18 Jun 2015 17:46:17 +0100 -Subject: [PATCH 074/204] mach-bcm270x: Enable the building of pinctrl-bcm2835 +Subject: [PATCH 083/113] mach-bcm270x: Enable the building of pinctrl-bcm2835 --- drivers/pinctrl/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 6eadf04..9119513 100644 +index cad077c..26b0bb4 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile -@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o +@@ -39,6 +39,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o @@ -133998,2113 +134314,10 @@ index 6eadf04..9119513 100644 obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-y += freescale/ -From 697b347118f88f65839dbf93dfc583b06407e791 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 19 Jun 2015 16:41:39 +0100 -Subject: [PATCH 075/204] BCM270X_DT: Document the i2s-mmap overlay - ---- - arch/arm/boot/dts/overlays/README | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 3e08f98..7fa6d33 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -260,6 +260,12 @@ Params: ds1307 Select the DS1307 device - pcf8563 Select the PCF8563 device - - -+Name: i2s-mmap -+Info: Enables mmap support in the bcm2708-i2s driver -+Load: dtoverlay=i2s-mmap -+Params: -+ -+ - Name: iqaudio-dac - Info: Configures the IQaudio DAC audio card - Load: dtoverlay=iqaudio-dac - -From 459023e570ec920d21cf3d01988a595f9027c87c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 17 Jun 2015 11:36:53 +0100 -Subject: [PATCH 076/204] bcm2835-sdhost: Improve error handling and recovery - -1) Expose the hw_reset method to the MMC framework, removing many - internal calls by the driver. - -2) Reduce overclock setting on error. - -3) Increase timeout to cope with high capacity cards. - -4) Add properties and parameters to control pio_limit and debug. - -5) Reduce messages at probe time. ---- - arch/arm/boot/dts/overlays/README | 8 +- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 4 +- - drivers/mmc/host/bcm2835-sdhost.c | 578 ++++++++++++++++++-------- - 3 files changed, 404 insertions(+), 186 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7fa6d33..63da266 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -408,7 +408,13 @@ Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock - Load: dtoverlay=sdhost,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz -- force_pio Disable DMA support -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 2) -+ -+ debug Enable debug output (default off) - - - Name: spi-bcm2708 -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index 8fb28e9..b408ab4 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -22,6 +22,7 @@ - dma-names = "tx", "rx"; - brcm,delay-after-stop = <0>; - brcm,overclock-50 = <0>; -+ brcm,pio-limit = <2>; - status = "okay"; - }; - }; -@@ -70,9 +71,10 @@ - }; - - __overrides__ { -- delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; - overclock_50 = <&sdhost>,"brcm,overclock-50:0"; - force_pio = <&sdhost>,"brcm,force-pio?"; -+ pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ debug = <&sdhost>,"brcm,debug?"; - sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - }; - }; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index eef8a24..6277e43 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -90,9 +90,8 @@ - /* Reserved */ - #define SDHSTS_DATA_FLAG 0x01 - --#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) -+#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) - #define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) --/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ - - #define SDHCFG_BUSY_IRPT_EN (1<<10) - #define SDHCFG_BLOCK_IRPT_EN (1<<8) -@@ -111,16 +110,7 @@ - #define SDEDM_READ_THRESHOLD_SHIFT 14 - #define SDEDM_THRESHOLD_MASK 0x1f - --/* the inclusive limit in bytes under which PIO will be used instead of DMA */ --#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER --#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER --#else --#define PIO_DMA_BARRIER 0 --#endif -- --#define MIN_FREQ 400000 --#define TIMEOUT_VAL 0xE --#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) -+#define MHZ 1000000 - - #ifndef BCM2708_PERI_BASE - #define BCM2708_PERI_BASE 0x20000000 -@@ -138,19 +128,20 @@ struct bcm2835_host { - - struct mmc_host *mmc; - -- u32 timeout; -+ u32 pio_timeout; /* In jiffies */ - - int clock; /* Current clock speed */ - - bool slow_card; /* Force 11-bit divisor */ - - unsigned int max_clk; /* Max possible freq */ -- unsigned int timeout_clk; /* Timeout freq (KHz) */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - - struct timer_list timer; /* Timer for timeouts */ - -+ struct timer_list pio_timer; /* PIO error detection timer */ -+ - struct sg_mapping_iter sg_miter; /* SG state for PIO */ - unsigned int blocks; /* remaining PIO blocks */ - -@@ -170,6 +161,10 @@ struct bcm2835_host { - - unsigned int use_busy:1; /* Wait for busy interrupt */ - -+ unsigned int reduce_overclock:1; /* ...at the next opportunity */ -+ -+ unsigned int debug:1; /* Enable debug output */ -+ - u32 thread_isr; - - /*DMA part*/ -@@ -185,7 +180,8 @@ struct bcm2835_host { - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -- u32 max_overclock; /* Highest reported */ -+ u32 overclock; /* Current frequency if overclocked, else zero */ -+ u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - }; - - -@@ -204,41 +200,79 @@ static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg - return readl_relaxed(host->ioaddr + reg); - } - -+static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, -+ struct mmc_command *cmd, -+ const char *label) -+{ -+ if (cmd) -+ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", -+ mmc_hostname(host->mmc), -+ (cmd == host->cmd) ? '>' : ' ', -+ label, cmd->opcode, cmd->arg, cmd->flags, -+ cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], -+ cmd->error); -+} -+ - static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) - { -- pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", -+ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -+ if (host->mrq->data) -+ pr_err("%s: data blocks %x blksz %x - err %d\n", -+ mmc_hostname(host->mmc), -+ host->mrq->data->blocks, -+ host->mrq->data->blksz, -+ host->mrq->data->error); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); -+ -+ pr_info("%s: =========== REGISTER DUMP ===========\n", - mmc_hostname(host->mmc)); - -- pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", -+ pr_info("%s: SDCMD 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCMD)); -- pr_info(DRIVER_NAME ": SDARG 0x%08x\n", -+ pr_info("%s: SDARG 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDARG)); -- pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", -+ pr_info("%s: SDTOUT 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDTOUT)); -- pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", -+ pr_info("%s: SDCDIV 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCDIV)); -- pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", -+ pr_info("%s: SDRSP0 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP0)); -- pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", -+ pr_info("%s: SDRSP1 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP1)); -- pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", -+ pr_info("%s: SDRSP2 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP2)); -- pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", -+ pr_info("%s: SDRSP3 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP3)); -- pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", -+ pr_info("%s: SDHSTS 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHSTS)); -- pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", -+ pr_info("%s: SDVDD 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDVDD)); -- pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", -+ pr_info("%s: SDEDM 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDEDM)); -- pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", -+ pr_info("%s: SDHCFG 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHCFG)); -- pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", -+ pr_info("%s: SDHBCT 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBCT)); -- pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", -+ pr_info("%s: SDHBLC 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBLC)); - -- pr_debug(DRIVER_NAME ": ===========================================\n"); -+ pr_info("%s: ===========================================\n", -+ mmc_hostname(host->mmc)); - } - - -@@ -248,12 +282,10 @@ static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) - } - - --static void bcm2835_sdhost_reset(struct bcm2835_host *host) -+static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - { - u32 temp; - -- pr_debug("bcm2835_sdhost_reset\n"); -- - bcm2835_sdhost_set_power(host, false); - - bcm2835_sdhost_write(host, 0, SDCMD); -@@ -281,6 +313,20 @@ static void bcm2835_sdhost_reset(struct bcm2835_host *host) - mmiowb(); - } - -+ -+static void bcm2835_sdhost_reset(struct mmc_host *mmc) -+{ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ if (host->debug) -+ pr_info("%s: reset\n", mmc_hostname(mmc)); -+ spin_lock_irqsave(&host->lock, flags); -+ -+ bcm2835_sdhost_reset_internal(host); -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - - static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) -@@ -290,7 +336,7 @@ static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) - /* Set interrupt enables */ - host->hcfg = SDHCFG_BUSY_IRPT_EN; - -- bcm2835_sdhost_reset(host); -+ bcm2835_sdhost_reset_internal(host); - - if (soft) { - /* force clock reconfiguration */ -@@ -420,6 +466,40 @@ static void bcm2835_sdhost_dma_complete(void *param) - spin_unlock_irqrestore(&host->lock, flags); - } - -+static bool data_transfer_wait(struct bcm2835_host *host, const char *caller) -+{ -+ unsigned long timeout = 1000000; -+ u32 hsts; -+ while (timeout) -+ { -+ hsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (hsts & (SDHSTS_TRANSFER_ERROR_MASK | -+ SDHSTS_DATA_FLAG)) { -+ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -+ SDHSTS); -+ break; -+ } -+ timeout--; -+ } -+ -+ if (hsts & (SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) { -+ pr_err("%s: data error in %s - HSTS %x\n", -+ mmc_hostname(host->mmc), caller, hsts); -+ host->data->error = -EILSEQ; -+ return false; -+ } else if ((timeout == 0) || -+ (hsts & (SDHSTS_CMD_TIME_OUT | -+ SDHSTS_REW_TIME_OUT))) { -+ pr_err("%s: timeout in %s - HSTS %x\n", -+ mmc_hostname(host->mmc), caller, hsts); -+ host->data->error = -ETIMEDOUT; -+ return false; -+ } -+ return true; -+} -+ - static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - { - unsigned long flags; -@@ -443,35 +523,15 @@ static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - buf = (u32 *)host->sg_miter.addr; - - while (len) { -- while (1) { -- u32 hsts; -- hsts = bcm2835_sdhost_read(host, SDHSTS); -- if (hsts & SDHSTS_DATA_FLAG) -- break; -- -- if (hsts & SDHSTS_ERROR_MASK) { -- pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", -- mmc_hostname(host->mmc), -- hsts, -- bcm2835_sdhost_read(host, SDHBCT), -- blksize + len); -- if (hsts & SDHSTS_REW_TIME_OUT) -- host->data->error = -ETIMEDOUT; -- else if (hsts & (SDHSTS_CRC16_ERROR || -- SDHSTS_CRC7_ERROR)) -- host->data->error = -EILSEQ; -- else { -- pr_err("%s: unexpected data error\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -- } -- } -- } -+ if (!data_transfer_wait(host, "read_block_pio")) -+ break; - - *(buf++) = bcm2835_sdhost_read(host, SDDATA); - len -= 4; - } -+ -+ if (host->data->error) -+ break; - } - - sg_miter_stop(&host->sg_miter); -@@ -502,11 +562,15 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - buf = host->sg_miter.addr; - - while (len) { -- while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) -- continue; -+ if (!data_transfer_wait(host, "write_block_pio")) -+ break; -+ - bcm2835_sdhost_write(host, *(buf++), SDDATA); - len -= 4; - } -+ -+ if (host->data->error) -+ break; - } - - sg_miter_stop(&host->sg_miter); -@@ -519,10 +583,15 @@ static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - { - BUG_ON(!host->data); - -- if (host->data->flags & MMC_DATA_READ) -+ if (host->data->flags & MMC_DATA_READ) { - bcm2835_sdhost_read_block_pio(host); -- else -+ } else { - bcm2835_sdhost_write_block_pio(host); -+ -+ /* Start a timer in case a transfer error occurs because -+ there is no error interrupt */ -+ mod_timer(&host->pio_timer, jiffies + host->pio_timeout); -+ } - } - - -@@ -607,6 +676,7 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -+ host->use_dma = host->have_dma && (data->blocks > host->pio_limit); - if (!host->use_dma) { - int flags; - -@@ -619,8 +689,6 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->blocks = data->blocks; - } - -- host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; -- - bcm2835_sdhost_set_transfer_irqs(host); - - bcm2835_sdhost_write(host, data->blksz, SDHBCT); -@@ -638,22 +706,25 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - - WARN_ON(host->cmd); - -- if (1) { -- pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", -- cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); -- if (cmd->data) -- pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", -- (cmd->data->flags & MMC_DATA_READ) ? -- "read" : "write", cmd->data->blocks, -- cmd->data->blksz); -- } -+ if (cmd->data) -+ pr_debug("%s: send_command %d 0x%x " -+ "(flags 0x%x) - %s %d*%d\n", -+ mmc_hostname(host->mmc), -+ cmd->opcode, cmd->arg, cmd->flags, -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ else -+ pr_debug("%s: send_command %d 0x%x (flags 0x%x)\n", -+ mmc_hostname(host->mmc), -+ cmd->opcode, cmd->arg, cmd->flags); - - /* Wait max 10 ms */ - timeout = 1000; - - while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { - if (timeout == 0) { -- pr_err("%s: Previous command never completed.\n", -+ pr_err("%s: previous command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - cmd->error = -EIO; -@@ -666,16 +737,16 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - - if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { - host->max_delay = (1000-timeout)/100; -- pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); -+ pr_warning("%s: controller hung for %d ms\n", -+ mmc_hostname(host->mmc), -+ host->max_delay); - } - - timeout = jiffies; --#ifdef CONFIG_ARCH_BCM2835 - if (!cmd->data && cmd->busy_timeout > 9000) - timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; - else --#endif -- timeout += 10 * HZ; -+ timeout += 10 * HZ; - mod_timer(&host->timer, timeout); - - host->cmd = cmd; -@@ -685,7 +756,7 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - bcm2835_sdhost_write(host, cmd->arg, SDARG); - - if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { -- pr_err("%s: Unsupported response type!\n", -+ pr_err("%s: unsupported response type!\n", - mmc_hostname(host->mmc)); - cmd->error = -EINVAL; - tasklet_schedule(&host->finish_tasklet); -@@ -783,13 +854,6 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - pr_debug("transfer_complete(error %d, stop %d)\n", - data->error, data->stop ? 1 : 0); - -- if (data->error) -- /* -- * The controller needs a reset of internal state machines -- * upon error conditions. -- */ -- bcm2835_sdhost_reset(host); -- - /* - * Need to send CMD12 if - - * a) open-ended multiblock transfer (no CMD23) -@@ -845,7 +909,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - #endif - - if (timeout == 0) { -- pr_err("%s: Command never completed.\n", -+ pr_err("%s: command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - host->cmd->error = -EIO; -@@ -875,14 +939,23 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - { - u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); - -- pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -- mmc_hostname(host->mmc), sdcmd, sdhsts, -- bcm2835_sdhost_read(host, SDEDM)); -- -- if (sdhsts & SDHSTS_CMD_TIME_OUT) -+ if (host->debug) -+ pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -+ mmc_hostname(host->mmc), sdcmd, sdhsts, -+ bcm2835_sdhost_read(host, SDEDM)); -+ -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) { -+ switch (host->cmd->opcode) { -+ case 5: case 52: case 53: -+ /* Don't warn about SDIO commands */ -+ break; -+ default: -+ pr_err("%s: command timeout\n", -+ mmc_hostname(host->mmc)); -+ break; -+ } - host->cmd->error = -ETIMEDOUT; -- else -- { -+ } else { - pr_err("%s: unexpected command error\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); -@@ -897,11 +970,13 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - int i; - for (i = 0; i < 4; i++) - host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); -- pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", -+ pr_debug("%s: finish_command %08x %08x %08x %08x\n", -+ mmc_hostname(host->mmc), - host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); - } else { - host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); -- pr_debug("bcm2835_sdhost_finish_command: %08x\n", -+ pr_debug("%s: finish_command %08x\n", -+ mmc_hostname(host->mmc), - host->cmd->resp[0]); - } - } -@@ -932,7 +1007,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - } - } - --static void bcm2835_sdhost_timeout_timer(unsigned long data) -+static void bcm2835_sdhost_timeout(unsigned long data) - { - struct bcm2835_host *host; - unsigned long flags; -@@ -942,7 +1017,7 @@ static void bcm2835_sdhost_timeout_timer(unsigned long data) - spin_lock_irqsave(&host->lock, flags); - - if (host->mrq) { -- pr_err("%s: Timeout waiting for hardware interrupt.\n", -+ pr_err("%s: timeout waiting for hardware interrupt.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - -@@ -964,6 +1039,41 @@ static void bcm2835_sdhost_timeout_timer(unsigned long data) - spin_unlock_irqrestore(&host->lock, flags); - } - -+static void bcm2835_sdhost_pio_timeout(unsigned long data) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ host = (struct bcm2835_host *)data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->data) { -+ u32 hsts = bcm2835_sdhost_read(host, SDHSTS); -+ -+ if (hsts & SDHSTS_REW_TIME_OUT) { -+ pr_err("%s: transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); -+ } else { -+ pr_err("%s: unexpected transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -+ SDHSTS); -+ -+ host->data->error = -ETIMEDOUT; -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ - static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) - { - if (enable) -@@ -979,7 +1089,7 @@ static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; - -- pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); -+ pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); - spin_lock_irqsave(&host->lock, flags); - bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); - spin_unlock_irqrestore(&host->lock, flags); -@@ -987,11 +1097,12 @@ static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) - - static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - { -- const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | -+ SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR); - - if (!host->cmd) { -- pr_err("%s: Got command busy interrupt 0x%08x even " -+ pr_err("%s: got command busy interrupt 0x%08x even " - "though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -@@ -999,7 +1110,7 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - } - - if (!host->use_busy) { -- pr_err("%s: Got command busy interrupt 0x%08x even " -+ pr_err("%s: got command busy interrupt 0x%08x even " - "though not expecting one.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -@@ -1007,14 +1118,28 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - } - host->use_busy = 0; - -- if (intmask & SDHSTS_CMD_TIME_OUT) -- host->cmd->error = -ETIMEDOUT; -- else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -- SDHSTS_FIFO_ERROR)) -- host->cmd->error = -EILSEQ; -+ if (intmask & SDHSTS_ERROR_MASK) -+ { -+ pr_err("sdhost_busy_irq: intmask %x, data %p\n", intmask, host->mrq->data); -+ if (intmask & SDHSTS_CRC7_ERROR) -+ host->cmd->error = -EILSEQ; -+ else if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR)) { -+ if (host->mrq->data) -+ host->mrq->data->error = -EILSEQ; -+ else -+ host->cmd->error = -EILSEQ; -+ } else if (intmask & SDHSTS_REW_TIME_OUT) { -+ if (host->mrq->data) -+ host->mrq->data->error = -ETIMEDOUT; -+ else -+ host->cmd->error = -ETIMEDOUT; -+ } else if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; - -- if (host->cmd->error) -+ bcm2835_sdhost_dumpregs(host); - tasklet_schedule(&host->finish_tasklet); -+ } - else - bcm2835_sdhost_finish_command(host); - -@@ -1023,8 +1148,9 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - - static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - { -- const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); - - /* There are no dedicated data/space available interrupt - status bits, so it is necessary to use the single shared -@@ -1034,13 +1160,19 @@ static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - if (!host->data) - return 0; - -- // XXX FIFO_ERROR -- if (intmask & SDHSTS_CMD_TIME_OUT) -- host->cmd->error = -ETIMEDOUT; -- else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -- ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -- != MMC_BUS_TEST_R)) -- host->cmd->error = -EILSEQ; -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR | -+ SDHSTS_REW_TIME_OUT)) { -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->data->error = -EILSEQ; -+ else -+ host->data->error = -ETIMEDOUT; -+ -+ bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; -+ } - - /* Use the block interrupt for writes after the first block */ - if (host->data->flags & MMC_DATA_WRITE) { -@@ -1067,31 +1199,48 @@ static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - { - struct dma_chan *dma_chan; - u32 dir_data; -- const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); - - if (!host->data) { -- pr_err("%s: Got block interrupt 0x%08x even " -+ pr_err("%s: got block interrupt 0x%08x even " - "though no data operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); - return handled; - } - -- if (intmask & SDHSTS_CMD_TIME_OUT) -- host->cmd->error = -ETIMEDOUT; -- else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -- ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -- != MMC_BUS_TEST_R)) -- host->cmd->error = -EILSEQ; -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR | -+ SDHSTS_REW_TIME_OUT)) { -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->data->error = -EILSEQ; -+ else -+ host->data->error = -ETIMEDOUT; -+ -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; -+ } - - if (!host->use_dma) { - BUG_ON(!host->blocks); - host->blocks--; -- if ((host->blocks == 0) || host->data->error) -+ if ((host->blocks == 0) || host->data->error) { -+ /* Cancel the timer */ -+ del_timer(&host->pio_timer); -+ - bcm2835_sdhost_finish_data(host); -- else -+ } else { - bcm2835_sdhost_transfer_pio(host); -+ -+ /* Reset the timer */ -+ mod_timer(&host->pio_timer, -+ jiffies + host->pio_timeout); -+ } - } else if (host->data->flags & MMC_DATA_WRITE) { - dma_chan = host->dma_chan_tx; - dir_data = DMA_TO_DEVICE; -@@ -1125,7 +1274,7 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - SDHSTS_BLOCK_IRPT | - SDHSTS_SDIO_IRPT | - SDHSTS_DATA_FLAG); -- if ((handled == SDHSTS_DATA_FLAG) && // XXX -+ if ((handled == SDHSTS_DATA_FLAG) && - (loops == 0) && !host->data) { - pr_err("%s: sdhost_irq data interrupt 0x%08x even " - "though no data operation was in progress.\n", -@@ -1177,10 +1326,11 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - spin_unlock(&host->lock); - - if (early) -- pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); -+ pr_debug("%s: early %x (loops %d)\n", -+ mmc_hostname(host->mmc), early, loops); - - if (unexpected) { -- pr_err("%s: Unexpected interrupt 0x%08x.\n", -+ pr_err("%s: unexpected interrupt 0x%08x.\n", - mmc_hostname(host->mmc), unexpected); - bcm2835_sdhost_dumpregs(host); - } -@@ -1227,8 +1377,22 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - int div = 0; /* Initialized for compiler warning */ - unsigned int input_clock = clock; - -- if (host->overclock_50 && (clock == 50000000)) -- clock = host->overclock_50 * 1000000 + 999999; -+ if (host->debug) -+ pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -+ -+ if ((clock == 0) && host->reduce_overclock) { -+ /* This is a reset following data corruption - reduce any -+ overclock */ -+ host->reduce_overclock = 0; -+ if (host->overclock_50 > 50) { -+ pr_warn("%s: reducing overclock due to errors\n", -+ mmc_hostname(host->mmc)); -+ host->overclock_50--; -+ } -+ } -+ -+ if (host->overclock_50 && (clock == 50*MHZ)) -+ clock = host->overclock_50 * MHZ + (MHZ - 1); - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1275,17 +1439,34 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - -- if ((clock > input_clock) && (clock > host->max_overclock)) { -- pr_warn("%s: Overclocking to %dHz\n", -- mmc_hostname(host->mmc), clock); -- host->max_overclock = clock; -+ if (clock > input_clock) { -+ /* Save the closest value, to make it easier -+ to reduce in the event of error */ -+ host->overclock_50 = (clock/MHZ); -+ -+ if (clock != host->overclock) { -+ pr_warn("%s: overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); -+ host->overclock = clock; -+ } -+ } -+ else if ((clock == 50 * MHZ) && host->overclock) -+ { -+ pr_warn("%s: cancelling overclock\n", -+ mmc_hostname(host->mmc)); -+ host->overclock = 0; - } - - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -- input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); -+ -+ if (host->debug) -+ pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), input_clock, -+ host->max_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1293,29 +1474,32 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - struct bcm2835_host *host; - unsigned long flags; - -- if (1) { -+ host = mmc_priv(mmc); -+ -+ if (host->debug) { - struct mmc_command *cmd = mrq->cmd; -- const char *src = "cmd"; - BUG_ON(!cmd); -- pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", -- src, cmd->opcode, cmd->arg, cmd->flags); - if (cmd->data) -- pr_debug("bcm2835_sdhost_request: %s %d*%d\n", -- (cmd->data->flags & MMC_DATA_READ) ? -- "read" : "write", cmd->data->blocks, -- cmd->data->blksz); -+ pr_info("%s: cmd %d 0x%x (flags 0x%x) - %s %d*%d\n", -+ mmc_hostname(mmc), -+ cmd->opcode, cmd->arg, cmd->flags, -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ else -+ pr_info("%s: cmd %d 0x%x (flags 0x%x)\n", -+ mmc_hostname(mmc), -+ cmd->opcode, cmd->arg, cmd->flags); - } - - if (mrq->data && !is_power_of_2(mrq->data->blksz)) { -- pr_err("%s: Unsupported block size (%d bytes)\n", -+ pr_err("%s: unsupported block size (%d bytes)\n", - mmc_hostname(mmc), mrq->data->blksz); - mrq->cmd->error = -EINVAL; - mmc_request_done(mmc, mrq); - return; - } - -- host = mmc_priv(mmc); -- - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -@@ -1345,9 +1529,12 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; - -- pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -- ios->clock, ios->power_mode, ios->bus_width, -- ios->timing, ios->signal_voltage, ios->drv_type); -+ if (host->debug) -+ pr_info("%s: ios clock %d, pwr %d, bus_width %d, " -+ "timing %d, vdd %d, drv_type %d\n", -+ mmc_hostname(mmc), -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); - - spin_lock_irqsave(&host->lock, flags); - -@@ -1396,6 +1583,7 @@ static struct mmc_host_ops bcm2835_sdhost_ops = { - .request = bcm2835_sdhost_request, - .set_ios = bcm2835_sdhost_set_ios, - .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, -+ .hw_reset = bcm2835_sdhost_reset, - .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, - }; - -@@ -1423,15 +1611,24 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - mrq = host->mrq; - -- /* -- * The controller needs a reset of internal state machines -- * upon error conditions. -- */ -- if (((mrq->cmd && mrq->cmd->error) || -- (mrq->data && (mrq->data->error || -- (mrq->data->stop && mrq->data->stop->error))))) { -+ /* Drop the overclock after any data corruption, or after any -+ error overclocked */ -+ if (mrq->data && (mrq->data->error == -EILSEQ)) -+ host->reduce_overclock = 1; -+ else if (host->overclock) { -+ /* Convert timeout errors while overclocked to data errors, -+ because the system recovers better. */ -+ if (mrq->cmd && mrq->cmd->error) { -+ host->reduce_overclock = 1; -+ if (mrq->cmd->error == -ETIMEDOUT) -+ mrq->cmd->error = -EILSEQ; -+ } - -- bcm2835_sdhost_reset(host); -+ if (mrq->data && mrq->data->error) { -+ host->reduce_overclock = 1; -+ if (mrq->data->error == -ETIMEDOUT) -+ mrq->data->error = -EILSEQ; -+ } - } - - host->mrq = NULL; -@@ -1450,35 +1647,37 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - { - struct mmc_host *mmc; - struct dma_slave_config cfg; -+ char pio_limit_string[20]; - int ret; - - mmc = host->mmc; - -- bcm2835_sdhost_reset(host); -+ bcm2835_sdhost_reset_internal(host); - - mmc->f_max = host->max_clk; - mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; - -- /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ -- host->timeout_clk = mmc->f_max / 1000; --#ifdef CONFIG_ARCH_BCM2835 -- mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; --#endif -+ mmc->max_busy_timeout = (~(unsigned int)0)/(mmc->f_max/1000); -+ -+ pr_debug("f_max %d, f_min %d, max_busy_timeout %d\n", -+ mmc->f_max, mmc->f_min, mmc->max_busy_timeout); -+ - /* host controller capabilities */ - mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -- MMC_CAP_NEEDS_POLL | -+ MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | - (ALLOW_CMD23 * MMC_CAP_CMD23); - - spin_lock_init(&host->lock); - - if (host->allow_dma) { -- if (!host->dma_chan_tx || !host->dma_chan_rx || -- IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { -- pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); -+ if (IS_ERR_OR_NULL(host->dma_chan_tx) || -+ IS_ERR_OR_NULL(host->dma_chan_rx)) { -+ pr_err("%s: unable to initialise DMA channels. " -+ "Falling back to PIO\n", -+ mmc_hostname(mmc)); - host->have_dma = false; - } else { -- pr_info("DMA channels allocated for the SDHost driver"); - host->have_dma = true; - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -@@ -1496,7 +1695,6 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); - } - } else { -- pr_info("Forcing PIO mode\n"); - host->have_dma = false; - } - -@@ -1512,18 +1710,23 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - tasklet_init(&host->finish_tasklet, - bcm2835_sdhost_tasklet_finish, (unsigned long)host); - -- setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); -+ setup_timer(&host->timer, bcm2835_sdhost_timeout, -+ (unsigned long)host); -+ -+ setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, -+ (unsigned long)host); - - bcm2835_sdhost_init(host, 0); - #ifndef CONFIG_ARCH_BCM2835 - ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, - mmc_hostname(mmc), host); - #else -- ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, -+ bcm2835_sdhost_thread_irq, - IRQF_SHARED, mmc_hostname(mmc), host); - #endif - if (ret) { -- pr_err("%s: Failed to request IRQ %d: %d\n", -+ pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); - goto untasklet; - } -@@ -1531,10 +1734,13 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - mmiowb(); - mmc_add_host(mmc); - -- pr_info("Load BCM2835 SDHost driver\n"); -- if (host->delay_after_stop) -- pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", -- host->delay_after_stop); -+ pio_limit_string[0] = '\0'; -+ if (host->have_dma && (host->pio_limit > 0)) -+ sprintf(pio_limit_string, " (>%d)", host->pio_limit); -+ pr_info("%s: %s loaded - DMA %s%s\n", -+ mmc_hostname(mmc), DRIVER_NAME, -+ host->have_dma ? "enabled" : "disabled", -+ pio_limit_string); - - return 0; - -@@ -1562,7 +1768,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - mmc->ops = &bcm2835_sdhost_ops; - host = mmc_priv(mmc); - host->mmc = mmc; -- host->timeout = msecs_to_jiffies(1000); -+ host->pio_timeout = msecs_to_jiffies(500); - spin_lock_init(&host->lock); - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -1588,8 +1794,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - of_property_read_u32(node, - "brcm,overclock-50", - &host->overclock_50); -+ of_property_read_u32(node, -+ "brcm,pio-limit", -+ &host->pio_limit); - host->allow_dma = ALLOW_DMA && - !of_property_read_bool(node, "brcm,force-pio"); -+ host->debug = of_property_read_bool(node, "brcm,debug"); - } - - if (host->allow_dma) { - -From 1b37e961ff949769a09160dcc9567c47f8d093e6 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Jun 2015 13:11:46 -0700 -Subject: [PATCH 077/204] ARM: bcm2835: Add the Raspberry Pi firmware driver - -This gives us a function for making mailbox property channel requests -of the firmware, which is most notable in that it will let us get and -set clock rates. - -Signed-off-by: Eric Anholt ---- - drivers/firmware/Kconfig | 7 + - drivers/firmware/Makefile | 1 + - drivers/firmware/raspberrypi.c | 260 +++++++++++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 115 +++++++++++++ - 4 files changed, 383 insertions(+) - create mode 100644 drivers/firmware/raspberrypi.c - create mode 100644 include/soc/bcm2835/raspberrypi-firmware.h - -diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig -index 6517132..564aa5b 100644 ---- a/drivers/firmware/Kconfig -+++ b/drivers/firmware/Kconfig -@@ -136,6 +136,13 @@ config QCOM_SCM - bool - depends on ARM || ARM64 - -+config RASPBERRYPI_FIRMWARE -+ tristate "Raspberry Pi Firmware Driver" -+ depends on BCM2835_MBOX -+ help -+ This option enables support for communicating with the firmware on the -+ Raspberry Pi. -+ - source "drivers/firmware/google/Kconfig" - source "drivers/firmware/efi/Kconfig" - -diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile -index 3fdd391..ee101a2 100644 ---- a/drivers/firmware/Makefile -+++ b/drivers/firmware/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o - obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o - obj-$(CONFIG_QCOM_SCM) += qcom_scm.o - CFLAGS_qcom_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) -+obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o - - obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ - obj-$(CONFIG_EFI) += efi/ -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -new file mode 100644 -index 0000000..dd506cd3 ---- /dev/null -+++ b/drivers/firmware/raspberrypi.c -@@ -0,0 +1,260 @@ -+/* -+ * Defines interfaces for interacting wtih the Raspberry Pi firmware's -+ * property channel. -+ * -+ * Copyright © 2015 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_CHAN_PROPERTY 8 -+ -+struct rpi_firmware { -+ struct mbox_client cl; -+ struct mbox_chan *chan; /* The property channel. */ -+ struct completion c; -+ u32 enabled; -+}; -+ -+static DEFINE_MUTEX(transaction_lock); -+ -+static void response_callback(struct mbox_client *cl, void *msg) -+{ -+ struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); -+ complete(&fw->c); -+} -+ -+/* -+ * Sends a request to the firmware through the BCM2835 mailbox driver, -+ * and synchronously waits for the reply. -+ */ -+static int -+rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) -+{ -+ u32 message = MBOX_MSG(chan, data); -+ int ret; -+ -+ WARN_ON(data & 0xf); -+ -+ mutex_lock(&transaction_lock); -+ reinit_completion(&fw->c); -+ ret = mbox_send_message(fw->chan, &message); -+ if (ret >= 0) { -+ wait_for_completion(&fw->c); -+ ret = 0; -+ } else { -+ dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); -+ } -+ mutex_unlock(&transaction_lock); -+ -+ return ret; -+} -+ -+/** -+ * rpi_firmware_property_list - Submit firmware property list -+ * @fw: Pointer to firmware structure from rpi_firmware_get(). -+ * @data: Buffer holding tags. -+ * @tag_size: Size of tags buffer. -+ * -+ * Submits a set of concatenated tags to the VPU firmware through the -+ * mailbox property interface. -+ * -+ * The buffer header and the ending tag are added by this function and -+ * don't need to be supplied, just the actual tags for your operation. -+ * See struct rpi_firmware_property_tag_header for the per-tag -+ * structure. -+ */ -+int rpi_firmware_property_list(struct rpi_firmware *fw, -+ void *data, size_t tag_size) -+{ -+ size_t size = tag_size + 12; -+ u32 *buf; -+ dma_addr_t bus_addr; -+ int ret; -+ -+ /* Packets are processed a dword at a time. */ -+ if (size & 3) -+ return -EINVAL; -+ -+ buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, -+ GFP_ATOMIC); -+ if (!buf) -+ return -ENOMEM; -+ -+ /* The firmware will error out without parsing in this case. */ -+ WARN_ON(size >= 1024 * 1024); -+ -+ buf[0] = size; -+ buf[1] = RPI_FIRMWARE_STATUS_REQUEST; -+ memcpy(&buf[2], data, tag_size); -+ buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END; -+ wmb(); -+ -+ ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr); -+ -+ rmb(); -+ memcpy(data, &buf[2], tag_size); -+ if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) { -+ /* -+ * The tag name here might not be the one causing the -+ * error, if there were multiple tags in the request. -+ * But single-tag is the most common, so go with it. -+ */ -+ dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", -+ buf[2], buf[1]); -+ ret = -EINVAL; -+ } -+ -+ dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rpi_firmware_property_list); -+ -+/** -+ * rpi_firmware_property - Submit single firmware property -+ * @fw: Pointer to firmware structure from rpi_firmware_get(). -+ * @tag: One of enum_mbox_property_tag. -+ * @tag_data: Tag data buffer. -+ * @buf_size: Buffer size. -+ * -+ * Submits a single tag to the VPU firmware through the mailbox -+ * property interface. -+ * -+ * This is a convenience wrapper around -+ * rpi_firmware_property_list() to avoid some of the -+ * boilerplate in property calls. -+ */ -+int rpi_firmware_property(struct rpi_firmware *fw, -+ u32 tag, void *tag_data, size_t buf_size) -+{ -+ /* Single tags are very small (generally 8 bytes), so the -+ * stack should be safe. -+ */ -+ u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)]; -+ struct rpi_firmware_property_tag_header *header = -+ (struct rpi_firmware_property_tag_header *)data; -+ int ret; -+ -+ header->tag = tag; -+ header->buf_size = buf_size; -+ header->req_resp_size = 0; -+ memcpy(data + sizeof(struct rpi_firmware_property_tag_header), -+ tag_data, buf_size); -+ -+ ret = rpi_firmware_property_list(fw, &data, sizeof(data)); -+ memcpy(tag_data, -+ data + sizeof(struct rpi_firmware_property_tag_header), -+ buf_size); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rpi_firmware_property); -+ -+static void -+rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) -+{ -+ u32 packet; -+ int ret = rpi_firmware_property(fw, -+ RPI_FIRMWARE_GET_FIRMWARE_REVISION, -+ &packet, sizeof(packet)); -+ -+ if (ret == 0) { -+ struct tm tm; -+ -+ time_to_tm(packet, 0, &tm); -+ -+ dev_info(fw->cl.dev, -+ "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -+ tm.tm_hour, tm.tm_min); -+ } -+} -+ -+static int rpi_firmware_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct rpi_firmware *fw; -+ -+ fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); -+ if (!fw) -+ return -ENOMEM; -+ -+ fw->cl.dev = dev; -+ fw->cl.rx_callback = response_callback; -+ fw->cl.tx_block = true; -+ -+ fw->chan = mbox_request_channel(&fw->cl, 0); -+ if (IS_ERR(fw->chan)) { -+ int ret = PTR_ERR(fw->chan); -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "Failed to get mbox channel: %d\n", ret); -+ return ret; -+ } -+ -+ init_completion(&fw->c); -+ -+ platform_set_drvdata(pdev, fw); -+ -+ rpi_firmware_print_firmware_revision(fw); -+ -+ return 0; -+} -+ -+static int rpi_firmware_remove(struct platform_device *pdev) -+{ -+ struct rpi_firmware *fw = platform_get_drvdata(pdev); -+ -+ mbox_free_channel(fw->chan); -+ -+ return 0; -+} -+ -+/** -+ * rpi_firmware_get - Get pointer to rpi_firmware structure. -+ * @firmware_node: Pointer to the firmware Device Tree node. -+ * -+ * Returns NULL is the firmware device is not ready. -+ */ -+struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) -+{ -+ struct platform_device *pdev = of_find_device_by_node(firmware_node); -+ -+ if (!pdev) -+ return NULL; -+ -+ return platform_get_drvdata(pdev); -+} -+EXPORT_SYMBOL_GPL(rpi_firmware_get); -+ -+static const struct of_device_id rpi_firmware_of_match[] = { -+ { .compatible = "raspberrypi,bcm2835-firmware", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rpi_firmware_of_match); -+ -+static struct platform_driver rpi_firmware_driver = { -+ .driver = { -+ .name = "raspberrypi-firmware", -+ .of_match_table = rpi_firmware_of_match, -+ }, -+ .probe = rpi_firmware_probe, -+ .remove = rpi_firmware_remove, -+}; -+module_platform_driver(rpi_firmware_driver); -+ -+MODULE_AUTHOR("Eric Anholt "); -+MODULE_DESCRIPTION("Raspberry Pi firmware driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -new file mode 100644 -index 0000000..9d9efb7 ---- /dev/null -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -0,0 +1,115 @@ -+/* -+ * Copyright © 2015 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+struct rpi_firmware; -+ -+enum rpi_firmware_property_status { -+ RPI_FIRMWARE_STATUS_REQUEST = 0, -+ RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000, -+ RPI_FIRMWARE_STATUS_ERROR = 0x80000001, -+}; -+ -+/** -+ * struct rpi_firmware_property_tag_header - Firmware property tag header -+ * @tag: One of enum_mbox_property_tag. -+ * @buf_size: The number of bytes in the value buffer following this -+ * struct. -+ * @req_resp_size: On submit, the length of the request (though it doesn't -+ * appear to be currently used by the firmware). On return, -+ * the length of the response (always 4 byte aligned), with -+ * the low bit set. -+ */ -+struct rpi_firmware_property_tag_header { -+ u32 tag; -+ u32 buf_size; -+ u32 req_resp_size; -+}; -+ -+enum rpi_firmware_property_tag { -+ RPI_FIRMWARE_PROPERTY_END = 0, -+ RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, -+ -+ RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, -+ RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, -+ -+ RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, -+ RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, -+ RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, -+ RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, -+ RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, -+ RPI_FIRMWARE_GET_CLOCKS = 0x00010007, -+ RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, -+ RPI_FIRMWARE_GET_TIMING = 0x00020002, -+ RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, -+ RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, -+ RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, -+ RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, -+ RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, -+ RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, -+ RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, -+ RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, -+ RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, -+ RPI_FIRMWARE_GET_TURBO = 0x00030009, -+ RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, -+ RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, -+ RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, -+ RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, -+ RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, -+ RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, -+ RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, -+ RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, -+ RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, -+ RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, -+ RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, -+ RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, -+ RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, -+ RPI_FIRMWARE_SET_TURBO = 0x00038009, -+ -+ /* Dispmanx TAGS */ -+ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -+ RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, -+ RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, -+ -+ RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, -+ RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, -+}; -+ -+int rpi_firmware_property(struct rpi_firmware *fw, -+ u32 tag, void *data, size_t len); -+int rpi_firmware_property_list(struct rpi_firmware *fw, -+ void *data, size_t tag_size); -+struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); - -From 9666e309b64fbf73d945c934dc3e991e25218fba Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 22 Mar 2015 13:33:23 +0000 -Subject: [PATCH 078/204] config: Enable ZSMALLOC, ZRAM and PGTABLE_MAPPING - ---- - arch/arm/configs/bcm2709_defconfig | 4 ++++ - arch/arm/configs/bcmrpi_defconfig | 4 ++++ - 2 files changed, 8 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index a3067bf..7ef615c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -49,6 +49,8 @@ CONFIG_OABI_COMPAT=y - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y - CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y - CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y - CONFIG_ZBOOT_ROM_TEXT=0x0 -@@ -389,6 +391,8 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_CRYPTOLOOP=m - CONFIG_BLK_DEV_DRBD=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 6a41231..cacde14 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -44,6 +44,8 @@ CONFIG_OABI_COMPAT=y - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y - CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y - CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y - CONFIG_ZBOOT_ROM_TEXT=0x0 -@@ -382,6 +384,8 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_CRYPTOLOOP=m - CONFIG_BLK_DEV_DRBD=m - -From a767c3cb4c6604ad27b92a36644de098f8bdcabb Mon Sep 17 00:00:00 2001 -From: Gordon Hollingworth -Date: Mon, 22 Jun 2015 16:27:07 +0100 -Subject: [PATCH 079/204] Add rpi-ft5406 overlay Add rpi-ft5406 driver as - module - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 5 +++++ - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 16 ++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 24 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 6947556..19eef3c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -35,6 +35,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 63da266..aa09b6c 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -396,6 +396,11 @@ Params: speed Display SPI bus speed - - xohms Touchpanel sensitivity (X-plate resistance) - -+Name: rpi-ft5406 -+Info: Official Raspberry Pi display touchscreen -+Load: dtoverlay=rpi-ft5406 -+Params: -+ - - Name: rpi-proto - Info: Configures the RPi Proto audio card -diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -new file mode 100644 -index 0000000..40deab5 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -@@ -0,0 +1,16 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ rpi_ft5406: rpi_ft5406 { -+ compatible = "rpi,rpi-ft5406"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7ef615c..7469d07 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -535,6 +535,7 @@ CONFIG_JOYSTICK_XPAD_FF=y - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m - CONFIG_TOUCHSCREEN_STMPE=m - CONFIG_INPUT_MISC=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index cacde14..f952ff2 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -528,6 +528,7 @@ CONFIG_JOYSTICK_XPAD_FF=y - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m - CONFIG_TOUCHSCREEN_STMPE=m - CONFIG_INPUT_MISC=y - -From f13481ed18c0a520fc1776890d1066c1397b358f Mon Sep 17 00:00:00 2001 -From: Gordon Hollingworth -Date: Tue, 23 Jun 2015 09:53:40 +0100 -Subject: [PATCH 080/204] Fix driver detection failure Check that the buffer - response is non-zero meaning the touchscreen was detected - ---- - drivers/input/touchscreen/rpi-ft5406.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c -index f55151b..d41851d 100644 ---- a/drivers/input/touchscreen/rpi-ft5406.c -+++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -184,7 +184,7 @@ static int ft5406_probe(struct platform_device *pdev) - - bcm_mailbox_property(&request, sizeof(request)); - -- if(request.request_code == VCMSG_REQUEST_SUCCESSFUL) -+ if(request.request_code == VCMSG_REQUEST_SUCCESSFUL && request.tag.val != 0) - { - dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", request.tag.val); - } - -From 7b53303429e40fddef7ffeb405f898af16adf578 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 23 Jun 2015 13:24:01 +0100 -Subject: [PATCH 081/204] config: Enable 8250 serial port - ---- - arch/arm/configs/bcm2709_defconfig | 7 +++++++ - arch/arm/configs/bcmrpi_defconfig | 7 +++++++ - 2 files changed, 14 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7469d07..7e8643c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -557,8 +557,15 @@ CONFIG_GAMEPORT_L4=m - CONFIG_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=1 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_BCM2835=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index f952ff2..0c25d8b 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -550,8 +550,15 @@ CONFIG_GAMEPORT_L4=m - CONFIG_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=1 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_BCM2835=m - -From 1ae977a7312c852775ea4bd9da294d7010e42dff Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 23 Jun 2015 14:10:58 +0100 -Subject: [PATCH 082/204] config: Enable POWER_RESET_GPIO - ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7e8643c..46d56d7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -606,6 +606,8 @@ CONFIG_W1_SLAVE_DS2781=m - CONFIG_W1_SLAVE_DS28E04=m - CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0c25d8b..e757db6 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -599,6 +599,8 @@ CONFIG_W1_SLAVE_DS2781=m - CONFIG_W1_SLAVE_DS28E04=m - CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - -From 5c8ef44617382fa1fa35577714eb1d4e2e17b647 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 26 Jun 2015 17:37:38 +0100 -Subject: [PATCH 083/204] bcm2708-vcio: Remove restriction of only a single - instance being open - -We need more than one process to be able to use mailbox interface (e.g. HW cursor in fbturbo and hello_fft). -Locking should be handled on each mailbox access ---- - drivers/mailbox/bcm2708-vcio.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index d91672b..06fb2c2f 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -242,20 +242,9 @@ EXPORT_SYMBOL_GPL(bcm_mailbox_property); - - /* Platform Device for Mailbox */ - --/* -- * Is the device open right now? Used to prevent -- * concurent access into the same device -- */ --static bool device_is_open; -- - /* This is called whenever a process attempts to open the device file */ - static int device_open(struct inode *inode, struct file *file) - { -- /* We don't want to talk to two processes at the same time */ -- if (device_is_open) -- return -EBUSY; -- -- device_is_open = true; - try_module_get(THIS_MODULE); - - return 0; -@@ -263,9 +252,6 @@ static int device_open(struct inode *inode, struct file *file) - - static int device_release(struct inode *inode, struct file *file) - { -- /* We're now ready for our next caller */ -- device_is_open = false; -- - module_put(THIS_MODULE); - - return 0; - -From cc364b46f26d4d8fc925ab96616e2443f29a0a60 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 26 Jun 2015 08:39:19 +0100 -Subject: [PATCH 084/204] BCM270X_DT: Create a "core" clock, use it for SPI and - sdhost - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 6 +++--- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 28 ++------------------------- - 6 files changed, 9 insertions(+), 29 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 0fa2210..3b252dc 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -124,6 +124,7 @@ - i2c1 = <&i2c1>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 3fd49d0..40fded1 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -118,6 +118,7 @@ - i2c1 = <&i2c1>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 238bd65..e82fcb2 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -14,5 +14,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 8caa234..4a975dfd 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -110,7 +110,7 @@ - compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; -- clocks = <&clk_spi>; -+ clocks = <&clk_core>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; -@@ -203,11 +203,11 @@ - clock-frequency = <250000000>; - }; - -- clk_spi: clock@2 { -+ clk_core: clock@2 { - compatible = "fixed-clock"; - reg = <2>; - #clock-cells = <0>; -- clock-output-names = "spi"; -+ clock-output-names = "core"; - clock-frequency = <250000000>; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 8aaaf1f..24fa849 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -124,6 +124,7 @@ - i2c1 = <&i2c1>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index b408ab4..897204a 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -16,7 +16,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&sdhost_pins>; - interrupts = <2 24>; -- clocks = <&clk_sdhost>; -+ clocks = <&clk_core>; - dmas = <&dma 13>, - <&dma 13>; - dma-names = "tx", "rx"; -@@ -29,22 +29,6 @@ - }; - - fragment@1 { -- target = <&clocks>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_sdhost: sdhost { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "sdhost"; -- clock-frequency = <250000000>; -- }; -- }; -- }; -- -- fragment@2 { - target = <&gpio>; - __overlay__ { - sdhost_pins: sdhost_pins { -@@ -54,7 +38,7 @@ - }; - }; - -- fragment@3 { -+ fragment@2 { - target = <&mmc>; - __overlay__ { - /* Find a way to disable the other driver */ -@@ -63,18 +47,10 @@ - }; - }; - -- fragment@4 { -- target-path = "/__overrides__"; -- __overlay__ { -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -- }; -- }; -- - __overrides__ { - overclock_50 = <&sdhost>,"brcm,overclock-50:0"; - force_pio = <&sdhost>,"brcm,force-pio?"; - pio_limit = <&sdhost>,"brcm,pio-limit:0"; - debug = <&sdhost>,"brcm,debug?"; -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - }; - }; - -From 18fdf653ca9b05f1e30a4e1cb6bb9320b6642ea9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 24 Jun 2015 09:24:31 +0100 -Subject: [PATCH 085/204] BCM270X_DT: Add MCP7941X to i2c-rtc overlay - ---- - arch/arm/boot/dts/overlays/README | 3 +++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 6 ++++++ - 2 files changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index aa09b6c..425eb19 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -253,6 +253,8 @@ Params: ds1307 Select the DS1307 device - - ds3231 Select the DS3231 device - -+ mcp7941x Select the MCP7941x device -+ - pcf2127 Select the PCF2127 device - - pcf8523 Select the PCF8523 device -@@ -396,6 +398,7 @@ Params: speed Display SPI bus speed - - xohms Touchpanel sensitivity (X-plate resistance) - -+ - Name: rpi-ft5406 - Info: Official Raspberry Pi display touchscreen - Load: dtoverlay=rpi-ft5406 -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index 6bccfdc..7052c71 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -17,6 +17,11 @@ - reg = <0x68>; - status = "disable"; - }; -+ mcp7941x: mcp7941x@6f { -+ compatible = "microchip,mcp7941x"; -+ reg = <0x6f>; -+ status = "disable"; -+ }; - ds3231: ds3231@68 { - compatible = "maxim,ds3231"; - reg = <0x68>; -@@ -42,6 +47,7 @@ - __overrides__ { - ds1307 = <&ds1307>,"status"; - ds3231 = <&ds3231>,"status"; -+ mcp7941x = <&mcp7941x>,"status"; - pcf2127 = <&pcf2127>,"status"; - pcf8523 = <&pcf8523>,"status"; - pcf8563 = <&pcf8563>,"status"; - -From 4b29016b330d96063fcb94f935b2c0a18a3a3fde Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 24 Jun 2015 11:23:06 +0100 -Subject: [PATCH 086/204] dts/overlays: document DHT11 overlay - ---- - arch/arm/boot/dts/overlays/README | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 425eb19..9406cf3 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -173,6 +173,14 @@ Load: dtoverlay=bmp085_i2c-sensor - Params: - - -+Name: dht11 -+Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors -+ Also sometimes found with the part number(s) AM230x. -+Load: dtoverlay=dht11,= -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) -+ -+ - [ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] - - - -From a64baab36c2fea4043c2e862efd5f2ce979d3671 Mon Sep 17 00:00:00 2001 +From 0bdb8e1577ce61590107451fa0cbb9b629a487b6 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 087/204] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 084/113] gpio-poweroff: Allow it to work on Raspberry Pi The Raspberry Pi firmware manages the power-down and reboot process. To do this it installs a pm_power_off handler, causing @@ -136118,97 +134331,17 @@ Note that running in an active-low configuration (DT parameter allow a reboot without switching off, so an external inversion of the trigger signal may be preferable. --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 13 +++++++++ - .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 ++++++++++++++++++++++ - drivers/power/reset/gpio-poweroff.c | 4 ++- - 4 files changed, 51 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts + drivers/power/reset/gpio-poweroff.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 19eef3c..a1397c7 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -16,6 +16,7 @@ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9406cf3..0ed7094 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -192,6 +192,19 @@ Params: int_pin GPIO used for INT (default 25) - speed SPI bus speed (default 12000000) - - -+Name: gpio-poweroff -+Info: Drives a GPIO high or low on reboot -+Load: gpio-poweroff,= -+Params: gpiopin GPIO for signalling (default 26) -+ -+ active_low Set if the power control device requires a -+ high->low transition to trigger a power-down. -+ Note that this will require the support of a -+ custom dt-blob.bin to prevent a power-down -+ during the boot process, and that a reboot -+ will also cause the pin to go low. -+ -+ - Name: hifiberry-amp - Info: Configures the HifiBerry Amp and Amp+ audio cards - Load: dtoverlay=hifiberry-amp -diff --git a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -new file mode 100644 -index 0000000..ff8cb36 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for gpio-poweroff module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ power_ctrl: power_ctrl { -+ compatible = "gpio-poweroff"; -+ gpios = <&gpio 26 0>; -+ force; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ power_ctrl_pins: power_ctrl_pins { -+ brcm,pins = <26>; -+ brcm,function = <1>; // out -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&power_ctrl>,"gpios:4", -+ <&power_ctrl_pins>,"brcm,pins:0"; -+ active_low = <&power_ctrl>,"gpios:8"; -+ }; -+}; diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c -index e5332f1..6e3fec2 100644 +index be3d81f..a030ae9 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c -@@ -48,9 +48,11 @@ static void gpio_poweroff_do_poweroff(void) - static int gpio_poweroff_probe(struct platform_device *pdev) +@@ -49,9 +49,11 @@ static int gpio_poweroff_probe(struct platform_device *pdev) { bool input = false; + enum gpiod_flags flags; + bool force = false; /* If a pm_power_off function has already been added, leave it alone */ @@ -136219,994 +134352,20 @@ index e5332f1..6e3fec2 100644 "%s: pm_power_off function already registered", __func__); -From 751f8f85e9ecb31382f4b15fbf04311da32bd403 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 17 Jun 2015 17:10:40 +0100 -Subject: [PATCH 088/204] BCM270x_DT: Default Compute Module i2c, i2s and spi - support - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 67 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 67 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index e82fcb2..af252bd 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -10,10 +10,77 @@ - status = "okay"; - }; - -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ - / { - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; - -From 310ac993d7e597234de083f9e28a950beea57e05 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 22 Jun 2015 14:21:55 +0100 -Subject: [PATCH 089/204] BCM270X_DT: Sort nodes by bus address, and - consolidate aliases - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 19 ---------- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 19 ---------- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 21 ----------- - arch/arm/boot/dts/bcm2708_common.dtsi | 63 +++++++++++++++++++++++--------- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 19 ---------- - 5 files changed, 46 insertions(+), 95 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 3b252dc..9af99b8 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -5,25 +5,6 @@ - / { - compatible = "brcm,bcm2708"; - model = "Raspberry Pi Model B+"; -- -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; - }; - - &gpio { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 40fded1..092d15d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -5,25 +5,6 @@ - / { - compatible = "brcm,bcm2708"; - model = "Raspberry Pi Model B"; -- -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; - }; - - &gpio { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 3da7d3b..34d4bc6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -1,26 +1,5 @@ - /include/ "bcm2708.dtsi" - --/ { -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; --}; -- - &leds { - act_led: act { - label = "led0"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4a975dfd..b71b208 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -3,6 +3,31 @@ - / { - interrupt-parent = <&intc>; - -+ aliases { -+ audio = &audio; -+ sound = &sound; -+ soc = &soc; -+ dma = &dma; -+ intc = &intc; -+ watchdog = &watchdog; -+ random = &random; -+ mailbox = &mailbox; -+ gpio = &gpio; -+ uart0 = &uart0; -+ i2s = &i2s; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ uart1 = &uart1; -+ mmc = &mmc; -+ i2c1 = &i2c1; -+ usb = &usb; -+ leds = &leds; -+ fb = &fb; -+ vchiq = &vchiq; -+ thermal = &thermal; -+ clocks = &clocks; -+ }; -+ - /* Onboard audio */ - audio: audio { - compatible = "brcm,bcm2835-audio"; -@@ -10,6 +35,10 @@ - status = "disabled"; - }; - -+ /* External sound card */ -+ sound: sound { -+ }; -+ - soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; -@@ -43,6 +72,12 @@ - #interrupt-cells = <2>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - watchdog: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm-wdt"; - reg = <0x7e100000 0x28>; -@@ -55,12 +90,6 @@ - status = "disabled"; - }; - -- mailbox: mailbox@7e00b800 { -- compatible = "brcm,bcm2708-vcio"; -- reg = <0x7e00b880 0x40>; -- interrupts = <0 1>; -- }; -- - gpio: gpio { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; -@@ -73,17 +102,6 @@ - #interrupt-cells = <2>; - }; - -- mmc: mmc@7e300000 { -- compatible = "brcm,bcm2835-mmc"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- - uart0: uart@7e201000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; -@@ -144,6 +162,17 @@ - status = "disabled"; - }; - -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ - i2c1: i2c@7e804000 { - compatible = "brcm,bcm2708-i2c"; - reg = <0x7e804000 0x1000>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 24fa849..ccb9c31 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -5,25 +5,6 @@ - / { - compatible = "brcm,bcm2709"; - model = "Raspberry Pi 2 Model B"; -- -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; - }; - - &gpio { - -From e2eb20fe73389475f652fa9ad78db6b9dc5fd780 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 22 Jun 2015 14:23:03 +0100 -Subject: [PATCH 090/204] i2c-bcm2708/BCM270X_DT: Add support for I2C2 - -The third I2C bus (I2C2) is normally reserved for HDMI use. Careless -use of this bus can break an attached display - use with caution. - -It is recommended to disable accesses by VideoCore by setting -hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt. - -The interface is disabled by default - enable using the -i2c2_iknowwhatimdoing DT parameter. ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 6 ++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 6 ++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 6 ++++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 14 ++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 6 ++++++ - drivers/i2c/busses/i2c-bcm2708.c | 5 ++++- - 6 files changed, 42 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 9af99b8..e3ae8e6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -75,6 +75,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -103,8 +107,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 092d15d..18ca7a2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -75,6 +75,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -97,8 +101,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index af252bd..bddc369 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -65,6 +65,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -79,8 +83,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index b71b208..8181a4e 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -20,6 +20,7 @@ - uart1 = &uart1; - mmc = &mmc; - i2c1 = &i2c1; -+ i2c2 = &i2c2; - usb = &usb; - leds = &leds; - fb = &fb; -@@ -183,6 +184,19 @@ - status = "disabled"; - }; - -+ i2c2: i2c@7e805000 { -+ // Beware - this is shared with the HDMI module. -+ // Careless use may break (really) your display. -+ // Caveat emptor. -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e805000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ - usb: usb@7e980000 { - compatible = "brcm,bcm2708-usb"; - reg = <0x7e980000 0x10000>, -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index ccb9c31..76d44a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -75,6 +75,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -103,8 +107,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 8773203..7a24fbe 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -407,8 +407,11 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - case 1: - adap->class = I2C_CLASS_DDC; - break; -+ case 2: -+ adap->class = I2C_CLASS_DDC; -+ break; - default: -- dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); -+ dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n"); - err = -ENXIO; - goto out_free_bi; - } - -From 9845042a17cd1bfc818801e7a5793b00346bb242 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 29 Jun 2015 12:14:02 +0100 -Subject: [PATCH 091/204] BCM270X_DT: Correct the lirc-rpi overlay - documentation - -The polarity of the "sense" parameter was inverted with respect to reality. - -See: https://github.com/raspberrypi/linux/issues/1038 ---- - arch/arm/boot/dts/overlays/README | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0ed7094..ec762d2 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -313,8 +313,8 @@ Params: gpio_out_pin GPIO for output (default "17") - (default "down") - - sense Override the IR receive auto-detection logic: -- "1" = force active high -- "0" = force active low -+ "0" = force active-high -+ "1" = force active-low - "-1" = use auto-detection - (default "-1") - - -From e75018d8c8385653326af3519474b108f0f74945 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 25 Jun 2015 08:47:09 +0100 -Subject: [PATCH 092/204] bcm2835-sdhost: Further improve overclock back-off - ---- - drivers/mmc/host/bcm2835-sdhost.c | 144 +++++++++++++++++++++----------------- - 1 file changed, 78 insertions(+), 66 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 6277e43..a03db06 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -161,8 +161,6 @@ struct bcm2835_host { - - unsigned int use_busy:1; /* Wait for busy interrupt */ - -- unsigned int reduce_overclock:1; /* ...at the next opportunity */ -- - unsigned int debug:1; /* Enable debug output */ - - u32 thread_isr; -@@ -466,36 +464,25 @@ static void bcm2835_sdhost_dma_complete(void *param) - spin_unlock_irqrestore(&host->lock, flags); - } - --static bool data_transfer_wait(struct bcm2835_host *host, const char *caller) -+static bool data_transfer_wait(struct bcm2835_host *host) - { - unsigned long timeout = 1000000; -- u32 hsts; - while (timeout) - { -- hsts = bcm2835_sdhost_read(host, SDHSTS); -- if (hsts & (SDHSTS_TRANSFER_ERROR_MASK | -- SDHSTS_DATA_FLAG)) { -- bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -- SDHSTS); -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & SDHSTS_DATA_FLAG) { -+ bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); - break; - } - timeout--; - } -- -- if (hsts & (SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | -- SDHSTS_FIFO_ERROR)) { -- pr_err("%s: data error in %s - HSTS %x\n", -- mmc_hostname(host->mmc), caller, hsts); -- host->data->error = -EILSEQ; -- return false; -- } else if ((timeout == 0) || -- (hsts & (SDHSTS_CMD_TIME_OUT | -- SDHSTS_REW_TIME_OUT))) { -- pr_err("%s: timeout in %s - HSTS %x\n", -- mmc_hostname(host->mmc), caller, hsts); -- host->data->error = -ETIMEDOUT; -- return false; -+ if (timeout == 0) { -+ pr_err("%s: Data %s timeout\n", -+ mmc_hostname(host->mmc), -+ (host->data->flags & MMC_DATA_READ) ? "read" : "write"); -+ bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; -+ return false; - } - return true; - } -@@ -523,7 +510,7 @@ static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - buf = (u32 *)host->sg_miter.addr; - - while (len) { -- if (!data_transfer_wait(host, "read_block_pio")) -+ if (!data_transfer_wait(host)) - break; - - *(buf++) = bcm2835_sdhost_read(host, SDDATA); -@@ -562,7 +549,7 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - buf = host->sg_miter.addr; - - while (len) { -- if (!data_transfer_wait(host, "write_block_pio")) -+ if (!data_transfer_wait(host)) - break; - - bcm2835_sdhost_write(host, *(buf++), SDDATA); -@@ -581,13 +568,33 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - - static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - { -+ u32 sdhsts; -+ bool is_read; - BUG_ON(!host->data); - -- if (host->data->flags & MMC_DATA_READ) { -+ is_read = (host->data->flags & MMC_DATA_READ) != 0; -+ if (is_read) - bcm2835_sdhost_read_block_pio(host); -- } else { -+ else - bcm2835_sdhost_write_block_pio(host); - -+ sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & (SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) { -+ pr_err("%s: %s transfer error - HSTS %x\n", -+ mmc_hostname(host->mmc), -+ is_read ? "read" : "write", -+ sdhsts); -+ host->data->error = -EILSEQ; -+ } else if ((sdhsts & (SDHSTS_CMD_TIME_OUT | -+ SDHSTS_REW_TIME_OUT))) { -+ pr_err("%s: %s timeout error - HSTS %x\n", -+ mmc_hostname(host->mmc), -+ is_read ? "read" : "write", -+ sdhsts); -+ host->data->error = -ETIMEDOUT; -+ } else if (!is_read && !host->data->error) { - /* Start a timer in case a transfer error occurs because - there is no error interrupt */ - mod_timer(&host->pio_timer, jiffies + host->pio_timeout); -@@ -701,8 +708,9 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - - void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) - { -- u32 sdcmd; -+ u32 sdcmd, sdhsts; - unsigned long timeout; -+ int delay; - - WARN_ON(host->cmd); - -@@ -719,8 +727,8 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - mmc_hostname(host->mmc), - cmd->opcode, cmd->arg, cmd->flags); - -- /* Wait max 10 ms */ -- timeout = 1000; -+ /* Wait max 100 ms */ -+ timeout = 10000; - - while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { - if (timeout == 0) { -@@ -735,8 +743,9 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - udelay(10); - } - -- if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { -- host->max_delay = (1000-timeout)/100; -+ delay = (10000 - timeout)/100; -+ if (delay > host->max_delay) { -+ host->max_delay = delay; - pr_warning("%s: controller hung for %d ms\n", - mmc_hostname(host->mmc), - host->max_delay); -@@ -751,6 +760,11 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - - host->cmd = cmd; - -+ /* Clear any error flags */ -+ sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & SDHSTS_ERROR_MASK) -+ bcm2835_sdhost_write(host, sdhsts, SDHSTS); -+ - bcm2835_sdhost_prepare_data(host, cmd); - - bcm2835_sdhost_write(host, cmd->arg, SDARG); -@@ -876,7 +890,7 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - { - u32 sdcmd; -- int timeout = 1000; -+ unsigned long timeout; - #ifdef DEBUG - struct timeval before, after; - int timediff = 0; -@@ -889,6 +903,8 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - #ifdef DEBUG - do_gettimeofday(&before); - #endif -+ /* Wait max 100 ms */ -+ timeout = 10000; - for (sdcmd = bcm2835_sdhost_read(host, SDCMD); - (sdcmd & SDCMD_NEW_FLAG) && timeout; - timeout--) { -@@ -1049,9 +1065,9 @@ static void bcm2835_sdhost_pio_timeout(unsigned long data) - spin_lock_irqsave(&host->lock, flags); - - if (host->data) { -- u32 hsts = bcm2835_sdhost_read(host, SDHSTS); -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); - -- if (hsts & SDHSTS_REW_TIME_OUT) { -+ if (sdhsts & SDHSTS_REW_TIME_OUT) { - pr_err("%s: transfer timeout\n", - mmc_hostname(host->mmc)); - if (host->debug) -@@ -1380,19 +1396,10 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); - -- if ((clock == 0) && host->reduce_overclock) { -- /* This is a reset following data corruption - reduce any -- overclock */ -- host->reduce_overclock = 0; -- if (host->overclock_50 > 50) { -- pr_warn("%s: reducing overclock due to errors\n", -- mmc_hostname(host->mmc)); -- host->overclock_50--; -- } -- } -- -- if (host->overclock_50 && (clock == 50*MHZ)) -+ if ((host->overclock_50 > 50) && -+ (clock == 50*MHZ)) { - clock = host->overclock_50 * MHZ + (MHZ - 1); -+ } - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1450,11 +1457,12 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->overclock = clock; - } - } -- else if ((clock == 50 * MHZ) && host->overclock) -+ else if (host->overclock) - { -- pr_warn("%s: cancelling overclock\n", -- mmc_hostname(host->mmc)); - host->overclock = 0; -+ if (clock == 50 * MHZ) -+ pr_warn("%s: cancelling overclock\n", -+ mmc_hostname(host->mmc)); - } - - host->cdiv = div; -@@ -1492,6 +1500,14 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - cmd->opcode, cmd->arg, cmd->flags); - } - -+ /* Reset the error statuses in case this is a retry */ -+ if (mrq->cmd) -+ mrq->cmd->error = 0; -+ if (mrq->data) -+ mrq->data->error = 0; -+ if (mrq->stop) -+ mrq->stop->error = 0; -+ - if (mrq->data && !is_power_of_2(mrq->data->blksz)) { - pr_err("%s: unsupported block size (%d bytes)\n", - mmc_hostname(mmc), mrq->data->blksz); -@@ -1613,21 +1629,16 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - /* Drop the overclock after any data corruption, or after any - error overclocked */ -- if (mrq->data && (mrq->data->error == -EILSEQ)) -- host->reduce_overclock = 1; -- else if (host->overclock) { -- /* Convert timeout errors while overclocked to data errors, -- because the system recovers better. */ -- if (mrq->cmd && mrq->cmd->error) { -- host->reduce_overclock = 1; -- if (mrq->cmd->error == -ETIMEDOUT) -- mrq->cmd->error = -EILSEQ; -- } -- -- if (mrq->data && mrq->data->error) { -- host->reduce_overclock = 1; -- if (mrq->data->error == -ETIMEDOUT) -- mrq->data->error = -EILSEQ; -+ if (host->overclock) { -+ if ((mrq->cmd && mrq->cmd->error) || -+ (mrq->data && mrq->data->error) || -+ (mrq->stop && mrq->stop->error)) { -+ host->overclock_50--; -+ pr_warn("%s: reducing overclock due to errors\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_set_clock(host,50*MHZ); -+ mrq->cmd->error = -EILSEQ; -+ mrq->cmd->retries = 1; - } - } - -@@ -1769,6 +1780,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host = mmc_priv(mmc); - host->mmc = mmc; - host->pio_timeout = msecs_to_jiffies(500); -+ host->max_delay = 1; /* Warn if over 1ms */ - spin_lock_init(&host->lock); - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - -From 13cbc57aa3f9dd10bdc8dad7915626d1697c9903 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 10:28:59 +0100 -Subject: [PATCH 093/204] i2c-bcm2708: Increase timeouts to allow larger - transfers - -Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting -for completion. The default timeout is 1 second. - -See: https://github.com/raspberrypi/linux/issues/260 ---- - drivers/i2c/busses/i2c-bcm2708.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 7a24fbe..8b8762d 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -67,10 +67,9 @@ - #define BSC_S_DONE 0x00000002 - #define BSC_S_TA 0x00000001 - --#define I2C_TIMEOUT_MS 150 --#define I2C_WAIT_LOOP_COUNT 40 -+#define I2C_WAIT_LOOP_COUNT 200 - --#define DRV_NAME "bcm2708_i2c" -+#define DRV_NAME "bcm2708_i2c" - - static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; - module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -@@ -305,7 +304,7 @@ static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, - goto error_timeout; - } - -- ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); -+ ret = wait_for_completion_timeout(&bi->done, adap->timeout); - if (ret == 0) { - dev_err(&adap->dev, "transfer timed out\n"); - goto error_timeout; - -From f7d430536dec32c07a6ba6eb7ed6167ff4974855 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 10:33:52 +0100 -Subject: [PATCH 094/204] spi-bcm2708: Increase timeout from 150ms to 1s - -See: https://github.com/raspberrypi/linux/issues/260 ---- - drivers/spi/spi-bcm2708.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 041b5e2..5c0214e 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -70,9 +70,9 @@ - #define SPI_CS_CS_10 0x00000002 - #define SPI_CS_CS_01 0x00000001 - --#define SPI_TIMEOUT_MS 150 -+#define SPI_TIMEOUT_MS 1000 - --#define DRV_NAME "bcm2708_spi" -+#define DRV_NAME "bcm2708_spi" - - struct bcm2708_spi { - spinlock_t lock; - -From 9f8135d6ddcbf9ab9dd9678249c3b8c5d17a9229 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 15 Jun 2015 09:59:38 +0100 -Subject: [PATCH 095/204] bcm2708-spi: Don't use static pin configuration with - DT - -Also remove superfluous error checking - the SPI framework ensures the -validity of the chip_select value. ---- - drivers/spi/spi-bcm2708.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 5c0214e..781c747 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -386,14 +386,6 @@ static int bcm2708_spi_setup(struct spi_device *spi) - if (bs->stopping) - return -ESHUTDOWN; - -- if (!(spi->mode & SPI_NO_CS) && -- (spi->chip_select > spi->master->num_chipselect)) { -- dev_dbg(&spi->dev, -- "setup: invalid chipselect %u (%u defined)\n", -- spi->chip_select, spi->master->num_chipselect); -- return -EINVAL; -- } -- - state = spi->controller_state; - if (!state) { - state = kzalloc(sizeof(*state), GFP_KERNEL); -@@ -496,7 +488,8 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - return PTR_ERR(clk); - } - -- bcm2708_init_pinmode(); -+ if (!pdev->dev.of_node) -+ bcm2708_init_pinmode(); - - master = spi_alloc_master(&pdev->dev, sizeof(*bs)); - if (!master) { - -From 8c4cdb44d24dba5443a6bc18b7729ba76967acaa Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 15 Jun 2015 10:10:59 +0100 -Subject: [PATCH 096/204] bcm2708-i2s: Don't use static pin configuration with - DT - ---- - sound/soc/bcm/bcm2708-i2s.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c -index a515992..5e93cd6 100644 ---- a/sound/soc/bcm/bcm2708-i2s.c -+++ b/sound/soc/bcm/bcm2708-i2s.c -@@ -409,8 +409,8 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, - if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) - return 0; - -- -- bcm2708_i2s_setup_gpio(); -+ if (!dev->dev->of_node) -+ bcm2708_i2s_setup_gpio(); - - /* - * Adjust the data length according to the format. - -From 21f6968a52663113eab7b89f7cb192e92d8ea951 Mon Sep 17 00:00:00 2001 +From bd7c2a5be55489e6cee8f311ed2959ba0e9ff67d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 30 Jun 2015 14:12:42 +0100 -Subject: [PATCH 097/204] serial: 8250: Don't crash when nr_uarts is 0 +Subject: [PATCH 085/113] serial: 8250: Don't crash when nr_uarts is 0 --- drivers/tty/serial/8250/8250_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c -index b4fd8de..f459feb 100644 +index 271d121..d8e44c9 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c -@@ -3270,6 +3270,8 @@ static void __init serial8250_isa_init_ports(void) +@@ -509,6 +509,8 @@ static void __init serial8250_isa_init_ports(void) if (nr_uarts > UART_NR) nr_uarts = UART_NR; @@ -137216,182 +134375,10 @@ index b4fd8de..f459feb 100644 for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; -From afddc0087e5b1db8311454fa66909bc400151982 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 26 Jun 2015 08:50:11 +0100 -Subject: [PATCH 098/204] BCM270X_DT: Add overlay to enable uart1 - -N.B. The UART1 clock is derived from the core clock. The firmware -will update clock-frequency if core_freq is set, but be aware -that unless force_turbo=1 while overclocking then the baud rate -will vary with ARM activity. ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++++ - arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 ++++++++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm/configs/bcmrpi_defconfig | 2 +- - 9 files changed, 53 insertions(+), 2 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index e3ae8e6..3ad2e0d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -103,6 +103,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 18ca7a2..65628e1 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -97,6 +97,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index bddc369..96d8b97 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -79,6 +79,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 76d44a2..f25f0a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -103,6 +103,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index a1397c7..e91548c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -42,6 +42,7 @@ dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index ec762d2..d81d41a 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -489,6 +489,14 @@ Params: speed Display SPI bus speed - dtoverlay=tinylcd35,touch,touchgpio=3 - - -+Name: uart1 -+Info: Enable uart1 in place of uart0 -+Load: dtoverlay=uart1,= -+Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) -+ -+ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) -+ -+ - Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. -diff --git a/arch/arm/boot/dts/overlays/uart1-overlay.dts b/arch/arm/boot/dts/overlays/uart1-overlay.dts -new file mode 100644 -index 0000000..fa73e1f ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/uart1-overlay.dts -@@ -0,0 +1,38 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&uart1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ uart1_pins: uart1_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <2>; /* alt5 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/chosen"; -+ __overlay__ { -+ bootargs = "8250.nr_uarts=1"; -+ }; -+ }; -+ -+ __overrides__ { -+ txd1_pin = <&uart1_pins>,"brcm,pins:0"; -+ rxd1_pin = <&uart1_pins>,"brcm,pins:4"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 46d56d7..8a240fd 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -562,7 +562,7 @@ CONFIG_SERIAL_8250=y - CONFIG_SERIAL_8250_CONSOLE=y - # CONFIG_SERIAL_8250_DMA is not set - CONFIG_SERIAL_8250_NR_UARTS=1 --CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e757db6..363c894 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -555,7 +555,7 @@ CONFIG_SERIAL_8250=y - CONFIG_SERIAL_8250_CONSOLE=y - # CONFIG_SERIAL_8250_DMA is not set - CONFIG_SERIAL_8250_NR_UARTS=1 --CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=y - -From 9b7dfacf1ff658c5aa03075776f71c8d6e16564e Mon Sep 17 00:00:00 2001 +From 83bf3d318d5af31c35c593529a9174caf0624733 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 099/204] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 086/113] spi-bcm2835: Support pin groups other than 7-11 The spi-bcm2835 driver automatically uses GPIO chip-selects due to some unreliability of the native ones. In doing so it chooses the @@ -137408,10 +134395,10 @@ Signed-off-by: Phil Elwell 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index a506773..cf3190f 100644 +index 3e8eeb2..3835332 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c -@@ -376,6 +376,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) +@@ -688,6 +688,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) { int err; struct gpio_chip *chip; @@ -137420,7 +134407,7 @@ index a506773..cf3190f 100644 /* * sanity checking the native-chipselects */ -@@ -392,15 +394,42 @@ static int bcm2835_spi_setup(struct spi_device *spi) +@@ -704,15 +706,42 @@ static int bcm2835_spi_setup(struct spi_device *spi) "setup: only two native chip-selects are supported\n"); return -EINVAL; } @@ -137472,2768 +134459,10 @@ index a506773..cf3190f 100644 /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -From c26edc1513a5086a1a4e0c16746d52423b0259c8 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 17:37:38 +0100 -Subject: [PATCH 100/204] BCM270X_DT: Change pio_limit of sdhost driver to 1 - ---- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index 897204a..2da14a4 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -22,7 +22,7 @@ - dma-names = "tx", "rx"; - brcm,delay-after-stop = <0>; - brcm,overclock-50 = <0>; -- brcm,pio-limit = <2>; -+ brcm,pio-limit = <1>; - status = "okay"; - }; - }; - -From 83dda549d089cd0117282ec6edebd697fa59f173 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 1 Jul 2015 12:51:52 +0100 -Subject: [PATCH 101/204] bcm2835-sdhost: Clear HBLC for PIO mode - -Also update pio_limit default in overlay README. ---- - arch/arm/boot/dts/overlays/README | 2 +- - drivers/mmc/host/bcm2835-sdhost.c | 3 +-- - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d81d41a..980d358 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -441,7 +441,7 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - force_pio Disable DMA support (default off) - - pio_limit Number of blocks above which to use DMA -- (default 2) -+ (default 1) - - debug Enable debug output (default off) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index a03db06..d65870a 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -699,8 +699,7 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - bcm2835_sdhost_set_transfer_irqs(host); - - bcm2835_sdhost_write(host, data->blksz, SDHBCT); -- if (host->use_dma) -- bcm2835_sdhost_write(host, data->blocks, SDHBLC); -+ bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); - - BUG_ON(!host->data); - } - -From ecdc3c6d8615d2f5df08e2514cb0b6b12be840e1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 3 Jul 2015 12:21:01 +0100 -Subject: [PATCH 102/204] BCM270X_DT: I2S needs function Alt2 - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 +- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 +- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 2 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 3ad2e0d..562eb08 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 65628e1..e2b1491 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <28 29 30 31>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 96d8b97..5e3db01 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -28,7 +28,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index f25f0a2..62d1c62 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - - -From 906a4b80abdc53ea1369eb0ecf310a4b906d2f1c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:16:15 +0200 -Subject: [PATCH 103/204] configs: Incorporate v4.1 dependency changes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 78e9b7de78bb53e8bc7f4c4a60ebacb250c0c190 added a -dependency on TI_ST instead of selecting it, disabling: -CONFIG_BT_WILINK=m -CONFIG_RADIO_WL128X=m - -Commit 652ccae5cc4e1305fb0a4619947f9ee89d8c7f5a added a -depency on ARM_CRYPTO, disabling: -CONFIG_CRYPTO_SHA*_ARM*=m -CONFIG_CRYPTO_AES_ARM*=m - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 10 ++++++---- - arch/arm/configs/bcm2835_defconfig | 8 +++++--- - arch/arm/configs/bcmrpi_defconfig | 8 +++++--- - 3 files changed, 16 insertions(+), 10 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 8a240fd..ccfc14c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -401,6 +401,7 @@ CONFIG_BLK_DEV_RAM=y - CONFIG_CDROM_PKTCDVD=m - CONFIG_ATA_OVER_ETH=m - CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -@@ -1100,6 +1101,7 @@ CONFIG_OCFS2_FS=m - CONFIG_BTRFS_FS=m - CONFIG_BTRFS_FS_POSIX_ACL=y - CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y - CONFIG_QFMT_V1=m - CONFIG_QFMT_V2=m -@@ -1129,7 +1131,6 @@ CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y - CONFIG_SQUASHFS_XZ=y --CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y -@@ -1205,14 +1206,15 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA1_ARM_NEON=m --CONFIG_CRYPTO_SHA512_ARM_NEON=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m --CONFIG_CRYPTO_AES_ARM_BS=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set - # CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_SHA512_ARM_NEON=m -+CONFIG_CRYPTO_AES_ARM_BS=m - CONFIG_CRC_ITU_T=y - CONFIG_LIBCRC32C=y -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 2e8a95a..47f2a6a 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -402,6 +402,7 @@ CONFIG_BLK_DEV_RAM=y - CONFIG_CDROM_PKTCDVD=m - CONFIG_ATA_OVER_ETH=m - CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -@@ -1091,6 +1092,7 @@ CONFIG_OCFS2_FS=m - CONFIG_BTRFS_FS=m - CONFIG_BTRFS_FS_POSIX_ACL=y - CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y - CONFIG_QFMT_V1=m - CONFIG_QFMT_V2=m -@@ -1120,7 +1122,6 @@ CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y - CONFIG_SQUASHFS_XZ=y --CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y -@@ -1208,15 +1209,16 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA1_ARM=m - CONFIG_CRYPTO_SHA512=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m --CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set - # CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRC_ITU_T=y - CONFIG_LIBCRC32C=y - # CONFIG_XZ_DEC_ARM is not set -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 363c894..80f84d7 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -394,6 +394,7 @@ CONFIG_BLK_DEV_RAM=y - CONFIG_CDROM_PKTCDVD=m - CONFIG_ATA_OVER_ETH=m - CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -@@ -1093,6 +1094,7 @@ CONFIG_OCFS2_FS=m - CONFIG_BTRFS_FS=m - CONFIG_BTRFS_FS_POSIX_ACL=y - CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y - CONFIG_QFMT_V1=m - CONFIG_QFMT_V2=m -@@ -1122,7 +1124,6 @@ CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y - CONFIG_SQUASHFS_XZ=y --CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y -@@ -1200,14 +1201,15 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA1_ARM=m - CONFIG_CRYPTO_SHA512=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m --CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set - # CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRC_ITU_T=y - CONFIG_LIBCRC32C=y - -From 03edd2dd4b9c016f440383c9fae725f5c4e73eca Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 3 Jul 2015 15:47:33 +0100 -Subject: [PATCH 104/204] bcmrpi_defconfigs: Add SND_SOC_WM8804_I2C (for - HifiBerry Digi) - -4.1 has split out support for the I2C and SPI variants, so it now -necessary to explicitly enable the I2C support. ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index ccfc14c..5ecd84f 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -823,6 +823,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 80f84d7..14b91fdf 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -816,6 +816,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y - -From b1c7182dc37e87b47377b529de6e54a431fc07aa Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sat, 4 Jul 2015 19:55:23 +0100 -Subject: [PATCH 105/204] squash: BCM270X_DT: I2S only needs Alt2 on 28-31 - -See: https://github.com/raspberrypi/linux/issues/1046 ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 +- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 2 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 562eb08..3ad2e0d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 5e3db01..96d8b97 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -28,7 +28,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 62d1c62..f25f0a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ - }; - }; - - -From b52bc261c9b3c08ac73aca166afb05090ffca7eb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 8 Jul 2015 14:48:57 +0100 -Subject: [PATCH 106/204] vchiq_arm: Two cacheing fixes - -1) Make fragment size vary with cache line size -Without this patch, non-cache-line-aligned transfers may corrupt -(or be corrupted by) adjacent data structures. - -Both ARM and VC need to be updated to enable this feature. This is -ensured by having the loader apply a new DT parameter - -cache-line-size. The existence of this parameter guarantees that the -kernel is capable, and the parameter will only be modified from the -safe default if the loader is capable. - -2) Flush/invalidate vmalloc'd memory, and invalidate after reads ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 + - .../interface/vchiq_arm/vchiq_2835_arm.c | 112 +++++++++++++-------- - 2 files changed, 77 insertions(+), 40 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 8181a4e..abf3e5d 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -218,6 +218,7 @@ - compatible = "brcm,bcm2835-vchiq"; - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; -+ cache-line-size = <32>; - }; - - thermal: thermal { -@@ -270,4 +271,8 @@ - clock-frequency = <126000000>; - }; - }; -+ -+ __overrides__ { -+ cache_line_size = <&vchiq>, "cache-line-size:0"; -+ }; - }; -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index c739083..5edba23 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - #include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) -@@ -64,8 +65,10 @@ typedef struct vchiq_2835_state_struct { - } VCHIQ_2835_ARM_STATE_T; - - static void __iomem *g_regs; --static FRAGMENTS_T *g_fragments_base; --static FRAGMENTS_T *g_free_fragments; -+static unsigned int g_cache_line_size = sizeof(CACHE_LINE_SIZE); -+static unsigned int g_fragments_size; -+static char *g_fragments_base; -+static char *g_free_fragments; - static struct semaphore g_free_fragments_sema; - static unsigned long g_virt_to_bus_offset; - -@@ -95,9 +98,13 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - - g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); - -+ (void)of_property_read_u32(dev->of_node, "cache-line-size", -+ &g_cache_line_size); -+ g_fragments_size = 2 * g_cache_line_size; -+ - /* Allocate space for the channels in coherent memory */ - slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); -- frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); -+ frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); - - slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, - &slot_phys, GFP_KERNEL); -@@ -117,15 +124,15 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = - MAX_FRAGMENTS; - -- g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); -+ g_fragments_base = (char *)slot_mem + slot_mem_size; - slot_mem_size += frag_mem_size; - - g_free_fragments = g_fragments_base; - for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { -- *(FRAGMENTS_T **)&g_fragments_base[i] = -- &g_fragments_base[i + 1]; -+ *(char **)&g_fragments_base[i*g_fragments_size] = -+ &g_fragments_base[(i + 1)*g_fragments_size]; - } -- *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; -+ *(char **)&g_fragments_base[i * g_fragments_size] = NULL; - sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); - - if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) -@@ -344,7 +351,7 @@ vchiq_doorbell_irq(int irq, void *dev_id) - ** cached area. - - ** N.B. This implementation plays slightly fast and loose with the Linux --** driver programming rules, e.g. its use of __virt_to_bus instead of -+** driver programming rules, e.g. its use of dmac_map_area instead of - ** dma_map_single, but it isn't a multi-platform driver and it benefits - ** from increased speed as a result. - */ -@@ -355,7 +362,6 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - { - PAGELIST_T *pagelist; - struct page **pages; -- struct page *page; - unsigned long *addrs; - unsigned int num_pages, offset, i; - char *addr, *base_addr, *next_addr; -@@ -386,10 +392,25 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - pages = (struct page **)(addrs + num_pages + 1); - - if (is_vmalloc_addr(buf)) { -- for (actual_pages = 0; actual_pages < num_pages; actual_pages++) { -- pages[actual_pages] = vmalloc_to_page(buf + (actual_pages * PAGE_SIZE)); -+ int dir = (type == PAGELIST_WRITE) ? -+ DMA_TO_DEVICE : DMA_FROM_DEVICE; -+ unsigned long length = pagelist->length; -+ unsigned int offset = pagelist->offset; -+ -+ for (actual_pages = 0; actual_pages < num_pages; -+ actual_pages++) { -+ struct page *pg = vmalloc_to_page(buf + (actual_pages * -+ PAGE_SIZE)); -+ size_t bytes = PAGE_SIZE - offset; -+ -+ if (bytes > length) -+ bytes = length; -+ pages[actual_pages] = pg; -+ dmac_map_area(page_address(pg) + offset, bytes, dir); -+ length -= bytes; -+ offset = 0; - } -- *need_release = 0; /* do not try and release vmalloc pages */ -+ *need_release = 0; /* do not try and release vmalloc pages */ - } else { - down_read(&task->mm->mmap_sem); - actual_pages = get_user_pages(task, task->mm, -@@ -418,7 +439,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - actual_pages = -ENOMEM; - return actual_pages; - } -- *need_release = 1; /* release user pages */ -+ *need_release = 1; /* release user pages */ - } - - pagelist->length = count; -@@ -451,10 +472,10 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - - /* Partial cache lines (fragments) require special measures */ - if ((type == PAGELIST_READ) && -- ((pagelist->offset & (CACHE_LINE_SIZE - 1)) || -+ ((pagelist->offset & (g_cache_line_size - 1)) || - ((pagelist->offset + pagelist->length) & -- (CACHE_LINE_SIZE - 1)))) { -- FRAGMENTS_T *fragments; -+ (g_cache_line_size - 1)))) { -+ char *fragments; - - if (down_interruptible(&g_free_fragments_sema) != 0) { - kfree(pagelist); -@@ -464,19 +485,15 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - WARN_ON(g_free_fragments == NULL); - - down(&g_free_fragments_mutex); -- fragments = (FRAGMENTS_T *) g_free_fragments; -+ fragments = g_free_fragments; - WARN_ON(fragments == NULL); -- g_free_fragments = *(FRAGMENTS_T **) g_free_fragments; -+ g_free_fragments = *(char **) g_free_fragments; - up(&g_free_fragments_mutex); -- pagelist->type = -- PAGELIST_READ_WITH_FRAGMENTS + (fragments - -- g_fragments_base); -+ pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + -+ (fragments - g_fragments_base) / g_fragments_size; - } - -- for (page = virt_to_page(pagelist); -- page <= virt_to_page(addrs + num_pages - 1); page++) { -- flush_dcache_page(page); -- } -+ dmac_flush_range(pagelist, addrs + num_pages); - - *ppagelist = pagelist; - -@@ -502,13 +519,14 @@ free_pagelist(PAGELIST_T *pagelist, int actual) - - /* Deal with any partial cache lines (fragments) */ - if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { -- FRAGMENTS_T *fragments = g_fragments_base + -- (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS); -+ char *fragments = g_fragments_base + -+ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * -+ g_fragments_size; - int head_bytes, tail_bytes; -- head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & -- (CACHE_LINE_SIZE - 1); -+ head_bytes = (g_cache_line_size - pagelist->offset) & -+ (g_cache_line_size - 1); - tail_bytes = (pagelist->offset + actual) & -- (CACHE_LINE_SIZE - 1); -+ (g_cache_line_size - 1); - - if ((actual >= 0) && (head_bytes != 0)) { - if (head_bytes > actual) -@@ -516,32 +534,46 @@ free_pagelist(PAGELIST_T *pagelist, int actual) - - memcpy((char *)page_address(pages[0]) + - pagelist->offset, -- fragments->headbuf, -+ fragments, - head_bytes); - } - if ((actual >= 0) && (head_bytes < actual) && - (tail_bytes != 0)) { - memcpy((char *)page_address(pages[num_pages - 1]) + - ((pagelist->offset + actual) & -- (PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)), -- fragments->tailbuf, tail_bytes); -+ (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), -+ fragments + g_cache_line_size, -+ tail_bytes); - } - - down(&g_free_fragments_mutex); -- *(FRAGMENTS_T **) fragments = g_free_fragments; -+ *(char **)fragments = g_free_fragments; - g_free_fragments = fragments; - up(&g_free_fragments_mutex); - up(&g_free_fragments_sema); - } - -- if (*need_release) { -- for (i = 0; i < num_pages; i++) { -- if (pagelist->type != PAGELIST_WRITE) -- set_page_dirty(pages[i]); -+ if (*need_release) { -+ unsigned int length = pagelist->length; -+ unsigned int offset = pagelist->offset; - -- page_cache_release(pages[i]); -+ for (i = 0; i < num_pages; i++) { -+ struct page *pg = pages[i]; -+ -+ if (pagelist->type != PAGELIST_WRITE) { -+ unsigned int bytes = PAGE_SIZE - offset; -+ -+ if (bytes > length) -+ bytes = length; -+ dmac_unmap_area(page_address(pg) + offset, -+ bytes, DMA_FROM_DEVICE); -+ length -= bytes; -+ offset = 0; -+ set_page_dirty(pg); -+ } -+ page_cache_release(pg); - } -- } -+ } - - kfree(pagelist); - } - -From fc0a0a8a198ad39fa58dd4e2b3efba0a89a9d627 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 09:10:36 +0100 -Subject: [PATCH 107/204] BCM270X_DT: Overlay for the Fen Logic VGA666 board - -The VGA666 board requires GPIOs 2-21 (so no I2C or UART). Using the -overlay (instead of a custom dt-blob.bin) has the advantage that it will -reserve those pins and stop other devices using them (except for GPIO), -but it does delay the point at which the output becomes valid until 2-3 -seconds after the kernel has started. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 +++++++ - arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 +++++++++++++++++++++++++++ - 3 files changed, 39 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index e91548c..74ec825 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -43,6 +43,7 @@ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 980d358..5e1f530 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -497,6 +497,14 @@ Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) - rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - -+Name: vga666 -+Info: Overlay for the Fen Logic VGA666 board -+ This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds -+ after the kernel has started. -+Load: dtoverlay=vga666 -+Params: -+ -+ - Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. -diff --git a/arch/arm/boot/dts/overlays/vga666-overlay.dts b/arch/arm/boot/dts/overlays/vga666-overlay.dts -new file mode 100644 -index 0000000..7fcab96 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vga666-overlay.dts -@@ -0,0 +1,30 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ // There is no VGA driver module, but we need a platform device -+ // node (that doesn't already use pinctrl) to hang the pinctrl -+ // reference on - leds will do -+ -+ fragment@0 { -+ target = <&leds>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vga666_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ vga666_pins: vga666_pins { -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 -+ 13 14 15 16 17 18 19 20 21>; -+ brcm,function = <6>; /* alt2 */ -+ brcm,pull = <0>; /* no pull */ -+ }; -+ }; -+ }; -+}; - -From c9eb6844bc315ee5ab2c807f873ca04d45fc6303 Mon Sep 17 00:00:00 2001 -From: petit-miner -Date: Fri, 10 Jul 2015 13:59:18 +0200 -Subject: [PATCH 108/204] Added support for 2 mcp2515 CAN Bus IC - -See: https://github.com/raspberrypi/linux/issues/1018 - https://github.com/raspberrypi/linux/pull/1049 - https://github.com/raspberrypi/linux/pull/1052 ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 12 +++- - .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 69 ++++++++++++++++++++++ - 3 files changed, 81 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 74ec825..4ff9836 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,7 @@ dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 5e1f530..88ed678 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -328,7 +328,7 @@ Params: gpio_out_pin GPIO for output (default "17") - - - Name: mcp2515-can0 --Info: Configures the MCP2515 CAN controller -+Info: Configures the MCP2515 CAN controller on spi0.0 - Load: dtoverlay=mcp2515-can0,= - Params: oscillator Clock frequency for the CAN controller (Hz) - -@@ -337,6 +337,16 @@ Params: oscillator Clock frequency for the CAN controller (Hz) - interrupt GPIO for interrupt signal - - -+Name: mcp2515-can1 -+Info: Configures the MCP2515 CAN controller on spi0.1 -+Load: dtoverlay=mcp2515-can1,= -+Params: oscillator Clock frequency for the CAN controller (Hz) -+ -+ spimaxfrequency Maximum SPI frequence (Hz) -+ -+ interrupt GPIO for interrupt signal -+ -+ - Name: mmc - Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -new file mode 100644 -index 0000000..6bef9ae ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -0,0 +1,69 @@ -+/* -+ * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* disable spi-dev for spi0.1 */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ can1_pins: can1_pins { -+ brcm,pins = <25>; -+ brcm,function = <0>; /* input */ -+ }; -+ }; -+ }; -+ -+ /* the clock/oscillator of the can-controller */ -+ fragment@2 { -+ target-path = "/clocks"; -+ __overlay__ { -+ /* external oscillator of mcp2515 on spi0.1 */ -+ can1_osc: can1_osc { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <16000000>; -+ }; -+ }; -+ }; -+ -+ /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ can1: mcp2515@1 { -+ reg = <1>; -+ compatible = "microchip,mcp2515"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&can1_pins>; -+ spi-max-frequency = <10000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 0x2>; -+ clocks = <&can1_osc>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ oscillator = <&can1_osc>,"clock-frequency:0"; -+ spimaxfrequency = <&can1>,"spi-max-frequency:0"; -+ interrupt = <&can1_pins>,"brcm,pins:0",<&can1>,"interrupts:0"; -+ }; -+}; - -From 632d8b6abe925d8300a9c824856ea7c286d95229 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Tue, 5 May 2015 13:27:45 -0700 -Subject: [PATCH 109/204] mailbox: Enable BCM2835 mailbox support - -This mailbox driver provides a single mailbox channel to write 32-bit -values to the VPU and get a 32-bit response. The Raspberry Pi -firmware uses this mailbox channel to implement firmware calls, while -Roku 2 (despite being derived from the same firmware tree) doesn't. - -The driver was originally submitted by Lubomir, based on the -out-of-tree 2708 mailbox driver. Eric Anholt fixed it up for -upstreaming, with the major functional change being that it now has no -notion of multiple channels (since that is a firmware-dependent -concept) and instead the raspberrypi-firmware driver will do that -bit-twiddling in its own messages. -[Jassi: made the 'mbox_chan_ops' struct as const and removed a redundant -variable] - -Signed-off-by: Lubomir Rintel -Signed-off-by: Craig McGeachie -Signed-off-by: Eric Anholt -Acked-by: Stephen Warren -Signed-off-by: Jassi Brar ---- - drivers/mailbox/Kconfig | 9 ++ - drivers/mailbox/Makefile | 2 + - drivers/mailbox/bcm2835-mailbox.c | 216 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 227 insertions(+) - create mode 100644 drivers/mailbox/bcm2835-mailbox.c - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 7f19cb4..dc64c93 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -66,4 +66,13 @@ config ALTERA_MBOX - An implementation of the Altera Mailbox soft core. It is used - to send message between processors. Say Y here if you want to use the - Altera mailbox support. -+ -+config BCM2835_MBOX -+ tristate "BCM2835 Mailbox" -+ depends on ARCH_BCM2835 -+ help -+ An implementation of the BCM2385 Mailbox. It is used to invoke -+ the services of the Videocore. Say Y here if you want to use the -+ BCM2835 Mailbox. -+ - endif -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index cecfad3..c86bc91 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -13,3 +13,5 @@ obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o - obj-$(CONFIG_PCC) += pcc.o - - obj-$(CONFIG_ALTERA_MBOX) += mailbox-altera.o -+ -+obj-$(CONFIG_BCM2835_MBOX) += bcm2835-mailbox.o -diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c -new file mode 100644 -index 0000000..4b13268 ---- /dev/null -+++ b/drivers/mailbox/bcm2835-mailbox.c -@@ -0,0 +1,216 @@ -+/* -+ * Copyright (C) 2010,2015 Broadcom -+ * Copyright (C) 2013-2014 Lubomir Rintel -+ * Copyright (C) 2013 Craig McGeachie -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a mechanism for writing to the mailboxes, -+ * that are shared between the ARM and the VideoCore processor -+ * -+ * Parts of the driver are based on: -+ * - arch/arm/mach-bcm2708/vcio.c file written by Gray Girling that was -+ * obtained from branch "rpi-3.6.y" of git://github.com/raspberrypi/ -+ * linux.git -+ * - drivers/mailbox/bcm2835-ipc.c by Lubomir Rintel at -+ * https://github.com/hackerspace/rpi-linux/blob/lr-raspberry-pi/drivers/ -+ * mailbox/bcm2835-ipc.c -+ * - documentation available on the following web site: -+ * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Mailboxes */ -+#define ARM_0_MAIL0 0x00 -+#define ARM_0_MAIL1 0x20 -+ -+/* -+ * Mailbox registers. We basically only support mailbox 0 & 1. We -+ * deliver to the VC in mailbox 1, it delivers to us in mailbox 0. See -+ * BCM2835-ARM-Peripherals.pdf section 1.3 for an explanation about -+ * the placement of memory barriers. -+ */ -+#define MAIL0_RD (ARM_0_MAIL0 + 0x00) -+#define MAIL0_POL (ARM_0_MAIL0 + 0x10) -+#define MAIL0_STA (ARM_0_MAIL0 + 0x18) -+#define MAIL0_CNF (ARM_0_MAIL0 + 0x1C) -+#define MAIL1_WRT (ARM_0_MAIL1 + 0x00) -+ -+/* Status register: FIFO state. */ -+#define ARM_MS_FULL BIT(31) -+#define ARM_MS_EMPTY BIT(30) -+ -+/* Configuration register: Enable interrupts. */ -+#define ARM_MC_IHAVEDATAIRQEN BIT(0) -+ -+struct bcm2835_mbox { -+ void __iomem *regs; -+ spinlock_t lock; -+ struct mbox_controller controller; -+}; -+ -+static struct bcm2835_mbox *bcm2835_link_mbox(struct mbox_chan *link) -+{ -+ return container_of(link->mbox, struct bcm2835_mbox, controller); -+} -+ -+static irqreturn_t bcm2835_mbox_irq(int irq, void *dev_id) -+{ -+ struct bcm2835_mbox *mbox = dev_id; -+ struct device *dev = mbox->controller.dev; -+ struct mbox_chan *link = &mbox->controller.chans[0]; -+ -+ while (!(readl(mbox->regs + MAIL0_STA) & ARM_MS_EMPTY)) { -+ u32 msg = readl(mbox->regs + MAIL0_RD); -+ dev_dbg(dev, "Reply 0x%08X\n", msg); -+ mbox_chan_received_data(link, &msg); -+ } -+ return IRQ_HANDLED; -+} -+ -+static int bcm2835_send_data(struct mbox_chan *link, void *data) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ u32 msg = *(u32 *)data; -+ -+ spin_lock(&mbox->lock); -+ writel(msg, mbox->regs + MAIL1_WRT); -+ dev_dbg(mbox->controller.dev, "Request 0x%08X\n", msg); -+ spin_unlock(&mbox->lock); -+ return 0; -+} -+ -+static int bcm2835_startup(struct mbox_chan *link) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox->regs + MAIL0_CNF); -+ -+ return 0; -+} -+ -+static void bcm2835_shutdown(struct mbox_chan *link) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ -+ writel(0, mbox->regs + MAIL0_CNF); -+} -+ -+static bool bcm2835_last_tx_done(struct mbox_chan *link) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ bool ret; -+ -+ spin_lock(&mbox->lock); -+ ret = !(readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL); -+ spin_unlock(&mbox->lock); -+ return ret; -+} -+ -+static const struct mbox_chan_ops bcm2835_mbox_chan_ops = { -+ .send_data = bcm2835_send_data, -+ .startup = bcm2835_startup, -+ .shutdown = bcm2835_shutdown, -+ .last_tx_done = bcm2835_last_tx_done -+}; -+ -+static struct mbox_chan *bcm2835_mbox_index_xlate(struct mbox_controller *mbox, -+ const struct of_phandle_args *sp) -+{ -+ if (sp->args_count != 0) -+ return NULL; -+ -+ return &mbox->chans[0]; -+} -+ -+static int bcm2835_mbox_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ int ret = 0; -+ struct resource *iomem; -+ struct bcm2835_mbox *mbox; -+ -+ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL); -+ if (mbox == NULL) -+ return -ENOMEM; -+ spin_lock_init(&mbox->lock); -+ -+ ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), -+ bcm2835_mbox_irq, 0, dev_name(dev), mbox); -+ if (ret) { -+ dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", -+ ret); -+ return -ENODEV; -+ } -+ -+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mbox->regs = devm_ioremap_resource(&pdev->dev, iomem); -+ if (IS_ERR(mbox->regs)) { -+ ret = PTR_ERR(mbox->regs); -+ dev_err(&pdev->dev, "Failed to remap mailbox regs: %d\n", ret); -+ return ret; -+ } -+ -+ mbox->controller.txdone_poll = true; -+ mbox->controller.txpoll_period = 5; -+ mbox->controller.ops = &bcm2835_mbox_chan_ops; -+ mbox->controller.of_xlate = &bcm2835_mbox_index_xlate; -+ mbox->controller.dev = dev; -+ mbox->controller.num_chans = 1; -+ mbox->controller.chans = devm_kzalloc(dev, -+ sizeof(*mbox->controller.chans), GFP_KERNEL); -+ if (!mbox->controller.chans) -+ return -ENOMEM; -+ -+ ret = mbox_controller_register(&mbox->controller); -+ if (ret) -+ return ret; -+ -+ platform_set_drvdata(pdev, mbox); -+ dev_info(dev, "mailbox enabled\n"); -+ -+ return ret; -+} -+ -+static int bcm2835_mbox_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_mbox *mbox = platform_get_drvdata(pdev); -+ mbox_controller_unregister(&mbox->controller); -+ return 0; -+} -+ -+static const struct of_device_id bcm2835_mbox_of_match[] = { -+ { .compatible = "brcm,bcm2835-mbox", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_mbox_of_match); -+ -+static struct platform_driver bcm2835_mbox_driver = { -+ .driver = { -+ .name = "bcm2835-mbox", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_mbox_of_match, -+ }, -+ .probe = bcm2835_mbox_probe, -+ .remove = bcm2835_mbox_remove, -+}; -+module_platform_driver(bcm2835_mbox_driver); -+ -+MODULE_AUTHOR("Lubomir Rintel "); -+MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); -+MODULE_LICENSE("GPL v2"); - -From d9468dc86cfdb7fed108e1e888979b622d578f71 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 13 May 2015 13:10:32 -0700 -Subject: [PATCH 110/204] mailbox/bcm2835: Fix mailbox full detection. - -With the VC reader blocked and the ARM writing, MAIL0_STA reads empty -permanently while MAIL1_STA goes from empty (0x40000000) to non-empty -(0x00000001-0x00000007) to full (0x80000008). - -This bug ended up having no effect on us, because all of our -transactions in the client driver were synchronous and under a mutex. - -Suggested-by: Phil Elwell -Signed-off-by: Eric Anholt -Acked-by: Stephen Warren -Signed-off-by: Jassi Brar ---- - drivers/mailbox/bcm2835-mailbox.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c -index 4b13268..0b47dd4 100644 ---- a/drivers/mailbox/bcm2835-mailbox.c -+++ b/drivers/mailbox/bcm2835-mailbox.c -@@ -49,6 +49,7 @@ - #define MAIL0_STA (ARM_0_MAIL0 + 0x18) - #define MAIL0_CNF (ARM_0_MAIL0 + 0x1C) - #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) -+#define MAIL1_STA (ARM_0_MAIL1 + 0x18) - - /* Status register: FIFO state. */ - #define ARM_MS_FULL BIT(31) -@@ -117,7 +118,7 @@ static bool bcm2835_last_tx_done(struct mbox_chan *link) - bool ret; - - spin_lock(&mbox->lock); -- ret = !(readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL); -+ ret = !(readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL); - spin_unlock(&mbox->lock); - return ret; - } - -From 518512c73c439f3684fbe42f07048b79be906f4a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:19:30 +0200 -Subject: [PATCH 111/204] mailbox: bcm2835: Support ARCH_BCM270x -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make it possible to use bcm2835-mailbox without Device Tree. -Load driver early because of lacking support for deferred probing -in many drivers. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 2 +- - drivers/mailbox/bcm2835-mailbox.c | 18 ++++++++++++++++-- - drivers/mailbox/mailbox.c | 13 ++++++++++++- - 3 files changed, 29 insertions(+), 4 deletions(-) - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index dc64c93..962b80c 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -69,7 +69,7 @@ config ALTERA_MBOX - - config BCM2835_MBOX - tristate "BCM2835 Mailbox" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - help - An implementation of the BCM2385 Mailbox. It is used to invoke - the services of the Videocore. Say Y here if you want to use the -diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c -index 0b47dd4..d16e286 100644 ---- a/drivers/mailbox/bcm2835-mailbox.c -+++ b/drivers/mailbox/bcm2835-mailbox.c -@@ -51,12 +51,15 @@ - #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) - #define MAIL1_STA (ARM_0_MAIL1 + 0x18) - -+/* On ARCH_BCM270x these come through (arm_control.h ) */ -+#ifndef ARM_MS_FULL - /* Status register: FIFO state. */ - #define ARM_MS_FULL BIT(31) - #define ARM_MS_EMPTY BIT(30) - - /* Configuration register: Enable interrupts. */ - #define ARM_MC_IHAVEDATAIRQEN BIT(0) -+#endif - - struct bcm2835_mbox { - void __iomem *regs; -@@ -151,7 +154,7 @@ static int bcm2835_mbox_probe(struct platform_device *pdev) - return -ENOMEM; - spin_lock_init(&mbox->lock); - -- ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), -+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), - bcm2835_mbox_irq, 0, dev_name(dev), mbox); - if (ret) { - dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", -@@ -210,7 +213,18 @@ static struct platform_driver bcm2835_mbox_driver = { - .probe = bcm2835_mbox_probe, - .remove = bcm2835_mbox_remove, - }; --module_platform_driver(bcm2835_mbox_driver); -+ -+static int __init bcm2835_mbox_init(void) -+{ -+ return platform_driver_register(&bcm2835_mbox_driver); -+} -+arch_initcall(bcm2835_mbox_init); -+ -+static void __init bcm2835_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm2835_mbox_driver); -+} -+module_exit(bcm2835_mbox_exit); - - MODULE_AUTHOR("Lubomir Rintel "); - MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); -diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c -index 19b491d..cc07d71 100644 ---- a/drivers/mailbox/mailbox.c -+++ b/drivers/mailbox/mailbox.c -@@ -304,13 +304,23 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) - unsigned long flags; - int ret; - -- if (!dev || !dev->of_node) { -+ if (!dev) { - pr_debug("%s: No owner device node\n", __func__); - return ERR_PTR(-ENODEV); - } - - mutex_lock(&con_mutex); - -+ if (!dev->of_node) { -+ chan = NULL; -+ /* pick the first controller in the list */ -+ list_for_each_entry(mbox, &mbox_cons, node) { -+ chan = &mbox->chans[0]; -+ break; -+ } -+ goto skip_dt; -+ } -+ - if (of_parse_phandle_with_args(dev->of_node, "mboxes", - "#mbox-cells", index, &spec)) { - dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__); -@@ -327,6 +337,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) - - of_node_put(spec.np); - -+skip_dt: - if (!chan || chan->cl || !try_module_get(mbox->dev->driver->owner)) { - dev_dbg(dev, "%s: mailbox not free\n", __func__); - mutex_unlock(&con_mutex); - -From 69b0fd32b30439447e33723fde68aadaed7d9b42 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Jun 2015 13:11:47 -0700 -Subject: [PATCH 112/204] ARM: bcm2835: Add the firmware driver information to - the RPi DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Eric Anholt -Acked-by: Lee Jones (previous version with pm-domains) -Acked-by: Stephen Warren -[Rebased on rpi-4.1.y] -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index 466f02b..5cdfd5a 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -27,6 +27,13 @@ - }; - }; - -+ soc { -+ firmware: firmware { -+ compatible = "raspberrypi,bcm2835-firmware"; -+ mboxes = <&mailbox>; -+ }; -+ }; -+ - /* Onboard audio */ - audio: audio { - compatible = "brcm,bcm2835-audio"; - -From 0438cbca296cfb3bc165b1f54c4e16f57f5760f0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:21:20 +0200 -Subject: [PATCH 113/204] firmware: bcm2835: Add missing property tags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index 9d9efb7..d3933af 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -60,6 +60,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, - RPI_FIRMWARE_GET_TURBO = 0x00030009, - RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, -+ RPI_FIRMWARE_GET_STC = 0x0003000b, - RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, - RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, - RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, -@@ -69,10 +70,12 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, - RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, - RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, -+ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, - RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, - RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, - RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, - RPI_FIRMWARE_SET_TURBO = 0x00038009, -+ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, - - /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -@@ -86,6 +89,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, - RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -@@ -95,6 +99,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, - RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, - RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, -@@ -103,6 +108,9 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, -+ -+ RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - -From 2df587b5e056fb8a0eba5efc2023533efb2807be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:25:01 +0200 -Subject: [PATCH 114/204] firmware: bcm2835: Support ARCH_BCM270x -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Support booting without Device Tree. -Turn on USB power. -Load driver early because of lacking support for deferred probing -in many drivers. - -Signed-off-by: Noralf Trønnes ---- - drivers/firmware/raspberrypi.c | 41 +++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 39 insertions(+), 2 deletions(-) - -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -index dd506cd3..b980d53 100644 ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -28,6 +28,8 @@ struct rpi_firmware { - u32 enabled; - }; - -+static struct platform_device *g_pdev; -+ - static DEFINE_MUTEX(transaction_lock); - - static void response_callback(struct mbox_client *cl, void *msg) -@@ -183,6 +185,25 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) - } - } - -+static int raspberrypi_firmware_set_power(struct rpi_firmware *fw, -+ u32 domain, bool on) -+{ -+ struct { -+ u32 domain; -+ u32 on; -+ } packet; -+ int ret; -+ -+ packet.domain = domain; -+ packet.on = on; -+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POWER_STATE, -+ &packet, sizeof(packet)); -+ if (!ret && packet.on != on) -+ ret = -EINVAL; -+ -+ return ret; -+} -+ - static int rpi_firmware_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -207,9 +228,13 @@ static int rpi_firmware_probe(struct platform_device *pdev) - init_completion(&fw->c); - - platform_set_drvdata(pdev, fw); -+ g_pdev = pdev; - - rpi_firmware_print_firmware_revision(fw); - -+ if (raspberrypi_firmware_set_power(fw, 3, true)) -+ dev_err(dev, "failed to turn on USB power\n"); -+ - return 0; - } - -@@ -218,6 +243,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) - struct rpi_firmware *fw = platform_get_drvdata(pdev); - - mbox_free_channel(fw->chan); -+ g_pdev = NULL; - - return 0; - } -@@ -230,7 +256,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) - */ - struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) - { -- struct platform_device *pdev = of_find_device_by_node(firmware_node); -+ struct platform_device *pdev = g_pdev; - - if (!pdev) - return NULL; -@@ -253,7 +279,18 @@ static struct platform_driver rpi_firmware_driver = { - .probe = rpi_firmware_probe, - .remove = rpi_firmware_remove, - }; --module_platform_driver(rpi_firmware_driver); -+ -+static int __init rpi_firmware_init(void) -+{ -+ return platform_driver_register(&rpi_firmware_driver); -+} -+subsys_initcall(rpi_firmware_init); -+ -+static void __init rpi_firmware_exit(void) -+{ -+ platform_driver_unregister(&rpi_firmware_driver); -+} -+module_exit(rpi_firmware_exit); - - MODULE_AUTHOR("Eric Anholt "); - MODULE_DESCRIPTION("Raspberry Pi firmware driver"); - -From c9295b68944211995a84d596a904f9657b4482c6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:26:10 +0200 -Subject: [PATCH 115/204] firmware: bcm2835: Support legacy mailbox API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for the bcm_mailbox_*() functions. -This is temporary until all drivers have been converted to the -firmware API (rpi_firmware_property*()). - -Signed-off-by: Noralf Trønnes ---- - drivers/firmware/raspberrypi.c | 15 +++++++++++++-- - include/soc/bcm2835/raspberrypi-firmware.h | 2 ++ - 2 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -index b980d53..89421a9 100644 ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -19,6 +19,7 @@ - #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) - #define MBOX_CHAN(msg) ((msg) & 0xf) - #define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_CHAN_VCHIQ 3 - #define MBOX_CHAN_PROPERTY 8 - - struct rpi_firmware { -@@ -26,6 +27,7 @@ struct rpi_firmware { - struct mbox_chan *chan; /* The property channel. */ - struct completion c; - u32 enabled; -+ u32 received; - }; - - static struct platform_device *g_pdev; -@@ -35,6 +37,7 @@ static DEFINE_MUTEX(transaction_lock); - static void response_callback(struct mbox_client *cl, void *msg) - { - struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); -+ fw->received = *(u32 *)msg; - complete(&fw->c); - } - -@@ -42,7 +45,7 @@ static void response_callback(struct mbox_client *cl, void *msg) - * Sends a request to the firmware through the BCM2835 mailbox driver, - * and synchronously waits for the reply. - */ --static int -+int - rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - { - u32 message = MBOX_MSG(chan, data); -@@ -54,7 +57,8 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - reinit_completion(&fw->c); - ret = mbox_send_message(fw->chan, &message); - if (ret >= 0) { -- wait_for_completion(&fw->c); -+ if (chan != MBOX_CHAN_VCHIQ) -+ wait_for_completion(&fw->c); - ret = 0; - } else { - dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); -@@ -63,6 +67,13 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - - return ret; - } -+EXPORT_SYMBOL(rpi_firmware_transaction); -+ -+u32 rpi_firmware_transaction_received(struct rpi_firmware *fw) -+{ -+ return MBOX_DATA28(fw->received); -+} -+EXPORT_SYMBOL(rpi_firmware_transaction_received); - - /** - * rpi_firmware_property_list - Submit firmware property list -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index d3933af..9a08cf1 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -116,6 +116,8 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - }; - -+int rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data); -+u32 rpi_firmware_transaction_received(struct rpi_firmware *fw); - int rpi_firmware_property(struct rpi_firmware *fw, - u32 tag, void *data, size_t len); - int rpi_firmware_property_list(struct rpi_firmware *fw, - -From 2f10d2c9d55ec24c07d869e591d7db9fdde5dfa6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:27:06 +0200 -Subject: [PATCH 116/204] char: broadcom: Add vcio module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add module for accessing the mailbox property channel through -/dev/vcio. Was previously in bcm2708-vcio. - -Signed-off-by: Noralf Trønnes ---- - drivers/char/broadcom/Kconfig | 6 ++ - drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/vcio.c | 175 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 182 insertions(+) - create mode 100644 drivers/char/broadcom/vcio.c - -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index 75fa1cb..fc40846 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -22,6 +22,12 @@ config BCM2708_VCMEM - help - Helper for videocore memory access and total size allocation. - -+config BCM_VCIO -+ tristate "Mailbox userspace access" -+ depends on BCM2835_MBOX -+ help -+ Gives access to the mailbox property channel from userspace. -+ - endif - - config BCM_VC_SM -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index de8feb9..18171e2 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -1,3 +1,4 @@ - obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -+obj-$(CONFIG_BCM_VCIO) += vcio.o - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ -diff --git a/drivers/char/broadcom/vcio.c b/drivers/char/broadcom/vcio.c -new file mode 100644 -index 0000000..c19bc20 ---- /dev/null -+++ b/drivers/char/broadcom/vcio.c -@@ -0,0 +1,175 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * Copyright (C) 2015 Noralf Trønnes -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MBOX_CHAN_PROPERTY 8 -+ -+#define VCIO_IOC_MAGIC 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) -+ -+static struct { -+ dev_t devt; -+ struct cdev cdev; -+ struct class *class; -+ struct rpi_firmware *fw; -+} vcio; -+ -+static int vcio_user_property_list(void *user) -+{ -+ u32 *buf, size; -+ int ret; -+ -+ /* The first 32-bit is the size of the buffer */ -+ if (copy_from_user(&size, user, sizeof(size))) -+ return -EFAULT; -+ -+ buf = kmalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, user, size)) { -+ kfree(buf); -+ return -EFAULT; -+ } -+ -+ /* Strip off protocol encapsulation */ -+ ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); -+ if (ret) { -+ kfree(buf); -+ return ret; -+ } -+ -+ buf[1] = RPI_FIRMWARE_STATUS_SUCCESS; -+ if (copy_to_user(user, buf, size)) -+ ret = -EFAULT; -+ -+ kfree(buf); -+ -+ return ret; -+} -+ -+static int vcio_device_open(struct inode *inode, struct file *file) -+{ -+ try_module_get(THIS_MODULE); -+ -+ return 0; -+} -+ -+static int vcio_device_release(struct inode *inode, struct file *file) -+{ -+ module_put(THIS_MODULE); -+ -+ return 0; -+} -+ -+static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ return vcio_user_property_list((void *)ioctl_param); -+ default: -+ pr_err("unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+} -+ -+const struct file_operations vcio_fops = { -+ .unlocked_ioctl = vcio_device_ioctl, -+ .open = vcio_device_open, -+ .release = vcio_device_release, -+}; -+ -+static int __init vcio_init(void) -+{ -+ struct device_node *np; -+ static struct device *dev; -+ int ret; -+ -+ np = of_find_compatible_node(NULL, NULL, -+ "raspberrypi,bcm2835-firmware"); -+/* Uncomment this when we only boot with Device Tree -+ if (!of_device_is_available(np)) -+ return -ENODEV; -+*/ -+ vcio.fw = rpi_firmware_get(np); -+ if (!vcio.fw) -+ return -ENODEV; -+ -+ ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); -+ if (ret) { -+ pr_err("failed to allocate device number\n"); -+ return ret; -+ } -+ -+ cdev_init(&vcio.cdev, &vcio_fops); -+ vcio.cdev.owner = THIS_MODULE; -+ ret = cdev_add(&vcio.cdev, vcio.devt, 1); -+ if (ret) { -+ pr_err("failed to register device\n"); -+ goto err_unregister_chardev; -+ } -+ -+ /* -+ * Create sysfs entries -+ * 'bcm2708_vcio' is used for backwards compatibility so we don't break -+ * userspace. Raspian has a udev rule that changes the permissions. -+ */ -+ vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); -+ if (IS_ERR(vcio.class)) { -+ ret = PTR_ERR(vcio.class); -+ pr_err("failed to create class\n"); -+ goto err_cdev_del; -+ } -+ -+ dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); -+ if (IS_ERR(dev)) { -+ ret = PTR_ERR(dev); -+ pr_err("failed to create device\n"); -+ goto err_class_destroy; -+ } -+ -+ return 0; -+ -+err_class_destroy: -+ class_destroy(vcio.class); -+err_cdev_del: -+ cdev_del(&vcio.cdev); -+err_unregister_chardev: -+ unregister_chrdev_region(vcio.devt, 1); -+ -+ return ret; -+} -+module_init(vcio_init); -+ -+static void __exit vcio_exit(void) -+{ -+ device_destroy(vcio.class, vcio.devt); -+ class_destroy(vcio.class); -+ cdev_del(&vcio.cdev); -+ unregister_chrdev_region(vcio.devt, 1); -+} -+module_exit(vcio_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_AUTHOR("Noralf Trønnes"); -+MODULE_DESCRIPTION("Mailbox userspace access"); -+MODULE_LICENSE("GPL"); - -From 8bcd6e604c131b2009b0d9e47561cead558c3d82 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:37:19 +0200 -Subject: [PATCH 117/204] BCM270x: Switch to firmware driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -defconfig: enable BCM2835_MBOX, RASPBERRYPI_FIRMWARE and BCM_VCIO. -Add firmware node and change mailbox node in Device Tree. -Add/update platform file for firmware and mailbox. -Strip bcm2708-vcio of everything except the legacy API and hook it -up with the firmware driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 8 +- - arch/arm/configs/bcm2709_defconfig | 3 + - arch/arm/configs/bcmrpi_defconfig | 3 + - arch/arm/mach-bcm2708/bcm2708.c | 13 +- - arch/arm/mach-bcm2709/bcm2709.c | 13 +- - drivers/mailbox/Kconfig | 2 +- - drivers/mailbox/bcm2708-vcio.c | 353 ++-------------------------------- - 7 files changed, 51 insertions(+), 344 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index abf3e5d..2dd25f7 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -74,9 +74,10 @@ - }; - - mailbox: mailbox@7e00b800 { -- compatible = "brcm,bcm2708-vcio"; -+ compatible = "brcm,bcm2835-mbox"; - reg = <0x7e00b880 0x40>; - interrupts = <0 1>; -+ #mbox-cells = <0>; - }; - - watchdog: watchdog@7e100000 { -@@ -205,6 +206,11 @@ - <1 9>; - }; - -+ firmware: firmware { -+ compatible = "raspberrypi,bcm2835-firmware"; -+ mboxes = <&mailbox>; -+ }; -+ - leds: leds { - compatible = "gpio-leds"; - }; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 5ecd84f..d75b104 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -574,6 +574,7 @@ CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y - CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y - CONFIG_BCM_VC_SM=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1074,6 +1075,7 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -@@ -1082,6 +1084,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y - CONFIG_EXT4_FS_SECURITY=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 14b91fdf..9159892 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -567,6 +567,7 @@ CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y - CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y - CONFIG_BCM_VC_SM=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1067,6 +1068,7 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -@@ -1075,6 +1077,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y - CONFIG_EXT4_FS_SECURITY=y -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 937c2d3..1b9c3be 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -405,7 +405,7 @@ static struct resource bcm2708_vcio_resources[] = { - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = "bcm2708_vcio", -+ .name = "bcm2835-mbox", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -@@ -415,6 +415,16 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_rpifw_device = { -+ .name = "raspberrypi-firmware", -+ .dev = { -+ .dma_mask = &rpifw_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - static struct resource bcm2708_vchiq_resources[] = { - { - .start = ARMCTRL_0_BELL_BASE, -@@ -871,6 +881,7 @@ void __init bcm2708_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_rpifw_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index fe71c50..e1934dc 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -426,7 +426,7 @@ static struct resource bcm2708_vcio_resources[] = { - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = "bcm2708_vcio", -+ .name = "bcm2835-mbox", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -@@ -436,6 +436,16 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_rpifw_device = { -+ .name = "raspberrypi-firmware", -+ .dev = { -+ .dma_mask = &rpifw_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - static struct resource bcm2708_vchiq_resources[] = { - { - .start = ARMCTRL_0_BELL_BASE, -@@ -892,6 +902,7 @@ void __init bcm2709_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_rpifw_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 962b80c..d1a6671 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -9,7 +9,7 @@ if MAILBOX - - config BCM2708_MBOX - bool "Broadcom BCM2708 Mailbox (vcio)" -- depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ depends on BCM2835_MBOX - help - Broadcom BCM2708 Mailbox (vcio) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index 06fb2c2f..2e4031b 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -1,6 +1,4 @@ - /* -- * linux/arch/arm/mach-bcm2708/vcio.c -- * - * Copyright (C) 2010 Broadcom - * - * This program is free software; you can redistribute it and/or modify -@@ -12,195 +10,38 @@ - * VideoCore processor - */ - --#include - #include --#include --#include --#include - #include --#include --#include --#include -+#include - #include --#include - #include -+#include - - #define DRIVER_NAME "bcm2708_vcio" --#define DEVICE_FILE_NAME "vcio" -- --/* offsets from a mail box base address */ --#define MAIL0_RD 0x00 /* read - and next 4 words */ --#define MAIL0_POL 0x10 /* read without popping the fifo */ --#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL0_STA 0x18 /* status */ --#define MAIL0_CNF 0x1C /* configuration */ --#define MAIL1_WRT 0x20 /* write - and next 4 words */ --#define MAIL1_STA 0x38 /* status */ -- --/* On MACH_BCM270x these come through (arm_control.h ) */ --#ifndef ARM_MS_EMPTY --#define ARM_MS_EMPTY BIT(30) --#define ARM_MS_FULL BIT(31) -- --#define ARM_MC_IHAVEDATAIRQEN BIT(0) --#endif -- --#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) --#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) --#define MBOX_CHAN(msg) ((msg) & 0xf) --#define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -- --#define MBOX_MAGIC 0xd0d0c0de -- --#define MAJOR_NUM 100 --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -- --static struct class *vcio_class; -- --struct vc_mailbox { -- void __iomem *regs; -- uint32_t msg[MBOX_CHAN_COUNT]; -- struct semaphore sema[MBOX_CHAN_COUNT]; -- uint32_t magic; --}; -- --static void mbox_init(struct vc_mailbox *mbox_out) --{ -- int i; -- -- for (i = 0; i < MBOX_CHAN_COUNT; i++) { -- mbox_out->msg[i] = 0; -- sema_init(&mbox_out->sema[i], 0); -- } -- -- /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -- -- mbox_out->magic = MBOX_MAGIC; --} -- --static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) -- cpu_relax(); -- -- writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -- -- return 0; --} -- --static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- -- return 0; --} -- --static irqreturn_t mbox_irq_handler(int irq, void *dev_id) --{ -- /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -- int status = readl(mbox->regs + MAIL0_STA); -- int ret = IRQ_NONE; -- -- while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->regs + MAIL0_RD); -- int chan = MBOX_CHAN(msg); -- -- if (chan < MBOX_CHAN_COUNT) { -- if (mbox->msg[chan]) { -- pr_err(DRIVER_NAME -- ": mbox chan %d overflow - drop %08x\n", -- chan, msg); -- } else { -- mbox->msg[chan] = (msg | 0xf); -- up(&mbox->sema[chan]); -- } -- } else { -- pr_err(DRIVER_NAME -- ": invalid channel selector (msg %08x)\n", msg); -- } -- ret = IRQ_HANDLED; -- status = readl(mbox->regs + MAIL0_STA); -- } -- return ret; --} -- --/* Mailbox Methods */ -- --static struct device *mbox_dev; /* we assume there's only one! */ -- --static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_write(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_read(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} - - extern int bcm_mailbox_write(unsigned chan, uint32_t data28) - { -- if (!mbox_dev) -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); -+ -+ if (!fw) - return -ENODEV; - -- return dev_mbox_write(mbox_dev, chan, data28); -+ return rpi_firmware_transaction(fw, chan, data28); - } - EXPORT_SYMBOL_GPL(bcm_mailbox_write); - - extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) - { -- if (!mbox_dev) -- return -ENODEV; -- -- return dev_mbox_read(mbox_dev, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); - --static int mbox_copy_from_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)src < TASK_SIZE) -- return copy_from_user(dst, src, size); -- -- memcpy(dst, src, size); -- -- return 0; --} -- --static int mbox_copy_to_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)dst < TASK_SIZE) -- return copy_to_user(dst, src, size); -+ if (!fw) -+ return -ENODEV; - -- memcpy(dst, src, size); -+ *data28 = rpi_firmware_transaction_received(fw); - - return 0; - } -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); - - static DEFINE_MUTEX(mailbox_lock); - extern int bcm_mailbox_property(void *data, int size) -@@ -216,7 +57,7 @@ extern int bcm_mailbox_property(void *data, int size) - GFP_KERNEL); - if (mem_kern) { - /* create the message */ -- mbox_copy_from_user(mem_kern, data, size); -+ memcpy(mem_kern, data, size); - - /* send the message */ - wmb(); -@@ -226,7 +67,7 @@ extern int bcm_mailbox_property(void *data, int size) - if (s == 0) { - /* copy the response */ - rmb(); -- mbox_copy_to_user(data, mem_kern, size); -+ memcpy(data, mem_kern, size); - } - dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); - } else { -@@ -240,174 +81,6 @@ extern int bcm_mailbox_property(void *data, int size) - } - EXPORT_SYMBOL_GPL(bcm_mailbox_property); - --/* Platform Device for Mailbox */ -- --/* This is called whenever a process attempts to open the device file */ --static int device_open(struct inode *inode, struct file *file) --{ -- try_module_get(THIS_MODULE); -- -- return 0; --} -- --static int device_release(struct inode *inode, struct file *file) --{ -- module_put(THIS_MODULE); -- -- return 0; --} -- --/* -- * This function is called whenever a process tries to do an ioctl on our -- * device file. We get two extra parameters (additional to the inode and file -- * structures, which all device functions get): the number of the ioctl called -- * and the parameter given to the ioctl function. -- * -- * If the ioctl is write or read/write (meaning output is returned to the -- * calling process), the ioctl call returns the output of this function. -- * -- */ --static long device_ioctl(struct file *file, unsigned int ioctl_num, -- unsigned long ioctl_param) --{ -- unsigned size; -- -- switch (ioctl_num) { -- case IOCTL_MBOX_PROPERTY: -- /* -- * Receive a pointer to a message (in user space) and set that -- * to be the device's message. Get the parameter given to -- * ioctl by the process. -- */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -- return bcm_mailbox_property((void *)ioctl_param, size); -- default: -- pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -- return -EINVAL; -- } -- -- return 0; --} -- --/* Module Declarations */ -- --/* -- * This structure will hold the functions to be called -- * when a process does something to the device we -- * created. Since a pointer to this structure is kept in -- * the devices table, it can't be local to -- * init_module. NULL is for unimplemented functios. -- */ --const struct file_operations fops = { -- .unlocked_ioctl = device_ioctl, -- .open = device_open, -- .release = device_release, /* a.k.a. close */ --}; -- --static int bcm_vcio_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct device *vdev; -- struct vc_mailbox *mailbox; -- struct resource *res; -- int irq, ret; -- -- mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -- if (!mailbox) -- return -ENOMEM; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- mailbox->regs = devm_ioremap_resource(dev, res); -- if (IS_ERR(mailbox->regs)) -- return PTR_ERR(mailbox->regs); -- -- irq = platform_get_irq(pdev, 0); -- ret = devm_request_irq(dev, irq, mbox_irq_handler, -- IRQF_IRQPOLL, -- dev_name(dev), mailbox); -- if (ret) { -- dev_err(dev, "Interrupt request failed %d\n", ret); -- return ret; -- } -- -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- if (ret < 0) { -- pr_err("Character device registration failed %d\n", ret); -- return ret; -- } -- -- vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- pr_err("Class creation failed %d\n", ret); -- goto err_class; -- } -- -- vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -- if (IS_ERR(vdev)) { -- ret = PTR_ERR(vdev); -- pr_err("Device creation failed %d\n", ret); -- goto err_dev; -- } -- -- mbox_init(mailbox); -- platform_set_drvdata(pdev, mailbox); -- mbox_dev = dev; -- -- dev_info(dev, "mailbox at %p\n", mailbox->regs); -- -- return 0; -- --err_dev: -- class_destroy(vcio_class); --err_class: -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return ret; --} -- --static int bcm_vcio_remove(struct platform_device *pdev) --{ -- mbox_dev = NULL; -- platform_set_drvdata(pdev, NULL); -- device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return 0; --} -- --static const struct of_device_id bcm_vcio_of_match_table[] = { -- { .compatible = "brcm,bcm2708-vcio", }, -- {}, --}; --MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -- --static struct platform_driver bcm_mbox_driver = { -- .probe = bcm_vcio_probe, -- .remove = bcm_vcio_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- .of_match_table = bcm_vcio_of_match_table, -- }, --}; -- --static int __init bcm_mbox_init(void) --{ -- return platform_driver_register(&bcm_mbox_driver); --} -- --static void __exit bcm_mbox_exit(void) --{ -- platform_driver_unregister(&bcm_mbox_driver); --} -- --arch_initcall(bcm_mbox_init); /* Initialize early */ --module_exit(bcm_mbox_exit); -- - MODULE_AUTHOR("Gray Girling"); - MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); - MODULE_LICENSE("GPL"); - -From 51a7a4a822bc6ab6927bc0522e5afb6bda8f52b4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:39:21 +0200 -Subject: [PATCH 118/204] bcm2835: Switch to firmware driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -defconfig: enable BCM2835_MBOX, RASPBERRYPI_FIRMWARE and BCM_VCIO. - -Add firmware node and change mailbox node in Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 3 ++- - arch/arm/configs/bcm2835_defconfig | 3 +++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 4b6dd65f..4a63704 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -62,9 +62,10 @@ - }; - - mailbox: mailbox@7e00b800 { -- compatible = "brcm,bcm2708-vcio"; -+ compatible = "brcm,bcm2835-mbox"; - reg = <0x7e00b880 0x40>; - interrupts = <0 1>; -+ #mbox-cells = <0>; - }; - - gpio: gpio@7e200000 { -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 47f2a6a..c284414 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -568,6 +568,7 @@ CONFIG_HW_RANDOM_BCM2835=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y - CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y - CONFIG_BCM_VC_SM=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1064,9 +1065,11 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - CONFIG_EXT2_FS_POSIX_ACL=y - -From 46dd86c7b1dd676e614daca70ec3b7a31cc905f9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 13 Jul 2015 13:25:31 +0100 -Subject: [PATCH 119/204] Merge pull request #1059 from pelwell/rpi-4.0.y - -w1_therm: Back-port locking improvements from 4.2-rc1 ---- - Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 | 6 ++ - Documentation/w1/slaves/w1_therm | 11 ++- - drivers/w1/slaves/w1_therm.c | 102 +++++++++++++++++++++- - 3 files changed, 117 insertions(+), 2 deletions(-) - create mode 100644 Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 - -diff --git a/Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 b/Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 -new file mode 100644 -index 0000000..e928def ---- /dev/null -+++ b/Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 -@@ -0,0 +1,6 @@ -+What: /sys/bus/w1/devices/.../w1_seq -+Date: Apr 2015 -+Contact: Matt Campbell -+Description: Support for the DS28EA00 chain sequence function -+ see Documentation/w1/slaves/w1_therm for detailed information -+Users: any user space application which wants to communicate with DS28EA00 -diff --git a/Documentation/w1/slaves/w1_therm b/Documentation/w1/slaves/w1_therm -index cc62a95..13411fe 100644 ---- a/Documentation/w1/slaves/w1_therm -+++ b/Documentation/w1/slaves/w1_therm -@@ -11,12 +11,14 @@ Author: Evgeniy Polyakov - Description - ----------- - --w1_therm provides basic temperature conversion for ds18*20 devices. -+w1_therm provides basic temperature conversion for ds18*20 devices, and the -+ds28ea00 device. - supported family codes: - W1_THERM_DS18S20 0x10 - W1_THERM_DS1822 0x22 - W1_THERM_DS18B20 0x28 - W1_THERM_DS1825 0x3B -+W1_THERM_DS28EA00 0x42 - - Support is provided through the sysfs w1_slave file. Each open and - read sequence will initiate a temperature conversion then provide two -@@ -48,3 +50,10 @@ resistor). The DS18b20 temperature sensor specification lists a - maximum current draw of 1.5mA and that a 5k pullup resistor is not - sufficient. The strong pullup is designed to provide the additional - current required. -+ -+The DS28EA00 provides an additional two pins for implementing a sequence -+detection algorithm. This feature allows you to determine the physical -+location of the chip in the 1-wire bus without needing pre-existing -+knowledge of the bus ordering. Support is provided through the sysfs -+w1_seq file. The file will contain a single line with an integer value -+representing the device index in the bus starting at 0. -diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c -index 55eb86c..2f029e8 100644 ---- a/drivers/w1/slaves/w1_therm.c -+++ b/drivers/w1/slaves/w1_therm.c -@@ -92,13 +92,24 @@ static void w1_therm_remove_slave(struct w1_slave *sl) - static ssize_t w1_slave_show(struct device *device, - struct device_attribute *attr, char *buf); - -+static ssize_t w1_seq_show(struct device *device, -+ struct device_attribute *attr, char *buf); -+ - static DEVICE_ATTR_RO(w1_slave); -+static DEVICE_ATTR_RO(w1_seq); - - static struct attribute *w1_therm_attrs[] = { - &dev_attr_w1_slave.attr, - NULL, - }; -+ -+static struct attribute *w1_ds28ea00_attrs[] = { -+ &dev_attr_w1_slave.attr, -+ &dev_attr_w1_seq.attr, -+ NULL, -+}; - ATTRIBUTE_GROUPS(w1_therm); -+ATTRIBUTE_GROUPS(w1_ds28ea00); - - static struct w1_family_ops w1_therm_fops = { - .add_slave = w1_therm_add_slave, -@@ -106,6 +117,12 @@ static struct w1_family_ops w1_therm_fops = { - .groups = w1_therm_groups, - }; - -+static struct w1_family_ops w1_ds28ea00_fops = { -+ .add_slave = w1_therm_add_slave, -+ .remove_slave = w1_therm_remove_slave, -+ .groups = w1_ds28ea00_groups, -+}; -+ - static struct w1_family w1_therm_family_DS18S20 = { - .fid = W1_THERM_DS18S20, - .fops = &w1_therm_fops, -@@ -123,7 +140,7 @@ static struct w1_family w1_therm_family_DS1822 = { - - static struct w1_family w1_therm_family_DS28EA00 = { - .fid = W1_THERM_DS28EA00, -- .fops = &w1_therm_fops, -+ .fops = &w1_ds28ea00_fops, - }; - - static struct w1_family w1_therm_family_DS1825 = { -@@ -316,6 +333,89 @@ static ssize_t w1_slave_show(struct device *device, - return ret; - } - -+#define W1_42_CHAIN 0x99 -+#define W1_42_CHAIN_OFF 0x3C -+#define W1_42_CHAIN_OFF_INV 0xC3 -+#define W1_42_CHAIN_ON 0x5A -+#define W1_42_CHAIN_ON_INV 0xA5 -+#define W1_42_CHAIN_DONE 0x96 -+#define W1_42_CHAIN_DONE_INV 0x69 -+#define W1_42_COND_READ 0x0F -+#define W1_42_SUCCESS_CONFIRM_BYTE 0xAA -+#define W1_42_FINISHED_BYTE 0xFF -+static ssize_t w1_seq_show(struct device *device, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w1_slave *sl = dev_to_w1_slave(device); -+ ssize_t c = PAGE_SIZE; -+ int rv; -+ int i; -+ u8 ack; -+ u64 rn; -+ struct w1_reg_num *reg_num; -+ int seq = 0; -+ -+ mutex_lock(&sl->master->bus_mutex); -+ /* Place all devices in CHAIN state */ -+ if (w1_reset_bus(sl->master)) -+ goto error; -+ w1_write_8(sl->master, W1_SKIP_ROM); -+ w1_write_8(sl->master, W1_42_CHAIN); -+ w1_write_8(sl->master, W1_42_CHAIN_ON); -+ w1_write_8(sl->master, W1_42_CHAIN_ON_INV); -+ msleep(sl->master->pullup_duration); -+ -+ /* check for acknowledgment */ -+ ack = w1_read_8(sl->master); -+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE) -+ goto error; -+ -+ /* In case the bus fails to send 0xFF, limit*/ -+ for (i = 0; i <= 64; i++) { -+ if (w1_reset_bus(sl->master)) -+ goto error; -+ -+ w1_write_8(sl->master, W1_42_COND_READ); -+ rv = w1_read_block(sl->master, (u8 *)&rn, 8); -+ reg_num = (struct w1_reg_num *) &rn; -+ if (reg_num->family == W1_42_FINISHED_BYTE) -+ break; -+ if (sl->reg_num.id == reg_num->id) -+ seq = i; -+ -+ w1_write_8(sl->master, W1_42_CHAIN); -+ w1_write_8(sl->master, W1_42_CHAIN_DONE); -+ w1_write_8(sl->master, W1_42_CHAIN_DONE_INV); -+ w1_read_block(sl->master, &ack, sizeof(ack)); -+ -+ /* check for acknowledgment */ -+ ack = w1_read_8(sl->master); -+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE) -+ goto error; -+ -+ } -+ -+ /* Exit from CHAIN state */ -+ if (w1_reset_bus(sl->master)) -+ goto error; -+ w1_write_8(sl->master, W1_SKIP_ROM); -+ w1_write_8(sl->master, W1_42_CHAIN); -+ w1_write_8(sl->master, W1_42_CHAIN_OFF); -+ w1_write_8(sl->master, W1_42_CHAIN_OFF_INV); -+ -+ /* check for acknowledgment */ -+ ack = w1_read_8(sl->master); -+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE) -+ goto error; -+ mutex_unlock(&sl->master->bus_mutex); -+ -+ c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", seq); -+ return PAGE_SIZE - c; -+error: -+ mutex_unlock(&sl->master->bus_mutex); -+ return -EIO; -+} -+ - static int __init w1_therm_init(void) - { - int err, i; - -From 86a4624ee6bc33f41fd7f53d081096ed4aa28cca Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 11:11:51 +0100 -Subject: [PATCH 120/204] vchiq_arm: Sort out the vmalloc case - -See: https://github.com/raspberrypi/linux/issues/1055 ---- - .../misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 5edba23..56bff05 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -394,21 +394,21 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - if (is_vmalloc_addr(buf)) { - int dir = (type == PAGELIST_WRITE) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE; -- unsigned long length = pagelist->length; -- unsigned int offset = pagelist->offset; -+ unsigned long length = count; -+ unsigned int off = offset; - - for (actual_pages = 0; actual_pages < num_pages; - actual_pages++) { - struct page *pg = vmalloc_to_page(buf + (actual_pages * - PAGE_SIZE)); -- size_t bytes = PAGE_SIZE - offset; -+ size_t bytes = PAGE_SIZE - off; - - if (bytes > length) - bytes = length; - pages[actual_pages] = pg; -- dmac_map_area(page_address(pg) + offset, bytes, dir); -+ dmac_map_area(page_address(pg) + off, bytes, dir); - length -= bytes; -- offset = 0; -+ off = 0; - } - *need_release = 0; /* do not try and release vmalloc pages */ - } else { - -From 18952e8ccf8d64fb32bb7b2bbd04967047f02840 Mon Sep 17 00:00:00 2001 +From 16bad45bd62dfa5c591bf33b1725a4a391c2a18d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 121/204] spidev: Add "spidev" compatible string to silence +Subject: [PATCH 087/113] spidev: Add "spidev" compatible string to silence warning See: https://github.com/raspberrypi/linux/issues/1054 @@ -140242,44 +134471,4446 @@ See: https://github.com/raspberrypi/linux/issues/1054 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 8fab566..a9db602 100644 +index ef008e5..1a59226 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c -@@ -707,6 +707,7 @@ static struct class *spidev_class; - #ifdef CONFIG_OF +@@ -695,6 +695,7 @@ static struct class *spidev_class; static const struct of_device_id spidev_dt_ids[] = { { .compatible = "rohm,dh2228fv" }, + { .compatible = "lineartechnology,ltc2488" }, + { .compatible = "spidev" }, {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); -From 58f35e5dc8355250d21db3b7ba0aa560d76a0adc Mon Sep 17 00:00:00 2001 +From c75c13a442609aa49583c5bcd525c60a578337bb Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 14 Jul 2015 17:00:18 +0100 +Subject: [PATCH 088/113] scripts/dtc: Add overlay support + +--- + scripts/dtc/checks.c | 119 ++- + scripts/dtc/dtc-lexer.l | 5 + + scripts/dtc/dtc-lexer.lex.c_shipped | 490 ++++----- + scripts/dtc/dtc-parser.tab.c_shipped | 1896 +++++++++++++++++++--------------- + scripts/dtc/dtc-parser.tab.h_shipped | 107 +- + scripts/dtc/dtc-parser.y | 23 +- + scripts/dtc/dtc.c | 9 +- + scripts/dtc/dtc.h | 38 + + scripts/dtc/flattree.c | 141 ++- + scripts/dtc/version_gen.h | 2 +- + 10 files changed, 1685 insertions(+), 1145 deletions(-) + +diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c +index e81a8c7..efd1bc6 100644 +--- a/scripts/dtc/checks.c ++++ b/scripts/dtc/checks.c +@@ -458,21 +458,91 @@ static void fixup_phandle_references(struct check *c, struct node *dt, + struct node *node, struct property *prop) + { + struct marker *m = prop->val.markers; ++ struct fixup *f, **fp; ++ struct fixup_entry *fe, **fep; + struct node *refnode; + cell_t phandle; ++ int has_phandle_refs; ++ ++ has_phandle_refs = 0; ++ for_each_marker_of_type(m, REF_PHANDLE) { ++ has_phandle_refs = 1; ++ break; ++ } ++ ++ if (!has_phandle_refs) ++ return; + + for_each_marker_of_type(m, REF_PHANDLE) { + assert(m->offset + sizeof(cell_t) <= prop->val.len); + + refnode = get_node_by_ref(dt, m->ref); +- if (! refnode) { ++ if (!refnode && !symbol_fixup_support) { + FAIL(c, "Reference to non-existent node or label \"%s\"\n", +- m->ref); ++ m->ref); + continue; + } + +- phandle = get_node_phandle(dt, refnode); +- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); ++ if (!refnode) { ++ /* allocate fixup entry */ ++ fe = xmalloc(sizeof(*fe)); ++ ++ fe->node = node; ++ fe->prop = prop; ++ fe->offset = m->offset; ++ fe->next = NULL; ++ ++ /* search for an already existing fixup */ ++ for_each_fixup(dt, f) ++ if (strcmp(f->ref, m->ref) == 0) ++ break; ++ ++ /* no fixup found, add new */ ++ if (f == NULL) { ++ f = xmalloc(sizeof(*f)); ++ f->ref = m->ref; ++ f->entries = NULL; ++ f->next = NULL; ++ ++ /* add it to the tree */ ++ fp = &dt->fixups; ++ while (*fp) ++ fp = &(*fp)->next; ++ *fp = f; ++ } ++ ++ /* and now append fixup entry */ ++ fep = &f->entries; ++ while (*fep) ++ fep = &(*fep)->next; ++ *fep = fe; ++ ++ /* mark the entry as unresolved */ ++ phandle = 0xdeadbeef; ++ } else { ++ phandle = get_node_phandle(dt, refnode); ++ ++ /* if it's a plugin, we need to record it */ ++ if (symbol_fixup_support && dt->is_plugin) { ++ ++ /* allocate a new local fixup entry */ ++ fe = xmalloc(sizeof(*fe)); ++ ++ fe->node = node; ++ fe->prop = prop; ++ fe->offset = m->offset; ++ fe->next = NULL; ++ ++ /* append it to the local fixups */ ++ fep = &dt->local_fixups; ++ while (*fep) ++ fep = &(*fep)->next; ++ *fep = fe; ++ } ++ } ++ ++ *((cell_t *)(prop->val.val + m->offset)) = ++ cpu_to_fdt32(phandle); + } + } + ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, +@@ -652,6 +722,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, + } + TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); + ++static void check_auto_label_phandles(struct check *c, struct node *dt, ++ struct node *node) ++{ ++ struct label *l; ++ struct symbol *s, **sp; ++ int has_label; ++ ++ if (!symbol_fixup_support) ++ return; ++ ++ has_label = 0; ++ for_each_label(node->labels, l) { ++ has_label = 1; ++ break; ++ } ++ ++ if (!has_label) ++ return; ++ ++ /* force allocation of a phandle for this node */ ++ (void)get_node_phandle(dt, node); ++ ++ /* add the symbol */ ++ for_each_label(node->labels, l) { ++ ++ s = xmalloc(sizeof(*s)); ++ s->label = l; ++ s->node = node; ++ s->next = NULL; ++ ++ /* add it to the symbols list */ ++ sp = &dt->symbols; ++ while (*sp) ++ sp = &((*sp)->next); ++ *sp = s; ++ } ++} ++NODE_WARNING(auto_label_phandles, NULL); ++ + static struct check *check_table[] = { + &duplicate_node_names, &duplicate_property_names, + &node_name_chars, &node_name_format, &property_name_chars, +@@ -670,6 +779,8 @@ static struct check *check_table[] = { + &avoid_default_addr_size, + &obsolete_chosen_interrupt_controller, + ++ &auto_label_phandles, ++ + &always_fail, + }; + +diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l +index 0ee1caf0..dd44ba2 100644 +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...); + return DT_V1; + } + ++<*>"/plugin/" { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ + <*>"/memreserve/" { + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); +diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped +index 11cd78e..1518525 100644 +--- a/scripts/dtc/dtc-lexer.lex.c_shipped ++++ b/scripts/dtc/dtc-lexer.lex.c_shipped +@@ -9,7 +9,7 @@ + #define FLEX_SCANNER + #define YY_FLEX_MAJOR_VERSION 2 + #define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 39 ++#define YY_FLEX_SUBMINOR_VERSION 35 + #if YY_FLEX_SUBMINOR_VERSION > 0 + #define FLEX_BETA + #endif +@@ -162,12 +162,7 @@ typedef unsigned int flex_uint32_t; + typedef struct yy_buffer_state *YY_BUFFER_STATE; + #endif + +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-extern yy_size_t yyleng; ++extern int yyleng; + + extern FILE *yyin, *yyout; + +@@ -176,7 +171,6 @@ extern FILE *yyin, *yyout; + #define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) +- #define YY_LINENO_REWIND_TO(ptr) + + /* Return all but the first "n" matched characters back to the input stream. */ + #define yyless(n) \ +@@ -194,6 +188,11 @@ extern FILE *yyin, *yyout; + + #define unput(c) yyunput( c, (yytext_ptr) ) + ++#ifndef YY_TYPEDEF_YY_SIZE_T ++#define YY_TYPEDEF_YY_SIZE_T ++typedef size_t yy_size_t; ++#endif ++ + #ifndef YY_STRUCT_YY_BUFFER_STATE + #define YY_STRUCT_YY_BUFFER_STATE + struct yy_buffer_state +@@ -211,7 +210,7 @@ struct yy_buffer_state + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ +- yy_size_t yy_n_chars; ++ int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to +@@ -281,8 +280,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + + /* yy_hold_char holds the character lost when yytext is formed. */ + static char yy_hold_char; +-static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +-yy_size_t yyleng; ++static int yy_n_chars; /* number of characters read into yy_ch_buf */ ++int yyleng; + + /* Points to current character in buffer. */ + static char *yy_c_buf_p = (char *) 0; +@@ -310,7 +309,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + + YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); + YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); ++YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + + void *yyalloc (yy_size_t ); + void *yyrealloc (void *,yy_size_t ); +@@ -342,7 +341,7 @@ void yyfree (void * ); + + /* Begin user sect3 */ + +-#define yywrap() 1 ++#define yywrap(n) 1 + #define YY_SKIP_YYWRAP + + typedef unsigned char YY_CHAR; +@@ -373,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +-#define YY_NUM_RULES 30 +-#define YY_END_OF_BUFFER 31 ++#define YY_NUM_RULES 31 ++#define YY_END_OF_BUFFER 32 + /* This struct is not used in this scanner, + but its presence is necessary. */ + struct yy_trans_info +@@ -382,25 +381,26 @@ struct yy_trans_info + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +-static yyconst flex_int16_t yy_accept[159] = ++static yyconst flex_int16_t yy_accept[166] = + { 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, +- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, +- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, +- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, +- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, +- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, +- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, +- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, +- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, +- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, +- +- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, +- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, +- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +- 5, 8, 0, 0, 0, 0, 7, 0 ++ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, ++ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, ++ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, ++ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, ++ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, ++ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, ++ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, ++ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, ++ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, ++ ++ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, ++ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, ++ 0, 0, 0, 8, 0 + } ; + + static yyconst flex_int32_t yy_ec[256] = +@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = + 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, + 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, + +- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, +- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, +- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, ++ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, ++ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, ++ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +@@ -435,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = + 1, 1, 1, 1, 1 + } ; + +-static yyconst flex_int32_t yy_meta[47] = ++static yyconst flex_int32_t yy_meta[48] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, + 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, + 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 3, 1, 4 ++ 8, 8, 8, 8, 3, 1, 4 + } ; + +-static yyconst flex_int16_t yy_base[173] = ++static yyconst flex_int16_t yy_base[180] = + { 0, +- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, +- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, +- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, +- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, +- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, +- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, +- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, +- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, +- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, +- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, +- +- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, +- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, +- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, +- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, +- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, +- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, +- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, +- 318, 326 ++ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, ++ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, ++ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, ++ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, ++ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, ++ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, ++ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, ++ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, ++ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, ++ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, ++ ++ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, ++ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, ++ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, ++ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, ++ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, ++ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, ++ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, ++ 281, 288, 292, 300, 308, 312, 318, 326, 334 + } ; + +-static yyconst flex_int16_t yy_def[173] = ++static yyconst flex_int16_t yy_def[180] = + { 0, +- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, +- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, +- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, +- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, +- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, +- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, +- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- +- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, +- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, +- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158 ++ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, ++ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, ++ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, ++ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, ++ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, ++ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, ++ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, ++ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, ++ ++ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, ++ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_nxt[438] = ++static yyconst flex_int16_t yy_nxt[449] = + { 0, + 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, + 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, + 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, +- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, +- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, +- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, +- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, +- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, +- +- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, +- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, +- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, +- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, +- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, +- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, +- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, +- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, +- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, +- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, +- +- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, +- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, +- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, +- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, +- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, +- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, +- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, +- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, +- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, +- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, +- +- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, +- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, +- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, +- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, +- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, +- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, +- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, +- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, +- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, +- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158 ++ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, ++ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, ++ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, ++ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, ++ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, ++ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, ++ ++ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, ++ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, ++ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, ++ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, ++ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, ++ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, ++ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, ++ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, ++ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, ++ ++ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, ++ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, ++ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, ++ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, ++ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, ++ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, ++ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, ++ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, ++ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, ++ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, ++ ++ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, ++ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, ++ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, ++ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, ++ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, ++ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, ++ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, ++ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, ++ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, ++ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, ++ ++ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_chk[438] = ++static yyconst flex_int16_t yy_chk[449] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, +- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, +- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, ++ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, ++ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, ++ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, +- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, +- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, +- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, +- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, +- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, +- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, +- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, +- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, +- +- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, +- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, +- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, +- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, +- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, +- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, +- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, +- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, +- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, +- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, +- +- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, +- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, +- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, +- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, +- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, +- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, +- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, +- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, ++ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, ++ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, ++ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, ++ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, ++ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, ++ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, ++ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, ++ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, ++ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, ++ ++ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, ++ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, ++ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, ++ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, ++ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, ++ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, ++ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, ++ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, ++ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, ++ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, ++ ++ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, ++ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, ++ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, ++ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, ++ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, ++ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, ++ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, ++ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, ++ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, + 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158 ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + + static yy_state_type yy_last_accepting_state; +@@ -662,7 +664,7 @@ static int dts_version = 1; + static void push_input_file(const char *filename); + static bool pop_input_file(void); + static void lexical_error(const char *fmt, ...); +-#line 666 "dtc-lexer.lex.c" ++#line 668 "dtc-lexer.lex.c" + + #define INITIAL 0 + #define BYTESTRING 1 +@@ -704,7 +706,7 @@ FILE *yyget_out (void ); + + void yyset_out (FILE * out_str ); + +-yy_size_t yyget_leng (void ); ++int yyget_leng (void ); + + char *yyget_text (void ); + +@@ -853,6 +855,10 @@ YY_DECL + register char *yy_cp, *yy_bp; + register int yy_act; + ++#line 68 "dtc-lexer.l" ++ ++#line 861 "dtc-lexer.lex.c" ++ + if ( !(yy_init) ) + { + (yy_init) = 1; +@@ -879,11 +885,6 @@ YY_DECL + yy_load_buffer_state( ); + } + +- { +-#line 68 "dtc-lexer.l" +- +-#line 886 "dtc-lexer.lex.c" +- + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); +@@ -901,7 +902,7 @@ YY_DECL + yy_match: + do + { +- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; ++ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; +@@ -910,13 +911,13 @@ yy_match: + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } +- while ( yy_current_state != 158 ); ++ while ( yy_current_state != 165 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +@@ -1007,23 +1008,31 @@ case 5: + YY_RULE_SETUP + #line 116 "dtc-lexer.l" + { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ YY_BREAK ++case 6: ++YY_RULE_SETUP ++#line 121 "dtc-lexer.l" ++{ + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); + return DT_MEMRESERVE; + } + YY_BREAK +-case 6: ++case 7: + YY_RULE_SETUP +-#line 122 "dtc-lexer.l" ++#line 127 "dtc-lexer.l" + { + DPRINT("Keyword: /bits/\n"); + BEGIN_DEFAULT(); + return DT_BITS; + } + YY_BREAK +-case 7: ++case 8: + YY_RULE_SETUP +-#line 128 "dtc-lexer.l" ++#line 133 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-property/\n"); + DPRINT("\n"); +@@ -1031,9 +1040,9 @@ YY_RULE_SETUP + return DT_DEL_PROP; + } + YY_BREAK +-case 8: ++case 9: + YY_RULE_SETUP +-#line 135 "dtc-lexer.l" ++#line 140 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-node/\n"); + DPRINT("\n"); +@@ -1041,9 +1050,9 @@ YY_RULE_SETUP + return DT_DEL_NODE; + } + YY_BREAK +-case 9: ++case 10: + YY_RULE_SETUP +-#line 142 "dtc-lexer.l" ++#line 147 "dtc-lexer.l" + { + DPRINT("Label: %s\n", yytext); + yylval.labelref = xstrdup(yytext); +@@ -1051,9 +1060,9 @@ YY_RULE_SETUP + return DT_LABEL; + } + YY_BREAK +-case 10: ++case 11: + YY_RULE_SETUP +-#line 149 "dtc-lexer.l" ++#line 154 "dtc-lexer.l" + { + char *e; + DPRINT("Integer Literal: '%s'\n", yytext); +@@ -1073,10 +1082,10 @@ YY_RULE_SETUP + return DT_LITERAL; + } + YY_BREAK +-case 11: +-/* rule 11 can match eol */ ++case 12: ++/* rule 12 can match eol */ + YY_RULE_SETUP +-#line 168 "dtc-lexer.l" ++#line 173 "dtc-lexer.l" + { + struct data d; + DPRINT("Character literal: %s\n", yytext); +@@ -1098,18 +1107,18 @@ YY_RULE_SETUP + return DT_CHAR_LITERAL; + } + YY_BREAK +-case 12: ++case 13: + YY_RULE_SETUP +-#line 189 "dtc-lexer.l" ++#line 194 "dtc-lexer.l" + { /* label reference */ + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = xstrdup(yytext+1); + return DT_REF; + } + YY_BREAK +-case 13: ++case 14: + YY_RULE_SETUP +-#line 195 "dtc-lexer.l" ++#line 200 "dtc-lexer.l" + { /* new-style path reference */ + yytext[yyleng-1] = '\0'; + DPRINT("Ref: %s\n", yytext+2); +@@ -1117,27 +1126,27 @@ YY_RULE_SETUP + return DT_REF; + } + YY_BREAK +-case 14: ++case 15: + YY_RULE_SETUP +-#line 202 "dtc-lexer.l" ++#line 207 "dtc-lexer.l" + { + yylval.byte = strtol(yytext, NULL, 16); + DPRINT("Byte: %02x\n", (int)yylval.byte); + return DT_BYTE; + } + YY_BREAK +-case 15: ++case 16: + YY_RULE_SETUP +-#line 208 "dtc-lexer.l" ++#line 213 "dtc-lexer.l" + { + DPRINT("/BYTESTRING\n"); + BEGIN_DEFAULT(); + return ']'; + } + YY_BREAK +-case 16: ++case 17: + YY_RULE_SETUP +-#line 214 "dtc-lexer.l" ++#line 219 "dtc-lexer.l" + { + DPRINT("PropNodeName: %s\n", yytext); + yylval.propnodename = xstrdup((yytext[0] == '\\') ? +@@ -1146,75 +1155,75 @@ YY_RULE_SETUP + return DT_PROPNODENAME; + } + YY_BREAK +-case 17: ++case 18: + YY_RULE_SETUP +-#line 222 "dtc-lexer.l" ++#line 227 "dtc-lexer.l" + { + DPRINT("Binary Include\n"); + return DT_INCBIN; + } + YY_BREAK +-case 18: +-/* rule 18 can match eol */ +-YY_RULE_SETUP +-#line 227 "dtc-lexer.l" +-/* eat whitespace */ +- YY_BREAK + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP +-#line 228 "dtc-lexer.l" +-/* eat C-style comments */ ++#line 232 "dtc-lexer.l" ++/* eat whitespace */ + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP +-#line 229 "dtc-lexer.l" +-/* eat C++-style comments */ ++#line 233 "dtc-lexer.l" ++/* eat C-style comments */ + YY_BREAK + case 21: ++/* rule 21 can match eol */ + YY_RULE_SETUP +-#line 231 "dtc-lexer.l" +-{ return DT_LSHIFT; }; ++#line 234 "dtc-lexer.l" ++/* eat C++-style comments */ + YY_BREAK + case 22: + YY_RULE_SETUP +-#line 232 "dtc-lexer.l" +-{ return DT_RSHIFT; }; ++#line 236 "dtc-lexer.l" ++{ return DT_LSHIFT; }; + YY_BREAK + case 23: + YY_RULE_SETUP +-#line 233 "dtc-lexer.l" +-{ return DT_LE; }; ++#line 237 "dtc-lexer.l" ++{ return DT_RSHIFT; }; + YY_BREAK + case 24: + YY_RULE_SETUP +-#line 234 "dtc-lexer.l" +-{ return DT_GE; }; ++#line 238 "dtc-lexer.l" ++{ return DT_LE; }; + YY_BREAK + case 25: + YY_RULE_SETUP +-#line 235 "dtc-lexer.l" +-{ return DT_EQ; }; ++#line 239 "dtc-lexer.l" ++{ return DT_GE; }; + YY_BREAK + case 26: + YY_RULE_SETUP +-#line 236 "dtc-lexer.l" +-{ return DT_NE; }; ++#line 240 "dtc-lexer.l" ++{ return DT_EQ; }; + YY_BREAK + case 27: + YY_RULE_SETUP +-#line 237 "dtc-lexer.l" +-{ return DT_AND; }; ++#line 241 "dtc-lexer.l" ++{ return DT_NE; }; + YY_BREAK + case 28: + YY_RULE_SETUP +-#line 238 "dtc-lexer.l" +-{ return DT_OR; }; ++#line 242 "dtc-lexer.l" ++{ return DT_AND; }; + YY_BREAK + case 29: + YY_RULE_SETUP +-#line 240 "dtc-lexer.l" ++#line 243 "dtc-lexer.l" ++{ return DT_OR; }; ++ YY_BREAK ++case 30: ++YY_RULE_SETUP ++#line 245 "dtc-lexer.l" + { + DPRINT("Char: %c (\\x%02x)\n", yytext[0], + (unsigned)yytext[0]); +@@ -1230,12 +1239,12 @@ YY_RULE_SETUP + return yytext[0]; + } + YY_BREAK +-case 30: ++case 31: + YY_RULE_SETUP +-#line 255 "dtc-lexer.l" ++#line 260 "dtc-lexer.l" + ECHO; + YY_BREAK +-#line 1239 "dtc-lexer.lex.c" ++#line 1248 "dtc-lexer.lex.c" + + case YY_END_OF_BUFFER: + { +@@ -1365,7 +1374,6 @@ ECHO; + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +- } /* end of user's declarations */ + } /* end of yylex */ + + /* yy_get_next_buffer - try to read in a new buffer +@@ -1421,21 +1429,21 @@ static int yy_get_next_buffer (void) + + else + { +- yy_size_t num_to_read = ++ int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; ++ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { +- yy_size_t new_size = b->yy_buf_size * 2; ++ int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; +@@ -1466,7 +1474,7 @@ static int yy_get_next_buffer (void) + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), num_to_read ); ++ (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } +@@ -1528,7 +1536,7 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +@@ -1556,13 +1564,13 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 158); ++ yy_is_jam = (yy_current_state == 165); + +- return yy_is_jam ? 0 : yy_current_state; ++ return yy_is_jam ? 0 : yy_current_state; + } + + #ifndef YY_NO_INPUT +@@ -1589,7 +1597,7 @@ static int yy_get_next_buffer (void) + + else + { /* need more input */ +- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++ int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) +@@ -1863,7 +1871,7 @@ void yypop_buffer_state (void) + */ + static void yyensure_buffer_stack (void) + { +- yy_size_t num_to_alloc; ++ int num_to_alloc; + + if (!(yy_buffer_stack)) { + +@@ -1960,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) + * + * @return the newly allocated buffer state object. + */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) ++YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; +- yy_size_t i; ++ int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; +@@ -2047,7 +2055,7 @@ FILE *yyget_out (void) + /** Get the length of the current token. + * + */ +-yy_size_t yyget_leng (void) ++int yyget_leng (void) + { + return yyleng; + } +@@ -2195,7 +2203,7 @@ void yyfree (void * ptr ) + + #define YYTABLES_NAME "yytables" + +-#line 254 "dtc-lexer.l" ++#line 260 "dtc-lexer.l" + + + +diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped +index 116458c..2c1784e 100644 +--- a/scripts/dtc/dtc-parser.tab.c_shipped ++++ b/scripts/dtc/dtc-parser.tab.c_shipped +@@ -1,19 +1,19 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ ++/* A Bison parser, made by GNU Bison 2.5. */ + + /* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- ++ ++ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. ++ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +@@ -26,7 +26,7 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +@@ -44,7 +44,7 @@ + #define YYBISON 1 + + /* Bison version. */ +-#define YYBISON_VERSION "3.0.2" ++#define YYBISON_VERSION "2.5" + + /* Skeleton name. */ + #define YYSKELETON_NAME "yacc.c" +@@ -58,13 +58,18 @@ + /* Pull parsers. */ + #define YYPULL 1 + ++/* Using locations. */ ++#define YYLSP_NEEDED 1 + + + + /* Copy the first part of user declarations. */ +-#line 20 "dtc-parser.y" /* yacc.c:339 */ ++ ++/* Line 268 of yacc.c */ ++#line 20 "dtc-parser.y" + + #include ++#include + + #include "dtc.h" + #include "srcpos.h" +@@ -80,15 +85,14 @@ extern void yyerror(char const *s); + extern struct boot_info *the_boot_info; + extern bool treesource_error; + +-#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ + +-# ifndef YY_NULLPTR +-# if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULLPTR nullptr +-# else +-# define YY_NULLPTR 0 +-# endif +-# endif ++/* Line 268 of yacc.c */ ++#line 91 "dtc-parser.tab.c" ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif + + /* Enabling verbose error messages. */ + #ifdef YYERROR_VERBOSE +@@ -98,53 +102,51 @@ extern bool treesource_error; + # define YYERROR_VERBOSE 0 + #endif + +-/* In a future release of Bison, this section will be replaced +- by #include "dtc-parser.tab.h". */ +-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED +-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; ++/* Enabling the token table. */ ++#ifndef YYTOKEN_TABLE ++# define YYTOKEN_TABLE 0 + #endif + +-/* Token type. */ ++ ++/* Tokens. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- enum yytokentype +- { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BYTE = 274, +- DT_STRING = 275, +- DT_LABEL = 276, +- DT_REF = 277, +- DT_INCBIN = 278 +- }; ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +-/* Value type. */ ++ ++ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE ++typedef union YYSTYPE + { +-#line 38 "dtc-parser.y" /* yacc.c:355 */ ++ ++/* Line 293 of yacc.c */ ++#line 39 "dtc-parser.y" + + char *propnodename; + char *labelref; +@@ -162,37 +164,37 @@ union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + +-#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ +-}; ++ ++ ++/* Line 293 of yacc.c */ ++#line 173 "dtc-parser.tab.c" ++} YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-/* Location type. */ + #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +-typedef struct YYLTYPE YYLTYPE; +-struct YYLTYPE ++typedef struct YYLTYPE + { + int first_line; + int first_column; + int last_line; + int last_column; +-}; ++} YYLTYPE; ++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ + # define YYLTYPE_IS_DECLARED 1 + # define YYLTYPE_IS_TRIVIAL 1 + #endif + + +-extern YYSTYPE yylval; +-extern YYLTYPE yylloc; +-int yyparse (void); +- +-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +- + /* Copy the second part of user declarations. */ + +-#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ ++ ++/* Line 343 of yacc.c */ ++#line 198 "dtc-parser.tab.c" + + #ifdef short + # undef short +@@ -206,8 +208,11 @@ typedef unsigned char yytype_uint8; + + #ifdef YYTYPE_INT8 + typedef YYTYPE_INT8 yytype_int8; +-#else ++#elif (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + typedef signed char yytype_int8; ++#else ++typedef short int yytype_int8; + #endif + + #ifdef YYTYPE_UINT16 +@@ -227,7 +232,8 @@ typedef short int yytype_int16; + # define YYSIZE_T __SIZE_TYPE__ + # elif defined size_t + # define YYSIZE_T size_t +-# elif ! defined YYSIZE_T ++# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + # include /* INFRINGES ON USER NAME SPACE */ + # define YYSIZE_T size_t + # else +@@ -241,68 +247,39 @@ typedef short int yytype_int16; + # if defined YYENABLE_NLS && YYENABLE_NLS + # if ENABLE_NLS + # include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(Msgid) dgettext ("bison-runtime", Msgid) ++# define YY_(msgid) dgettext ("bison-runtime", msgid) + # endif + # endif + # ifndef YY_ +-# define YY_(Msgid) Msgid +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +-#endif +- +-#ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +-#endif +- +-#if !defined _Noreturn \ +- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +-# if defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) ++# define YY_(msgid) msgid + # endif + #endif + + /* Suppress unused-variable warnings by "using" E. */ + #if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) ++# define YYUSE(e) ((void) (e)) + #else +-# define YYUSE(E) /* empty */ ++# define YYUSE(e) /* empty */ + #endif + +-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +-/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +- _Pragma ("GCC diagnostic pop") ++/* Identity function, used to suppress warnings about constant conditions. */ ++#ifndef lint ++# define YYID(n) (n) + #else +-# define YY_INITIAL_VALUE(Value) Value +-#endif +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static int ++YYID (int yyi) ++#else ++static int ++YYID (yyi) ++ int yyi; + #endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ ++{ ++ return yyi; ++} + #endif + +- + #if ! defined yyoverflow || YYERROR_VERBOSE + + /* The parser invokes alloca or malloc; define the necessary symbols. */ +@@ -320,9 +297,9 @@ typedef short int yytype_int16; + # define alloca _alloca + # else + # define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS ++# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + # include /* INFRINGES ON USER NAME SPACE */ +- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ + # ifndef EXIT_SUCCESS + # define EXIT_SUCCESS 0 + # endif +@@ -332,8 +309,8 @@ typedef short int yytype_int16; + # endif + + # ifdef YYSTACK_ALLOC +- /* Pacify GCC's 'empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + # ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely +@@ -349,7 +326,7 @@ typedef short int yytype_int16; + # endif + # if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) ++ && (defined YYFREE || defined free))) + # include /* INFRINGES ON USER NAME SPACE */ + # ifndef EXIT_SUCCESS + # define EXIT_SUCCESS 0 +@@ -357,13 +334,15 @@ typedef short int yytype_int16; + # endif + # ifndef YYMALLOC + # define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS ++# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif + # ifndef YYFREE + # define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS ++# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + void free (void *); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif +@@ -373,8 +352,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ + + #if (! defined yyoverflow \ + && (! defined __cplusplus \ +- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ +- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) ++ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ ++ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + + /* A type that is properly aligned for any stack member. */ + union yyalloc +@@ -400,35 +379,35 @@ union yyalloc + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (0) ++# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ ++ Stack = &yyptr->Stack_alloc; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (YYID (0)) + + #endif + + #if defined YYCOPY_NEEDED && YYCOPY_NEEDED +-/* Copy COUNT objects from SRC to DST. The source and destination do ++/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ + # ifndef YYCOPY + # if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) + # else +-# define YYCOPY(Dst, Src, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (Dst)[yyi] = (Src)[yyi]; \ +- } \ +- while (0) ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (YYID (0)) + # endif + # endif + #endif /* !YYCOPY_NEEDED */ +@@ -439,39 +418,37 @@ union yyalloc + #define YYLAST 136 + + /* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 47 ++#define YYNTOKENS 48 + /* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 28 ++#define YYNNTS 29 + /* YYNRULES -- Number of rules. */ +-#define YYNRULES 80 +-/* YYNSTATES -- Number of states. */ +-#define YYNSTATES 144 ++#define YYNRULES 82 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 147 + +-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +- by yylex, with out-of-bounds checking. */ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + #define YYUNDEFTOK 2 +-#define YYMAXUTOK 278 ++#define YYMAXUTOK 279 + +-#define YYTRANSLATE(YYX) \ ++#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +- as returned by yylex, without out-of-bounds checking. */ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ + static const yytype_uint8 yytranslate[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, +- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, +- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, ++ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, ++ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, ++ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, ++ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +@@ -486,292 +463,335 @@ static const yytype_uint8 yytranslate[] = + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23 ++ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 + }; + + #if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const yytype_uint16 yyprhs[] = ++{ ++ 0, 0, 3, 9, 10, 13, 14, 17, 22, 25, ++ 28, 32, 37, 41, 46, 52, 53, 56, 61, 64, ++ 68, 71, 74, 78, 83, 86, 96, 102, 105, 106, ++ 109, 112, 116, 118, 121, 124, 127, 129, 131, 135, ++ 137, 139, 145, 147, 151, 153, 157, 159, 163, 165, ++ 169, 171, 175, 177, 181, 185, 187, 191, 195, 199, ++ 203, 207, 211, 213, 217, 221, 223, 227, 231, 235, ++ 237, 239, 242, 245, 248, 249, 252, 255, 256, 259, ++ 262, 265, 269 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const yytype_int8 yyrhs[] = ++{ ++ 49, 0, -1, 3, 25, 50, 51, 53, -1, -1, ++ 4, 25, -1, -1, 52, 51, -1, 5, 60, 60, ++ 25, -1, 22, 52, -1, 26, 54, -1, 53, 26, ++ 54, -1, 53, 22, 23, 54, -1, 53, 23, 54, ++ -1, 53, 16, 23, 25, -1, 27, 55, 75, 28, ++ 25, -1, -1, 55, 56, -1, 17, 29, 57, 25, ++ -1, 17, 25, -1, 15, 17, 25, -1, 22, 56, ++ -1, 58, 21, -1, 58, 59, 30, -1, 58, 31, ++ 74, 32, -1, 58, 23, -1, 58, 24, 33, 21, ++ 34, 60, 34, 60, 35, -1, 58, 24, 33, 21, ++ 35, -1, 57, 22, -1, -1, 57, 34, -1, 58, ++ 22, -1, 14, 18, 36, -1, 36, -1, 59, 60, ++ -1, 59, 23, -1, 59, 22, -1, 18, -1, 19, ++ -1, 33, 61, 35, -1, 62, -1, 63, -1, 63, ++ 37, 61, 38, 62, -1, 64, -1, 63, 13, 64, ++ -1, 65, -1, 64, 12, 65, -1, 66, -1, 65, ++ 39, 66, -1, 67, -1, 66, 40, 67, -1, 68, ++ -1, 67, 41, 68, -1, 69, -1, 68, 10, 69, ++ -1, 68, 11, 69, -1, 70, -1, 69, 36, 70, ++ -1, 69, 30, 70, -1, 69, 8, 70, -1, 69, ++ 9, 70, -1, 70, 6, 71, -1, 70, 7, 71, ++ -1, 71, -1, 71, 42, 72, -1, 71, 43, 72, ++ -1, 72, -1, 72, 44, 73, -1, 72, 26, 73, ++ -1, 72, 45, 73, -1, 73, -1, 60, -1, 43, ++ 73, -1, 46, 73, -1, 47, 73, -1, -1, 74, ++ 20, -1, 74, 22, -1, -1, 76, 75, -1, 76, ++ 56, -1, 17, 54, -1, 16, 17, 25, -1, 22, ++ 76, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + static const yytype_uint16 yyrline[] = + { +- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, +- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, +- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, +- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, +- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, +- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, +- 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, +- 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, +- 465 ++ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, ++ 156, 161, 172, 182, 197, 205, 208, 215, 219, 223, ++ 227, 235, 239, 243, 247, 251, 267, 277, 285, 288, ++ 292, 299, 315, 320, 339, 353, 360, 361, 362, 369, ++ 373, 374, 378, 379, 383, 384, 388, 389, 393, 394, ++ 398, 399, 403, 404, 405, 409, 410, 411, 412, 413, ++ 417, 418, 419, 423, 424, 425, 429, 430, 431, 432, ++ 436, 437, 438, 439, 444, 447, 451, 459, 462, 466, ++ 474, 478, 482 + }; + #endif + +-#if YYDEBUG || YYERROR_VERBOSE || 0 ++#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ + static const char *const yytname[] = + { +- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", +- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", +- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", +- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", +- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", +- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", +- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", +- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", +- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", +- "integer_expr", "integer_trinary", "integer_or", "integer_and", +- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", +- "integer_rela", "integer_shift", "integer_add", "integer_mul", +- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR ++ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", ++ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", ++ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", ++ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", ++ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", ++ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", ++ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", ++ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", ++ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", ++ "integer_prim", "integer_expr", "integer_trinary", "integer_or", ++ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", ++ "integer_eq", "integer_rela", "integer_shift", "integer_add", ++ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", 0 + }; + #endif + + # ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ + static const yytype_uint16 yytoknum[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, +- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, +- 38, 43, 45, 42, 37, 126, 33 ++ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, ++ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, ++ 94, 38, 43, 45, 42, 37, 126, 33 + }; + # endif + +-#define YYPACT_NINF -81 +- +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-81))) +- +-#define YYTABLE_NINF -1 +- +-#define yytable_value_is_error(Yytable_value) \ +- 0 +- +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-static const yytype_int8 yypact[] = ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const yytype_uint8 yyr1[] = + { +- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, +- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, +- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, +- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, +- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, +- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, +- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, +- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, +- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, +- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, +- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, +- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, +- 74, 25, 75, -81 ++ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, ++ 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, ++ 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, ++ 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, ++ 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, ++ 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, ++ 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, ++ 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, ++ 76, 76, 76 + }; + +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const yytype_uint8 yyr2[] = + { +- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, +- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, +- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, +- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, +- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, +- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, +- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, +- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, +- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, +- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, +- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, +- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, +- 0, 0, 0, 23 ++ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, ++ 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, ++ 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, ++ 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, ++ 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, ++ 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, ++ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, ++ 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, ++ 2, 3, 2 + }; + +- /* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = ++/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. ++ Performed when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const yytype_uint8 yydefact[] = + { +- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, +- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, +- 37, 27, 34, 38, -14, -81, 22, 24 ++ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, ++ 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, ++ 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, ++ 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, ++ 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, ++ 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, ++ 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, ++ 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, ++ 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, ++ 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, ++ 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, ++ 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, ++ 23, 0, 26, 0, 0, 0, 25 + }; + +- /* YYDEFGOTO[NTERM-NUM]. */ ++/* YYDEFGOTO[NTERM-NUM]. */ + static const yytype_int16 yydefgoto[] = + { +- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, +- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 128, 94, 95 ++ -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, ++ 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, ++ 31, 32, 33, 34, 35, 36, 131, 97, 98 + }; + +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-static const yytype_uint8 yytable[] = ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -84 ++static const yytype_int8 yypact[] = + { +- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, +- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, +- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, +- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, +- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, +- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, +- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, +- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, +- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, +- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, +- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, +- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, +- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, +- 0, 0, 75, 140, 0, 0, 142 ++ 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, ++ 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, ++ -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, ++ 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, ++ 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, ++ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, ++ -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, ++ 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, ++ 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, ++ -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, ++ -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, ++ -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, ++ -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, ++ 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, ++ -84, 24, -84, 77, 24, 80, -84 + }; + +-static const yytype_int16 yycheck[] = ++/* YYPGOTO[NTERM-NUM]. */ ++static const yytype_int8 yypgoto[] = + { +- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, +- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, +- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, +- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, +- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, +- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, +- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, +- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, +- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, +- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, +- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, +- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, +- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, +- -1, -1, 50, 138, -1, -1, 141 ++ -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, ++ -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, ++ 82, 29, 18, 25, 26, -17, -84, 20, 28 + }; + +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -1 ++static const yytype_uint8 yytable[] = + { +- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, +- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, +- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, +- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, +- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, +- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, +- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, +- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, +- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, +- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, +- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, +- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, +- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, +- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, +- 58, 33, 58, 34 ++ 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, ++ 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, ++ 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, ++ 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, ++ 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, ++ 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, ++ 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, ++ 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, ++ 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, ++ 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, ++ 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, ++ 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, ++ 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 143, 0, 78, 145 + }; + +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = ++#define yypact_value_is_default(yystate) \ ++ ((yystate) == (-84)) ++ ++#define yytable_value_is_error(yytable_value) \ ++ YYID (0) ++ ++static const yytype_int16 yycheck[] = + { +- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, +- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, +- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, +- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, +- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, +- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, +- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, +- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, +- 74 ++ 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, ++ 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, ++ 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, ++ 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, ++ 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, ++ 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, ++ 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, ++ 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, ++ 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, ++ 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, ++ 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, ++ 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, ++ 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, 141, -1, 53, 144 + }; + +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const yytype_uint8 yystos[] = + { +- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, +- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, +- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, +- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, +- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, +- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, +- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, +- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, +- 2 ++ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, ++ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, ++ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, ++ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, ++ 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, ++ 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, ++ 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, ++ 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, ++ 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, ++ 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, ++ 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, ++ 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, ++ 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, ++ 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, ++ 32, 34, 35, 60, 34, 60, 35 + }; + +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. However, ++ YYFAIL appears to be in use. Nevertheless, it is formally deprecated ++ in Bison 2.4.2's NEWS entry, where a plan to phase it out is ++ discussed. */ ++ ++#define YYFAIL goto yyerrlab ++#if defined YYFAIL ++ /* This is here to suppress warnings from the GCC cpp's ++ -Wunused-macros. Normally we don't worry about that warning, but ++ some users do, and we want to make it easy for users to remove ++ YYFAIL uses, which will produce warnings from Bison 2.5. */ ++#endif + + #define YYRECOVERING() (!!yyerrstatus) + +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- YYPOPSTACK (yylen); \ +- yystate = *yyssp; \ +- goto yybackup; \ +- } \ +- else \ +- { \ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ YYPOPSTACK (1); \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ + yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (0) ++ YYERROR; \ ++ } \ ++while (YYID (0)) ++ + +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 ++#define YYTERROR 1 ++#define YYERRCODE 256 + + + /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + ++#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + #ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (N) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (0) ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ do \ ++ if (YYID (N)) \ ++ { \ ++ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ ++ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ ++ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ ++ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ ++ } \ ++ else \ ++ { \ ++ (Current).first_line = (Current).last_line = \ ++ YYRHSLOC (Rhs, 0).last_line; \ ++ (Current).first_column = (Current).last_column = \ ++ YYRHSLOC (Rhs, 0).last_column; \ ++ } \ ++ while (YYID (0)) + #endif + +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +- +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (0) +- + + /* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know +@@ -779,73 +799,82 @@ do { \ + + #ifndef YY_LOCATION_PRINT + # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++# define YY_LOCATION_PRINT(File, Loc) \ ++ fprintf (File, "%d.%d-%d.%d", \ ++ (Loc).first_line, (Loc).first_column, \ ++ (Loc).last_line, (Loc).last_column) ++# else ++# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++# endif ++#endif + +-/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +-YY_ATTRIBUTE_UNUSED +-static unsigned +-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +-{ +- unsigned res = 0; +- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; +- if (0 <= yylocp->first_line) +- { +- res += YYFPRINTF (yyo, "%d", yylocp->first_line); +- if (0 <= yylocp->first_column) +- res += YYFPRINTF (yyo, ".%d", yylocp->first_column); +- } +- if (0 <= yylocp->last_line) +- { +- if (yylocp->first_line < yylocp->last_line) +- { +- res += YYFPRINTF (yyo, "-%d", yylocp->last_line); +- if (0 <= end_col) +- res += YYFPRINTF (yyo, ".%d", end_col); +- } +- else if (0 <= end_col && yylocp->first_column < end_col) +- res += YYFPRINTF (yyo, "-%d", end_col); +- } +- return res; +- } ++/* YYLEX -- calling `yylex' with the right arguments. */ + +-# define YY_LOCATION_PRINT(File, Loc) \ +- yy_location_print_ (File, &(Loc)) ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (YYLEX_PARAM) ++#else ++# define YYLEX yylex () ++#endif + +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf + # endif +-#endif + ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (YYID (0)) + +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value, Location); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yy_symbol_print (stderr, \ ++ Type, Value, Location); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (YYID (0)) + + +-/*----------------------------------------. +-| Print this symbol's value on YYOUTPUT. | +-`----------------------------------------*/ ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ + ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) ++#else ++static void ++yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ YYLTYPE const * const yylocationp; ++#endif + { +- FILE *yyo = yyoutput; +- YYUSE (yyo); +- YYUSE (yylocationp); + if (!yyvaluep) + return; ++ YYUSE (yylocationp); + # ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# else ++ YYUSE (yyoutput); + # endif +- YYUSE (yytype); ++ switch (yytype) ++ { ++ default: ++ break; ++ } + } + + +@@ -853,11 +882,23 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) ++#else ++static void ++yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ YYLTYPE const * const yylocationp; ++#endif + { +- YYFPRINTF (yyoutput, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); ++ if (yytype < YYNTOKENS) ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); +@@ -870,8 +911,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL + | TOP (included). | + `------------------------------------------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) ++#else ++static void ++yy_stack_print (yybottom, yytop) ++ yytype_int16 *yybottom; ++ yytype_int16 *yytop; ++#endif + { + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) +@@ -882,42 +931,50 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) + YYFPRINTF (stderr, "\n"); + } + +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (0) ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (YYID (0)) + + + /*------------------------------------------------. + | Report that the YYRULE is going to be reduced. | + `------------------------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static void ++yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) ++#else + static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) ++yy_reduce_print (yyvsp, yylsp, yyrule) ++ YYSTYPE *yyvsp; ++ YYLTYPE *yylsp; ++ int yyrule; ++#endif + { +- unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; ++ unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); ++ yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- , &(yylsp[(yyi + 1) - (yynrhs)]) ); ++ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], ++ &(yyvsp[(yyi + 1) - (yynrhs)]) ++ , &(yylsp[(yyi + 1) - (yynrhs)]) ); + YYFPRINTF (stderr, "\n"); + } + } + +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ +-} while (0) ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (yyvsp, yylsp, Rule); \ ++} while (YYID (0)) + + /* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +@@ -931,7 +988,7 @@ int yydebug; + + + /* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH ++#ifndef YYINITDEPTH + # define YYINITDEPTH 200 + #endif + +@@ -954,8 +1011,15 @@ int yydebug; + # define yystrlen strlen + # else + /* Return the length of YYSTR. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static YYSIZE_T + yystrlen (const char *yystr) ++#else ++static YYSIZE_T ++yystrlen (yystr) ++ const char *yystr; ++#endif + { + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) +@@ -971,8 +1035,16 @@ yystrlen (const char *yystr) + # else + /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static char * + yystpcpy (char *yydest, const char *yysrc) ++#else ++static char * ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++#endif + { + char *yyd = yydest; + const char *yys = yysrc; +@@ -1002,27 +1074,27 @@ yytnamerr (char *yyres, const char *yystr) + char const *yyp = yystr; + + for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } ++ switch (*++yyp) ++ { ++ case '\'': ++ case ',': ++ goto do_not_strip_quotes; ++ ++ case '\\': ++ if (*++yyp != '\\') ++ goto do_not_strip_quotes; ++ /* Fall through. */ ++ default: ++ if (yyres) ++ yyres[yyn] = *yyp; ++ yyn++; ++ break; ++ ++ case '"': ++ if (yyres) ++ yyres[yyn] = '\0'; ++ return yyn; ++ } + do_not_strip_quotes: ; + } + +@@ -1045,11 +1117,12 @@ static int + yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) + { +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); ++ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize = yysize0; ++ YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; ++ const char *yyformat = 0; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per +@@ -1057,6 +1130,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + int yycount = 0; + + /* There are many possibilities here to consider: ++ - Assume YYFAIL is not used. It's too flawed to consider. See ++ ++ for details. YYERROR is fine as it does not invoke this ++ function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected +@@ -1105,13 +1182,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + break; + } + yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (! (yysize <= yysize1 +- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } ++ yysize1 = yysize + yytnamerr (0, yytname[yyx]); ++ if (! (yysize <= yysize1 ++ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) ++ return 2; ++ yysize = yysize1; + } + } + } +@@ -1131,12 +1206,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + # undef YYCASE_ + } + +- { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } ++ yysize1 = yysize + yystrlen (yyformat); ++ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) ++ return 2; ++ yysize = yysize1; + + if (*yymsg_alloc < yysize) + { +@@ -1173,21 +1246,50 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + | Release the memory associated to this symbol. | + `-----------------------------------------------*/ + ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) ++#else ++static void ++yydestruct (yymsg, yytype, yyvaluep, yylocationp) ++ const char *yymsg; ++ int yytype; ++ YYSTYPE *yyvaluep; ++ YYLTYPE *yylocationp; ++#endif + { + YYUSE (yyvaluep); + YYUSE (yylocationp); ++ + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- YYUSE (yytype); +- YY_IGNORE_MAYBE_UNINITIALIZED_END ++ switch (yytype) ++ { ++ ++ default: ++ break; ++ } + } + + ++/* Prevent warnings from -Wmissing-prototypes. */ ++#ifdef YYPARSE_PARAM ++#if defined __STDC__ || defined __cplusplus ++int yyparse (void *YYPARSE_PARAM); ++#else ++int yyparse (); ++#endif ++#else /* ! YYPARSE_PARAM */ ++#if defined __STDC__ || defined __cplusplus ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ + + + /* The lookahead symbol. */ +@@ -1195,12 +1297,10 @@ int yychar; + + /* The semantic value of the lookahead symbol. */ + YYSTYPE yylval; ++ + /* Location data for the lookahead symbol. */ +-YYLTYPE yylloc +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +- = { 1, 1, 1, 1 } +-# endif +-; ++YYLTYPE yylloc; ++ + /* Number of syntax errors so far. */ + int yynerrs; + +@@ -1209,19 +1309,38 @@ int yynerrs; + | yyparse. | + `----------*/ + ++#ifdef YYPARSE_PARAM ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++int ++yyparse (void *YYPARSE_PARAM) ++#else ++int ++yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++#endif ++#else /* ! YYPARSE_PARAM */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + int + yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif + { + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- 'yyls': related to locations. ++ `yyss': related to states. ++ `yyvs': related to semantic values. ++ `yyls': related to locations. + +- Refer to the stacks through separate pointers, to allow yyoverflow ++ Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ +@@ -1247,7 +1366,7 @@ yyparse (void) + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; ++ int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; +@@ -1266,9 +1385,10 @@ yyparse (void) + Keep to zero when no symbol should be popped. */ + int yylen = 0; + +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yylsp = yyls = yylsa; ++ yytoken = 0; ++ yyss = yyssa; ++ yyvs = yyvsa; ++ yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); +@@ -1277,7 +1397,21 @@ yyparse (void) + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ +- yylsp[0] = yylloc; ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ yylsp = yyls; ++ ++#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++ /* Initialize the default location before parsing starts. */ ++ yylloc.first_line = yylloc.last_line = 1; ++ yylloc.first_column = yylloc.last_column = 1; ++#endif ++ + goto yysetstate; + + /*------------------------------------------------------------. +@@ -1298,26 +1432,26 @@ yyparse (void) + + #ifdef yyoverflow + { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- YYLTYPE *yyls1 = yyls; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yyls1, yysize * sizeof (*yylsp), +- &yystacksize); +- +- yyls = yyls1; +- yyss = yyss1; +- yyvs = yyvs1; ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ yytype_int16 *yyss1 = yyss; ++ YYLTYPE *yyls1 = yyls; ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow (YY_("memory exhausted"), ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ &yyls1, yysize * sizeof (*yylsp), ++ &yystacksize); ++ ++ yyls = yyls1; ++ yyss = yyss1; ++ yyvs = yyvs1; + } + #else /* no yyoverflow */ + # ifndef YYSTACK_RELOCATE +@@ -1325,23 +1459,23 @@ yyparse (void) + # else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; ++ goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; ++ yystacksize = YYMAXDEPTH; + + { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); +- YYSTACK_RELOCATE (yyls_alloc, yyls); ++ yytype_int16 *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyexhaustedlab; ++ YYSTACK_RELOCATE (yyss_alloc, yyss); ++ YYSTACK_RELOCATE (yyvs_alloc, yyvs); ++ YYSTACK_RELOCATE (yyls_alloc, yyls); + # undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); + } + # endif + #endif /* no yyoverflow */ +@@ -1351,10 +1485,10 @@ yyparse (void) + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); ++ (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; ++ YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +@@ -1383,7 +1517,7 @@ yybackup: + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = yylex (); ++ yychar = YYLEX; + } + + if (yychar <= YYEOF) +@@ -1423,9 +1557,7 @@ yybackup: + yychar = YYEMPTY; + + yystate = yyn; +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END + *++yylsp = yylloc; + goto yynewstate; + +@@ -1448,7 +1580,7 @@ yyreduce: + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: +- '$$ = $1'. ++ `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison +@@ -1463,273 +1595,322 @@ yyreduce: + switch (yyn) + { + case 2: +-#line 105 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 109 "dtc-parser.y" + { +- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), +- guess_boot_cpuid((yyvsp[0].node))); ++ (yyvsp[(5) - (5)].node)->is_plugin = (yyvsp[(3) - (5)].is_plugin); ++ (yyvsp[(5) - (5)].node)->is_root = 1; ++ the_boot_info = build_boot_info((yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), ++ guess_boot_cpuid((yyvsp[(5) - (5)].node))); + } +-#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 3: +-#line 113 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 119 "dtc-parser.y" + { +- (yyval.re) = NULL; ++ (yyval.is_plugin) = 0; + } +-#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 4: +-#line 117 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 123 "dtc-parser.y" + { +- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); ++ (yyval.is_plugin) = 1; + } +-#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 5: +-#line 124 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 130 "dtc-parser.y" + { +- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); ++ (yyval.re) = NULL; + } +-#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 6: +-#line 128 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 134 "dtc-parser.y" + { +- add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); +- (yyval.re) = (yyvsp[0].re); ++ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); + } +-#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 7: +-#line 136 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 141 "dtc-parser.y" + { +- (yyval.node) = name_node((yyvsp[0].node), ""); ++ (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); + } +-#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 8: +-#line 140 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 145 "dtc-parser.y" + { +- (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); ++ add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.re) = (yyvsp[(2) - (2)].re); + } +-#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 9: +-#line 145 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); + +- add_label(&target->labels, (yyvsp[-2].labelref)); +- if (target) +- merge_nodes(target, (yyvsp[0].node)); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[-3].node); ++/* Line 1806 of yacc.c */ ++#line 153 "dtc-parser.y" ++ { ++ (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); + } +-#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 10: +-#line 156 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); + +- if (target) +- merge_nodes(target, (yyvsp[0].node)); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[-2].node); ++/* Line 1806 of yacc.c */ ++#line 157 "dtc-parser.y" ++ { ++ (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } +-#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 11: +-#line 166 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 162 "dtc-parser.y" + { +- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); ++ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); + ++ add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); + if (target) +- delete_node(target); ++ merge_nodes(target, (yyvsp[(4) - (4)].node)); + else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- +- +- (yyval.node) = (yyvsp[-3].node); ++ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); ++ (yyval.node) = (yyvsp[(1) - (4)].node); + } +-#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 12: +-#line 181 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 173 "dtc-parser.y" + { +- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); ++ struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); ++ ++ if (target) ++ merge_nodes(target, (yyvsp[(3) - (3)].node)); ++ else ++ ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); ++ (yyval.node) = (yyvsp[(1) - (3)].node); + } +-#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 13: +-#line 188 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 183 "dtc-parser.y" + { +- (yyval.proplist) = NULL; ++ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); ++ ++ if (target) ++ delete_node(target); ++ else ++ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); ++ ++ ++ (yyval.node) = (yyvsp[(1) - (4)].node); + } +-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 14: +-#line 192 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 198 "dtc-parser.y" + { +- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); ++ (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); + } +-#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 15: +-#line 199 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 205 "dtc-parser.y" + { +- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); ++ (yyval.proplist) = NULL; + } +-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 16: +-#line 203 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 209 "dtc-parser.y" + { +- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); ++ (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); + } +-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 17: +-#line 207 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 216 "dtc-parser.y" + { +- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); ++ (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); + } +-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 18: +-#line 211 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 220 "dtc-parser.y" + { +- add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); +- (yyval.prop) = (yyvsp[0].prop); ++ (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); + } +-#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 19: +-#line 219 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 224 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); ++ (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); + } +-#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 20: +-#line 223 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 228 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); ++ add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.prop) = (yyvsp[(2) - (2)].prop); + } +-#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 21: +-#line 227 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 236 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); ++ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); + } +-#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 22: +-#line 231 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 240 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); ++ (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); + } +-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 23: +-#line 235 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 244 "dtc-parser.y" + { +- FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); ++ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ++ } ++ break; ++ ++ case 24: ++ ++/* Line 1806 of yacc.c */ ++#line 248 "dtc-parser.y" ++ { ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); ++ } ++ break; ++ ++ case 25: ++ ++/* Line 1806 of yacc.c */ ++#line 252 "dtc-parser.y" ++ { ++ FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); + struct data d; + +- if ((yyvsp[-3].integer) != 0) +- if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) ++ if ((yyvsp[(6) - (9)].integer) != 0) ++ if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) + die("Couldn't seek to offset %llu in \"%s\": %s", +- (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, ++ (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, + strerror(errno)); + +- d = data_copy_file(f, (yyvsp[-1].integer)); ++ d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); + +- (yyval.data) = data_merge((yyvsp[-8].data), d); ++ (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); + fclose(f); + } +-#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 24: +-#line 251 "dtc-parser.y" /* yacc.c:1646 */ ++ case 26: ++ ++/* Line 1806 of yacc.c */ ++#line 268 "dtc-parser.y" + { +- FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); ++ FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); + struct data d = empty_data; + + d = data_copy_file(f, -1); + +- (yyval.data) = data_merge((yyvsp[-4].data), d); ++ (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); + fclose(f); + } +-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 25: +-#line 261 "dtc-parser.y" /* yacc.c:1646 */ ++ case 27: ++ ++/* Line 1806 of yacc.c */ ++#line 278 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 26: +-#line 268 "dtc-parser.y" /* yacc.c:1646 */ ++ case 28: ++ ++/* Line 1806 of yacc.c */ ++#line 285 "dtc-parser.y" + { + (yyval.data) = empty_data; + } +-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 27: +-#line 272 "dtc-parser.y" /* yacc.c:1646 */ ++ case 29: ++ ++/* Line 1806 of yacc.c */ ++#line 289 "dtc-parser.y" + { +- (yyval.data) = (yyvsp[-1].data); ++ (yyval.data) = (yyvsp[(1) - (2)].data); + } +-#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 28: +-#line 276 "dtc-parser.y" /* yacc.c:1646 */ ++ case 30: ++ ++/* Line 1806 of yacc.c */ ++#line 293 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 29: +-#line 283 "dtc-parser.y" /* yacc.c:1646 */ ++ case 31: ++ ++/* Line 1806 of yacc.c */ ++#line 300 "dtc-parser.y" + { + unsigned long long bits; + +- bits = (yyvsp[-1].integer); ++ bits = (yyvsp[(2) - (3)].integer); + + if ((bits != 8) && (bits != 16) && + (bits != 32) && (bits != 64)) { +- ERROR(&(yylsp[-1]), "Array elements must be" ++ ERROR(&(yylsp[(2) - (3)]), "Array elements must be" + " 8, 16, 32 or 64-bits"); + bits = 32; + } +@@ -1737,23 +1918,25 @@ yyreduce: + (yyval.array).data = empty_data; + (yyval.array).bits = bits; + } +-#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 30: +-#line 299 "dtc-parser.y" /* yacc.c:1646 */ ++ case 32: ++ ++/* Line 1806 of yacc.c */ ++#line 316 "dtc-parser.y" + { + (yyval.array).data = empty_data; + (yyval.array).bits = 32; + } +-#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 31: +-#line 304 "dtc-parser.y" /* yacc.c:1646 */ ++ case 33: ++ ++/* Line 1806 of yacc.c */ ++#line 321 "dtc-parser.y" + { +- if ((yyvsp[-1].array).bits < 64) { +- uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; ++ if ((yyvsp[(1) - (2)].array).bits < 64) { ++ uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; + /* + * Bits above mask must either be all zero + * (positive within range of mask) or all one +@@ -1762,258 +1945,293 @@ yyreduce: + * within the mask to one (i.e. | in the + * mask), all bits are one. + */ +- if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) +- ERROR(&(yylsp[0]), "Value out of range for" +- " %d-bit array element", (yyvsp[-1].array).bits); ++ if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) ++ ERROR(&(yylsp[(2) - (2)]), "Value out of range for" ++ " %d-bit array element", (yyvsp[(1) - (2)].array).bits); + } + +- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); ++ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); + } +-#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 32: +-#line 323 "dtc-parser.y" /* yacc.c:1646 */ ++ case 34: ++ ++/* Line 1806 of yacc.c */ ++#line 340 "dtc-parser.y" + { +- uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); ++ uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); + +- if ((yyvsp[-1].array).bits == 32) +- (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, ++ if ((yyvsp[(1) - (2)].array).bits == 32) ++ (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, + REF_PHANDLE, +- (yyvsp[0].labelref)); ++ (yyvsp[(2) - (2)].labelref)); + else +- ERROR(&(yylsp[0]), "References are only allowed in " ++ ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " + "arrays with 32-bit elements."); + +- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); ++ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); + } +-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 33: +-#line 337 "dtc-parser.y" /* yacc.c:1646 */ ++ case 35: ++ ++/* Line 1806 of yacc.c */ ++#line 354 "dtc-parser.y" + { +- (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); ++ (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 36: +-#line 346 "dtc-parser.y" /* yacc.c:1646 */ ++ case 38: ++ ++/* Line 1806 of yacc.c */ ++#line 363 "dtc-parser.y" + { +- (yyval.integer) = (yyvsp[-1].integer); ++ (yyval.integer) = (yyvsp[(2) - (3)].integer); + } +-#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; +- +- case 39: +-#line 357 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } +-#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 41: +-#line 362 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } +-#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 374 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } + break; + + case 43: +-#line 367 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } +-#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 379 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } + break; + + case 45: +-#line 372 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } +-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 384 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } + break; + + case 47: +-#line 377 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } +-#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 389 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } + break; + + case 49: +-#line 382 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } +-#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 394 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } + break; + + case 51: +-#line 387 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } +-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 399 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } + break; + +- case 52: +-#line 388 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } +-#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 53: ++ ++/* Line 1806 of yacc.c */ ++#line 404 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } + break; + + case 54: +-#line 393 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } +-#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; + +- case 55: +-#line 394 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } +-#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1806 of yacc.c */ ++#line 405 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } + break; + + case 56: +-#line 395 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } +-#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 410 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } + break; + + case 57: +-#line 396 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } +-#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 411 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } + break; + + case 58: +-#line 400 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } +-#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 412 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } + break; + + case 59: +-#line 401 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } +-#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 413 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } ++ break; ++ ++ case 60: ++ ++/* Line 1806 of yacc.c */ ++#line 417 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } + break; + + case 61: +-#line 406 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } +-#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 418 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } + break; + +- case 62: +-#line 407 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } +-#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 63: ++ ++/* Line 1806 of yacc.c */ ++#line 423 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } + break; + + case 64: +-#line 412 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } +-#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; + +- case 65: +-#line 413 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } +-#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1806 of yacc.c */ ++#line 424 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } + break; + + case 66: +-#line 414 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } +-#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 429 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } + break; + +- case 69: +-#line 420 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = -(yyvsp[0].integer); } +-#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 67: ++ ++/* Line 1806 of yacc.c */ ++#line 430 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } + break; + +- case 70: +-#line 421 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = ~(yyvsp[0].integer); } +-#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 68: ++ ++/* Line 1806 of yacc.c */ ++#line 431 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } + break; + + case 71: +-#line 422 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = !(yyvsp[0].integer); } +-#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 437 "dtc-parser.y" ++ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } + break; + + case 72: +-#line 427 "dtc-parser.y" /* yacc.c:1646 */ +- { +- (yyval.data) = empty_data; +- } +-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 438 "dtc-parser.y" ++ { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } + break; + + case 73: +-#line 431 "dtc-parser.y" /* yacc.c:1646 */ +- { +- (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); +- } +-#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 439 "dtc-parser.y" ++ { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } + break; + + case 74: +-#line 435 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 444 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); ++ (yyval.data) = empty_data; + } +-#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 75: +-#line 442 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 448 "dtc-parser.y" + { +- (yyval.nodelist) = NULL; ++ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); + } +-#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 76: +-#line 446 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 452 "dtc-parser.y" + { +- (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 77: +-#line 450 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 459 "dtc-parser.y" + { +- ERROR(&(yylsp[0]), "Properties must precede subnodes"); +- YYERROR; ++ (yyval.nodelist) = NULL; + } +-#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 78: +-#line 458 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 463 "dtc-parser.y" + { +- (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); ++ (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); + } +-#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 79: +-#line 462 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 467 "dtc-parser.y" + { +- (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); ++ ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); ++ YYERROR; + } +-#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 80: +-#line 466 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 475 "dtc-parser.y" + { +- add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[0].node); ++ (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); + } +-#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + ++ case 81: + +-#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1806 of yacc.c */ ++#line 479 "dtc-parser.y" ++ { ++ (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); ++ } ++ break; ++ ++ case 82: ++ ++/* Line 1806 of yacc.c */ ++#line 483 "dtc-parser.y" ++ { ++ add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.node) = (yyvsp[(2) - (2)].node); ++ } ++ break; ++ ++ ++ ++/* Line 1806 of yacc.c */ ++#line 2235 "dtc-parser.tab.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -2036,7 +2254,7 @@ yyreduce: + *++yyvsp = yyval; + *++yylsp = yyloc; + +- /* Now 'shift' the result of the reduction. Determine what state ++ /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + +@@ -2051,9 +2269,9 @@ yyreduce: + goto yynewstate; + + +-/*--------------------------------------. +-| yyerrlab -- here on detecting error. | +-`--------------------------------------*/ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ + yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ +@@ -2104,20 +2322,20 @@ yyerrlab: + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ ++ error, discard it. */ + + if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } ++ { ++ /* Return failure if at end of input. */ ++ if (yychar == YYEOF) ++ YYABORT; ++ } + else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval, &yylloc); +- yychar = YYEMPTY; +- } ++ { ++ yydestruct ("Error: discarding", ++ yytoken, &yylval, &yylloc); ++ yychar = YYEMPTY; ++ } + } + + /* Else will try to reuse lookahead token after shifting the error +@@ -2137,7 +2355,7 @@ yyerrorlab: + goto yyerrorlab; + + yyerror_range[1] = yylsp[1-yylen]; +- /* Do not reclaim the symbols of the rule whose action triggered ++ /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; +@@ -2150,37 +2368,35 @@ yyerrorlab: + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) +- YYABORT; ++ YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", +- yystos[yystate], yyvsp, yylsp); ++ yystos[yystate], yyvsp, yylsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END + + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of +@@ -2209,7 +2425,7 @@ yyabortlab: + yyresult = 1; + goto yyreturn; + +-#if !defined yyoverflow || YYERROR_VERBOSE ++#if !defined(yyoverflow) || YYERROR_VERBOSE + /*-------------------------------------------------. + | yyexhaustedlab -- memory exhaustion comes here. | + `-------------------------------------------------*/ +@@ -2228,14 +2444,14 @@ yyreturn: + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc); + } +- /* Do not reclaim the symbols of the rule whose action triggered ++ /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp, yylsp); ++ yystos[*yyssp], yyvsp, yylsp); + YYPOPSTACK (1); + } + #ifndef yyoverflow +@@ -2246,12 +2462,18 @@ yyreturn: + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + #endif +- return yyresult; ++ /* Make sure YYID is used. */ ++ return YYID (yyresult); + } +-#line 472 "dtc-parser.y" /* yacc.c:1906 */ ++ ++ ++ ++/* Line 2067 of yacc.c */ ++#line 489 "dtc-parser.y" + + + void yyerror(char const *s) + { + ERROR(&yylloc, "%s", s); + } ++ +diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped +index 30867c6..0b22bbb 100644 +--- a/scripts/dtc/dtc-parser.tab.h_shipped ++++ b/scripts/dtc/dtc-parser.tab.h_shipped +@@ -1,19 +1,19 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ ++/* A Bison parser, made by GNU Bison 2.5. */ + + /* Bison interface for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- ++ ++ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. ++ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +@@ -26,55 +26,50 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED +-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif + +-/* Token type. */ ++/* Tokens. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- enum yytokentype +- { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BYTE = 274, +- DT_STRING = 275, +- DT_LABEL = 276, +- DT_REF = 277, +- DT_INCBIN = 278 +- }; ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +-/* Value type. */ ++ ++ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE ++typedef union YYSTYPE + { +-#line 38 "dtc-parser.y" /* yacc.c:1909 */ ++ ++/* Line 2068 of yacc.c */ ++#line 39 "dtc-parser.y" + + char *propnodename; + char *labelref; +@@ -92,30 +87,32 @@ union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; ++ ++ + +-#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ +-}; ++/* Line 2068 of yacc.c */ ++#line 96 "dtc-parser.tab.h" ++} YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-/* Location type. */ ++extern YYSTYPE yylval; ++ + #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +-typedef struct YYLTYPE YYLTYPE; +-struct YYLTYPE ++typedef struct YYLTYPE + { + int first_line; + int first_column; + int last_line; + int last_column; +-}; ++} YYLTYPE; ++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ + # define YYLTYPE_IS_DECLARED 1 + # define YYLTYPE_IS_TRIVIAL 1 + #endif + +- +-extern YYSTYPE yylval; + extern YYLTYPE yylloc; +-int yyparse (void); + +-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y +index 5a897e3..56b9c15 100644 +--- a/scripts/dtc/dtc-parser.y ++++ b/scripts/dtc/dtc-parser.y +@@ -19,6 +19,7 @@ + */ + %{ + #include ++#include + + #include "dtc.h" + #include "srcpos.h" +@@ -52,9 +53,11 @@ extern bool treesource_error; + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + } + + %token DT_V1 ++%token DT_PLUGIN + %token DT_MEMRESERVE + %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR + %token DT_BITS +@@ -71,6 +74,7 @@ extern bool treesource_error; + + %type propdata + %type propdataprefix ++%type plugindecl + %type memreserve + %type memreserves + %type arrayprefix +@@ -101,10 +105,23 @@ extern bool treesource_error; + %% + + sourcefile: +- DT_V1 ';' memreserves devicetree ++ DT_V1 ';' plugindecl memreserves devicetree + { +- the_boot_info = build_boot_info($3, $4, +- guess_boot_cpuid($4)); ++ $5->is_plugin = $3; ++ $5->is_root = 1; ++ the_boot_info = build_boot_info($4, $5, ++ guess_boot_cpuid($5)); ++ } ++ ; ++ ++plugindecl: ++ /* empty */ ++ { ++ $$ = 0; ++ } ++ | DT_PLUGIN ';' ++ { ++ $$ = 1; + } + ; + +diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c +index 8c4add6..0cbb14c 100644 +--- a/scripts/dtc/dtc.c ++++ b/scripts/dtc/dtc.c +@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ + int minsize; /* Minimum blob size */ + int padsize; /* Additional padding to blob */ + int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ ++int symbol_fixup_support = 0; + + static void fill_fullpaths(struct node *tree, const char *prefix) + { +@@ -51,7 +52,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) + #define FDT_VERSION(version) _FDT_VERSION(version) + #define _FDT_VERSION(version) #version + static const char usage_synopsis[] = "dtc [options] "; +-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; ++static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; + static struct option const usage_long_opts[] = { + {"quiet", no_argument, NULL, 'q'}, + {"in-format", a_argument, NULL, 'I'}, +@@ -69,6 +70,7 @@ static struct option const usage_long_opts[] = { + {"phandle", a_argument, NULL, 'H'}, + {"warning", a_argument, NULL, 'W'}, + {"error", a_argument, NULL, 'E'}, ++ {"symbols", a_argument, NULL, '@'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {NULL, no_argument, NULL, 0x0}, +@@ -99,6 +101,7 @@ static const char * const usage_opts_help[] = { + "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", + "\n\tEnable/disable warnings (prefix with \"no-\")", + "\n\tEnable/disable errors (prefix with \"no-\")", ++ "\n\tSymbols and Fixups support", + "\n\tPrint this help and exit", + "\n\tPrint version and exit", + NULL, +@@ -186,7 +189,9 @@ int main(int argc, char *argv[]) + case 'E': + parse_checks_option(false, true, optarg); + break; +- ++ case '@': ++ symbol_fixup_support = 1; ++ break; + case 'h': + usage(NULL); + default: +diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h +index 56212c8..fe45748 100644 +--- a/scripts/dtc/dtc.h ++++ b/scripts/dtc/dtc.h +@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ + extern int minsize; /* Minimum blob size */ + extern int padsize; /* Additional padding to blob */ + extern int phandle_format; /* Use linux,phandle or phandle properties */ ++extern int symbol_fixup_support;/* enable symbols & fixup support */ + + #define PHANDLE_LEGACY 0x1 + #define PHANDLE_EPAPR 0x2 +@@ -132,6 +133,25 @@ struct label { + struct label *next; + }; + ++struct fixup_entry { ++ int offset; ++ struct node *node; ++ struct property *prop; ++ struct fixup_entry *next; ++}; ++ ++struct fixup { ++ char *ref; ++ struct fixup_entry *entries; ++ struct fixup *next; ++}; ++ ++struct symbol { ++ struct label *label; ++ struct node *node; ++ struct symbol *next; ++}; ++ + struct property { + bool deleted; + char *name; +@@ -158,6 +178,12 @@ struct node { + int addr_cells, size_cells; + + struct label *labels; ++ ++ int is_root; ++ int is_plugin; ++ struct fixup *fixups; ++ struct symbol *symbols; ++ struct fixup_entry *local_fixups; + }; + + #define for_each_label_withdel(l0, l) \ +@@ -181,6 +207,18 @@ struct node { + for_each_child_withdel(n, c) \ + if (!(c)->deleted) + ++#define for_each_fixup(n, f) \ ++ for ((f) = (n)->fixups; (f); (f) = (f)->next) ++ ++#define for_each_fixup_entry(f, fe) \ ++ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) ++ ++#define for_each_symbol(n, s) \ ++ for ((s) = (n)->symbols; (s); (s) = (s)->next) ++ ++#define for_each_local_fixup_entry(n, fe) \ ++ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) ++ + void add_label(struct label **labels, char *label); + void delete_labels(struct label **labels); + +diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c +index bd99fa2..f439b40 100644 +--- a/scripts/dtc/flattree.c ++++ b/scripts/dtc/flattree.c +@@ -262,6 +262,12 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + struct property *prop; + struct node *child; + bool seen_name_prop = false; ++ struct symbol *sym; ++ struct fixup *f; ++ struct fixup_entry *fe; ++ char *name, *s; ++ const char *fullpath; ++ int namesz, nameoff, vallen; + + if (tree->deleted) + return; +@@ -276,8 +282,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + emit->align(etarget, sizeof(cell_t)); + + for_each_property(tree, prop) { +- int nameoff; +- + if (streq(prop->name, "name")) + seen_name_prop = true; + +@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + flatten_tree(child, emit, etarget, strbuf, vi); + } + ++ if (!symbol_fixup_support) ++ goto no_symbols; ++ ++ /* add the symbol nodes (if any) */ ++ if (tree->symbols) { ++ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__symbols__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ for_each_symbol(tree, sym) { ++ ++ vallen = strlen(sym->node->fullpath); ++ ++ nameoff = stringtable_insert(strbuf, sym->label->label); ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, sym->node->fullpath, ++ strlen(sym->node->fullpath)); ++ emit->align(etarget, sizeof(cell_t)); ++ } ++ ++ emit->endnode(etarget, NULL); ++ } ++ ++ /* add the fixup nodes */ ++ if (tree->fixups) { ++ ++ /* emit the external fixups */ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__fixups__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ for_each_fixup(tree, f) { ++ ++ namesz = 0; ++ for_each_fixup_entry(f, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ namesz += strlen(fullpath) + 1; ++ namesz += strlen(fe->prop->name) + 1; ++ namesz += 32; /* space for : + '\0' */ ++ } ++ ++ name = xmalloc(namesz); ++ ++ s = name; ++ for_each_fixup_entry(f, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ snprintf(s, name + namesz - s, "%s:%s:%d", ++ fullpath, ++ fe->prop->name, fe->offset); ++ s += strlen(s) + 1; ++ } ++ ++ nameoff = stringtable_insert(strbuf, f->ref); ++ vallen = s - name - 1; ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, name, vallen); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ free(name); ++ } ++ ++ emit->endnode(etarget, tree->labels); ++ } ++ ++ /* add the local fixup property */ ++ if (tree->local_fixups) { ++ ++ /* emit the external fixups */ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__local_fixups__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ namesz = 0; ++ for_each_local_fixup_entry(tree, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ namesz += strlen(fullpath) + 1; ++ namesz += strlen(fe->prop->name) + 1; ++ namesz += 32; /* space for : + '\0' */ ++ } ++ ++ name = xmalloc(namesz); ++ ++ s = name; ++ for_each_local_fixup_entry(tree, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ snprintf(s, name + namesz - s, "%s:%s:%d", ++ fullpath, fe->prop->name, ++ fe->offset); ++ s += strlen(s) + 1; ++ } ++ ++ nameoff = stringtable_insert(strbuf, "fixup"); ++ vallen = s - name - 1; ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, name, vallen); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ free(name); ++ ++ emit->endnode(etarget, tree->labels); ++ } ++ ++no_symbols: + emit->endnode(etarget, tree->labels); + } + +diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h +index 5b8c7d5..86b7338 100644 +--- a/scripts/dtc/version_gen.h ++++ b/scripts/dtc/version_gen.h +@@ -1 +1 @@ +-#define DTC_VERSION "DTC 1.4.1-g9d3649bd" ++#define DTC_VERSION "DTC 1.4.1-g9d3649bd-dirty" + +From 03742881e78586b8a8e10fdbad4371d4d665a9fc Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 122/204] Merge pull request #1043 from XECDesign/sense-4.0 +Subject: [PATCH 089/113] Merge pull request #1043 from XECDesign/sense-4.0 mfd: Add Raspberry Pi Sense HAT core driver --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 +++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - drivers/input/joystick/Kconfig | 8 + - drivers/input/joystick/Makefile | 1 + - drivers/input/joystick/rpisense-js.c | 153 +++++++++++++++ - drivers/mfd/Kconfig | 8 + - drivers/mfd/Makefile | 2 + - drivers/mfd/rpisense-core.c | 157 +++++++++++++++ - drivers/video/fbdev/Kconfig | 13 ++ - drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/rpisense-fb.c | 235 +++++++++++++++++++++++ - include/linux/mfd/rpisense/core.h | 47 +++++ - include/linux/mfd/rpisense/framebuffer.h | 28 +++ - include/linux/mfd/rpisense/joystick.h | 35 ++++ - 17 files changed, 746 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts + drivers/input/joystick/Kconfig | 8 + + drivers/input/joystick/Makefile | 1 + + drivers/input/joystick/rpisense-js.c | 153 ++++++++++++++++ + drivers/mfd/Kconfig | 8 + + drivers/mfd/Makefile | 2 + + drivers/mfd/rpisense-core.c | 157 +++++++++++++++++ + drivers/video/fbdev/Kconfig | 13 ++ + drivers/video/fbdev/Makefile | 1 + + drivers/video/fbdev/rpisense-fb.c | 293 +++++++++++++++++++++++++++++++ + include/linux/mfd/rpisense/core.h | 47 +++++ + include/linux/mfd/rpisense/framebuffer.h | 32 ++++ + include/linux/mfd/rpisense/joystick.h | 35 ++++ + 12 files changed, 750 insertions(+) create mode 100644 drivers/input/joystick/rpisense-js.c create mode 100644 drivers/mfd/rpisense-core.c create mode 100644 drivers/video/fbdev/rpisense-fb.c @@ -140287,133 +138918,11 @@ mfd: Add Raspberry Pi Sense HAT core driver create mode 100644 include/linux/mfd/rpisense/framebuffer.h create mode 100644 include/linux/mfd/rpisense/joystick.h -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4ff9836..5f6082f 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -39,6 +39,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 88ed678..8792f98 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -442,6 +442,12 @@ Load: dtoverlay=rpi-proto - Params: - - -+Name: rpi-sense -+Info: Raspberry Pi Sense HAT -+Load: dtoverlay=rpi-sense -+Params: -+ -+ - Name: sdhost - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock - Load: dtoverlay=sdhost,= -diff --git a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -new file mode 100644 -index 0000000..2715324 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -@@ -0,0 +1,47 @@ -+// rpi-sense HAT -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ rpi-sense@46 { -+ compatible = "rpi,rpi-sense"; -+ reg = <0x46>; -+ keys-int-gpios = <&gpio 23 1>; -+ status = "okay"; -+ }; -+ -+ lsm9ds1-magn@1c { -+ compatible = "st,lsm9ds1-magn"; -+ reg = <0x1c>; -+ status = "okay"; -+ }; -+ -+ lsm9ds1-accel6a { -+ compatible = "st,lsm9ds1-accel"; -+ reg = <0x6a>; -+ status = "okay"; -+ }; -+ -+ lps25h-press@5c { -+ compatible = "st,lps25h-press"; -+ reg = <0x5c>; -+ status = "okay"; -+ }; -+ -+ hts221-humid@5f { -+ compatible = "st,hts221-humid"; -+ reg = <0x5f>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d75b104..f78a483 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -533,6 +533,7 @@ CONFIG_JOYSTICK_IFORCE=m - CONFIG_JOYSTICK_IFORCE_USB=y - CONFIG_JOYSTICK_XPAD=m - CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -@@ -789,6 +790,7 @@ CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 9159892..b9b5bdf 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -526,6 +526,7 @@ CONFIG_JOYSTICK_IFORCE=m - CONFIG_JOYSTICK_IFORCE_USB=y - CONFIG_JOYSTICK_XPAD=m - CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -@@ -782,6 +783,7 @@ CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig -index 56eb471..73e3a23 100644 +index 4215b53..4364d7c 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig -@@ -329,4 +329,12 @@ config JOYSTICK_MAPLE +@@ -330,4 +330,12 @@ config JOYSTICK_MAPLE To compile this as a module choose M here: the module will be called maplecontrol. @@ -140596,7 +139105,7 @@ index 0000000..9eca897 +MODULE_AUTHOR("Serge Schneider "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index d5ad04d..dfb730e 100644 +index 99d6367..296daf8 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -10,6 +10,14 @@ config MFD_CORE @@ -140615,10 +139124,10 @@ index d5ad04d..dfb730e 100644 tristate "AMD CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 0e5cfeb..9c491fb 100644 +index a59e3fc..205084b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile -@@ -185,3 +185,5 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o +@@ -192,3 +192,5 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o @@ -140788,13 +139297,13 @@ index 0000000..7539547 +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index 15098c5..b89998b7 100644 +index f1b031e..2a28938 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig -@@ -2495,3 +2495,16 @@ config FB_SSD1307 - help - This driver implements support for the Solomon SSD1307 - OLED controller over I2C. +@@ -2503,3 +2503,16 @@ config FB_SM712 + This driver is also available as a module. The module will be + called sm712fb. If you want to compile it as a module, say M + here and read . + +config FB_RPISENSE + tristate "Raspberry Pi Sense HAT framebuffer" @@ -140809,7 +139318,7 @@ index 15098c5..b89998b7 100644 + help + This is the framebuffer driver for the Raspberry Pi Sense HAT diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 57181ad..ee7568b 100644 +index 9b086ac..7101277 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o @@ -140822,10 +139331,10 @@ index 57181ad..ee7568b 100644 obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/fbdev/rpisense-fb.c b/drivers/video/fbdev/rpisense-fb.c new file mode 100644 -index 0000000..99bb8ea +index 0000000..90553fa --- /dev/null +++ b/drivers/video/fbdev/rpisense-fb.c -@@ -0,0 +1,235 @@ +@@ -0,0 +1,293 @@ +/* + * Raspberry Pi Sense HAT framebuffer driver + * http://raspberrypi.org @@ -140847,6 +139356,7 @@ index 0000000..99bb8ea +#include +#include +#include ++#include +#include +#include +#include @@ -140854,22 +139364,35 @@ index 0000000..99bb8ea +#include +#include + ++static bool lowlight; ++module_param(lowlight, bool, 0); ++MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); ++ +struct rpisense *rpisense; + +struct rpisense_fb_param { + char __iomem *vmem; + u8 *vmem_work; + u32 vmemsize; -+ u8 gamma[32]; ++ u8 *gamma; +}; + ++static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, ++ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, ++ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}; ++ ++static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, ++ 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, ++ 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,}; ++ ++static u8 gamma_user[32]; ++ +static struct rpisense_fb_param rpisense_fb_param = { + .vmem = NULL, + .vmemsize = 128, -+ .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -+ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, -+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, -+ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}, ++ .gamma = gamma_default, +}; + +static struct fb_deferred_io rpisense_fb_defio; @@ -140955,6 +139478,46 @@ index 0000000..99bb8ea + .deferred_io = rpisense_fb_deferred_io, +}; + ++static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd, ++ unsigned long arg) ++{ ++ switch (cmd) { ++ case SENSEFB_FBIOGET_GAMMA: ++ if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma, ++ sizeof(u8[32]))) ++ return -EFAULT; ++ return 0; ++ case SENSEFB_FBIOSET_GAMMA: ++ if (copy_from_user(gamma_user, (void __user *)arg, ++ sizeof(u8[32]))) ++ return -EFAULT; ++ rpisense_fb_param.gamma = gamma_user; ++ schedule_delayed_work(&info->deferred_work, ++ rpisense_fb_defio.delay); ++ return 0; ++ case SENSEFB_FBIORESET_GAMMA: ++ switch (arg) { ++ case 0: ++ rpisense_fb_param.gamma = gamma_default; ++ break; ++ case 1: ++ rpisense_fb_param.gamma = gamma_low; ++ break; ++ case 2: ++ rpisense_fb_param.gamma = gamma_user; ++ break; ++ default: ++ return -EINVAL; ++ } ++ schedule_delayed_work(&info->deferred_work, ++ rpisense_fb_defio.delay); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ +static struct fb_ops rpisense_fb_ops = { + .owner = THIS_MODULE, + .fb_read = fb_sys_read, @@ -140962,6 +139525,7 @@ index 0000000..99bb8ea + .fb_fillrect = rpisense_fb_fillrect, + .fb_copyarea = rpisense_fb_copyarea, + .fb_imageblit = rpisense_fb_imageblit, ++ .fb_ioctl = rpisense_fb_ioctl, +}; + +static int rpisense_fb_probe(struct platform_device *pdev) @@ -140999,6 +139563,9 @@ index 0000000..99bb8ea + info->screen_base = rpisense_fb_param.vmem; + info->screen_size = rpisense_fb_param.vmemsize; + ++ if (lowlight) ++ rpisense_fb_param.gamma = gamma_low; ++ + fb_deferred_io_init(info); + + ret = register_framebuffer(info); @@ -141116,10 +139683,10 @@ index 0000000..4856aa3 +#endif diff --git a/include/linux/mfd/rpisense/framebuffer.h b/include/linux/mfd/rpisense/framebuffer.h new file mode 100644 -index 0000000..c4c1118 +index 0000000..2ba95d7 --- /dev/null +++ b/include/linux/mfd/rpisense/framebuffer.h -@@ -0,0 +1,28 @@ +@@ -0,0 +1,32 @@ +/* + * Raspberry Pi Sense HAT framebuffer driver + * http://raspberrypi.org @@ -141138,7 +139705,11 @@ index 0000000..c4c1118 +#ifndef __LINUX_RPISENSE_FB_H_ +#define __LINUX_RPISENSE_FB_H_ + -+#include ++#define SENSEFB_FBIO_IOC_MAGIC 0xF1 ++ ++#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0) ++#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1) ++#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2) + +struct rpisense; + @@ -141190,2846 +139761,10 @@ index 0000000..56196dc + +#endif -From 7ec906836d03f54c2f62372c25a413af323c2564 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 15 Jul 2015 13:46:08 +0100 -Subject: [PATCH 123/204] leds-gpio: Implement the brightness_get method - -The power LED uses some clever logic that means it is driven -by a voltage measuring circuit when configured as input, otherwise -it is driven by the GPIO output value. This patch wires up the -brightness_get method for leds-gpio so that user-space can monitor -the LED value via /sys/class/gpio/led1/brightness. Using the input -trigger this returns an indication of the system power health, -otherwise it is just whatever value the trigger has written most -recently. - -See: https://github.com/raspberrypi/linux/issues/1064 ---- - drivers/leds/leds-gpio.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 3cfbd6a..4e4e132 100644 ---- a/drivers/leds/leds-gpio.c -+++ b/drivers/leds/leds-gpio.c -@@ -82,6 +82,13 @@ static void gpio_led_set(struct led_classdev *led_cdev, - } - } - -+static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) -+{ -+ struct gpio_led_data *led_dat = -+ container_of(led_cdev, struct gpio_led_data, cdev); -+ return gpiod_get_value_cansleep(led_dat->gpiod) ? LED_FULL : LED_OFF; -+} -+ - static int gpio_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, unsigned long *delay_off) - { -@@ -138,6 +145,7 @@ static int create_gpio_led(const struct gpio_led *template, - led_dat->cdev.blink_set = gpio_blink_set; - } - led_dat->cdev.brightness_set = gpio_led_set; -+ led_dat->cdev.brightness_get = gpio_led_get; - if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) - state = !!gpiod_get_value_cansleep(led_dat->gpiod); - else - -From 0cfac48f6780a5038da6e0fc0e37dfc3975f2077 Mon Sep 17 00:00:00 2001 -From: Robert Tiemann -Date: Fri, 17 Jul 2015 09:50:55 +0200 -Subject: [PATCH 124/204] dmaengine: bcm2708-dmaengine: Fix memory leak when - stopping a running transfer - ---- - drivers/dma/bcm2708-dmaengine.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 987ed53..73c6c00 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -964,6 +964,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan) - * c->desc is NULL and exit.) - */ - if (c->desc) { -+ bcm2835_dma_desc_free(&c->desc->vd); - c->desc = NULL; - bcm2835_dma_abort(c->chan_base); - - -From 095268253a866ff43278ff24f4a7502949c6cf92 Mon Sep 17 00:00:00 2001 -From: Robert Tiemann -Date: Mon, 20 Jul 2015 11:01:13 +0200 -Subject: [PATCH 125/204] BCM270X_DT: Fix I2S register map - ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 2dd25f7..728e14a 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -117,8 +117,8 @@ - - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - //dmas = <&dma 2>, - // <&dma 3>; - -From 649b011d757054ad6d9d5702f8d3bf670a42e404 Mon Sep 17 00:00:00 2001 -From: Robert Tiemann -Date: Mon, 20 Jul 2015 11:01:25 +0200 -Subject: [PATCH 126/204] BCM2835_DT: Fix I2S register map - ---- - Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- - Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 4 ++-- - arch/arm/boot/dts/bcm2835.dtsi | 4 ++-- - 3 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt -index 1396078..2db8294 100644 ---- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt -+++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt -@@ -48,8 +48,8 @@ Example: - - bcm2835_i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = < 0x7e203000 0x20>, -- < 0x7e101098 0x02>; -+ reg = < 0x7e203000 0x24>, -+ < 0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; -diff --git a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt -index 65783de..a89fe42 100644 ---- a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt -+++ b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt -@@ -16,8 +16,8 @@ Example: - - bcm2835_i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 4a63704..1135120 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -101,8 +101,8 @@ - - i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; - -From 5076ca8360f9ad0d46a060fcde7eefe7fb10eea1 Mon Sep 17 00:00:00 2001 -From: David Frey -Date: Tue, 14 Jul 2015 15:57:36 +0200 -Subject: [PATCH 127/204] config: Enable SHT drivers for raspberry pi - -The SHT temperature and humidity sensors are often used in weather -station projects. - -Signed-off-by: David Frey ---- - arch/arm/configs/bcm2709_defconfig | 4 +++- - arch/arm/configs/bcmrpi_defconfig | 4 +++- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index f78a483..dd00e7c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -611,7 +611,9 @@ CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y --# CONFIG_HWMON is not set -+CONFIG_HWMON=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHTC1=m - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index b9b5bdf..7b24274 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -604,7 +604,9 @@ CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y --# CONFIG_HWMON is not set -+CONFIG_HWMON=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHTC1=m - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y - -From 2e23dd0be7034e7aee9795288d9de1ed151ad5fd Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 14:07:14 +0100 -Subject: [PATCH 128/204] BCM270X_DT: Correct typo in overlays/README - ---- - arch/arm/boot/dts/overlays/README | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 8792f98..ed484ae 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -78,7 +78,7 @@ Name: - Info: Configures the base Raspberry Pi hardware - Load: - Params: -- audio Set to "on" to disable the onboard ALSA audio -+ audio Set to "on" to enable the onboard ALSA audio - interface (default "off") - - i2c_arm Set to "on" to enable the ARM's i2c interface - -From dc0a5bcc935ccc881fb4043dc949af755d3e8f1c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 10:53:26 +0100 -Subject: [PATCH 129/204] bcm2835-sdhost: Add the ERASE capability - -See: https://github.com/raspberrypi/linux/issues/1076 ---- - drivers/mmc/host/bcm2835-sdhost.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index d65870a..57a6ad3 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -1675,7 +1675,7 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - /* host controller capabilities */ - mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -- MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | -+ MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | - (ALLOW_CMD23 * MMC_CAP_CMD23); - - spin_lock_init(&host->lock); - -From 54ef0643fae43fff2cb1583919a34f787ad132af Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 17:32:18 +0100 -Subject: [PATCH 130/204] bcm2835-sdhost: Ignore CRC7 for MMC CMD1 - -It seems that the sdhost interface returns CRC7 errors for CMD1, -which is the MMC-specific SEND_OP_COND. Returning these errors to -the MMC layer causes a downward spiral, but ignoring them seems -to be harmless. ---- - drivers/mmc/host/bcm2835-sdhost.c | 39 +++++++++++++++++++++++---------------- - 1 file changed, 23 insertions(+), 16 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 57a6ad3..84f645f 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -959,25 +959,32 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - mmc_hostname(host->mmc), sdcmd, sdhsts, - bcm2835_sdhost_read(host, SDEDM)); - -- if (sdhsts & SDHSTS_CMD_TIME_OUT) { -- switch (host->cmd->opcode) { -- case 5: case 52: case 53: -- /* Don't warn about SDIO commands */ -- break; -- default: -- pr_err("%s: command timeout\n", -+ if ((sdhsts & SDHSTS_CRC7_ERROR) && -+ (host->cmd->opcode == 1)) { -+ if (host->debug) -+ pr_info("%s: ignoring CRC7 error for CMD1\n", -+ mmc_hostname(host->mmc)); -+ } else { -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) { -+ switch (host->cmd->opcode) { -+ case 5: case 52: case 53: -+ /* Don't warn about SDIO commands */ -+ break; -+ default: -+ pr_err("%s: command timeout\n", -+ mmc_hostname(host->mmc)); -+ break; -+ } -+ host->cmd->error = -ETIMEDOUT; -+ } else { -+ pr_err("%s: unexpected command error\n", - mmc_hostname(host->mmc)); -- break; -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; - } -- host->cmd->error = -ETIMEDOUT; -- } else { -- pr_err("%s: unexpected command error\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; - } -- tasklet_schedule(&host->finish_tasklet); -- return; - } - - if (host->cmd->flags & MMC_RSP_PRESENT) { - -From 24f4ffb4f7a2f5b37197a168485207216b736adb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 14:48:21 +0100 -Subject: [PATCH 131/204] BCM270X_DT: Add unit address to gpio node name - ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 728e14a..cb608df 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -92,7 +92,7 @@ - status = "disabled"; - }; - -- gpio: gpio { -+ gpio: gpio@7e200000 { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; - interrupts = <2 17>, <2 18>; - -From 7d633f69a6cbc12d37782f6ab96e402eb1b18949 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 24 Jul 2015 10:36:32 +0100 -Subject: [PATCH 132/204] BCM270X_DT: Use i2c_arm for rtc and bmp085 overlays - ---- - arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -index b830bf2..782b171 100644 ---- a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -@@ -6,7 +6,7 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -- target = <&i2c1>; -+ target = <&i2c_arm>; - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index 7052c71..fed4bd8 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -6,7 +6,7 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -- target = <&i2c1>; -+ target = <&i2c_arm>; - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; - -From 70694a4073fa62862c93ab409b49d3d86071a6c0 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 24 Jul 2015 12:11:31 +0100 -Subject: [PATCH 133/204] BCM2708_DT: CM dtparams for audio, watchdog and RNG - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 34d4bc6..713e5a2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -17,14 +17,14 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; - -From a36ecdc70162e181fac2f7b7afb952639df22384 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:13:18 +0200 -Subject: [PATCH 134/204] vchiq: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 1 + - .../vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 17 +++++++++-------- - .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 +++++++++++++++++ - 3 files changed, 27 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index cb608df..df66e64 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -225,6 +225,7 @@ - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; - cache-line-size = <32>; -+ firmware = <&firmware>; - }; - - thermal: thermal { -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 56bff05..c9febcc 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -39,11 +39,11 @@ - #include - #include - #include --#include - #include - #include - #include - #include -+#include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - -@@ -89,10 +89,12 @@ free_pagelist(PAGELIST_T *pagelist, int actual); - int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - { - struct device *dev = &pdev->dev; -+ struct rpi_firmware *fw = platform_get_drvdata(pdev); - VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; - struct resource *res; - void *slot_mem; - dma_addr_t slot_phys; -+ u32 channelbase; - int slot_mem_size, frag_mem_size; - int err, irq, i; - -@@ -157,13 +159,12 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - } - - /* Send the base address of the slots to VideoCore */ -- -- dsb(); /* Ensure all writes have completed */ -- -- err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); -- if (err) { -- dev_err(dev, "mailbox write failed\n"); -- return err; -+ channelbase = slot_phys; -+ err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, -+ &channelbase, sizeof(channelbase)); -+ if (err || channelbase) { -+ dev_err(dev, "failed to set channelbase\n"); -+ return err ? : -ENXIO; - } - - vchiq_log_info(vchiq_arm_log_level, -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index 31e2cba..e11c0e0 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -45,7 +45,9 @@ - #include - #include - #include -+#include - #include -+#include - - #include "vchiq_core.h" - #include "vchiq_ioctl.h" -@@ -2793,9 +2795,24 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, - - static int vchiq_probe(struct platform_device *pdev) - { -+ struct device_node *fw_node; -+ struct rpi_firmware *fw; - int err; - void *ptr_err; - -+ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); -+/* Remove comment when booting without Device Tree is no longer supported -+ if (!fw_node) { -+ dev_err(&pdev->dev, "Missing firmware node\n"); -+ return -ENOENT; -+ } -+*/ -+ fw = rpi_firmware_get(fw_node); -+ if (!fw) -+ return -EPROBE_DEFER; -+ -+ platform_set_drvdata(pdev, fw); -+ - /* create debugfs entries */ - err = vchiq_debugfs_init(); - if (err != 0) - -From 97df14a49141d2831362aac3d18875d271b1a97f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:17:10 +0200 -Subject: [PATCH 135/204] thermal: bcm2835: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. -Remove retry loop on failure to read temperature. -Clean up code. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 1 + - drivers/thermal/bcm2835-thermal.c | 197 +++++++++++++--------------------- - 2 files changed, 75 insertions(+), 123 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index df66e64..bd8ac0a 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -230,6 +230,7 @@ - - thermal: thermal { - compatible = "brcm,bcm2835-thermal"; -+ firmware = <&firmware>; - }; - }; - -diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c -index 3bc80f1..c1d8f1b 100644 ---- a/drivers/thermal/bcm2835-thermal.c -+++ b/drivers/thermal/bcm2835-thermal.c -@@ -12,161 +12,113 @@ - * consent. - *****************************************************************************/ - --#include - #include --#include --#include - #include --#include --#include - #include -+#include - -- --/* --- DEFINITIONS --- */ --#define MODULE_NAME "bcm2835_thermal" -- --/*#define THERMAL_DEBUG_ENABLE*/ -- --#ifdef THERMAL_DEBUG_ENABLE --#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) --#else --#define print_debug(fmt,...) --#endif --#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) -- --#define VC_TAG_GET_TEMP 0x00030006 --#define VC_TAG_GET_MAX_TEMP 0x0003000A -- --typedef enum { -- TEMP, -- MAX_TEMP, --} temp_type; -- --/* --- STRUCTS --- */ --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the tag ID for the temperature */ -- uint32_t buffer_size; /* size of the buffer (should be 8) */ -- uint32_t request_code; /* identifies message as a request (should be 0) */ -- uint32_t id; /* extra ID field (should be 0) */ -- uint32_t val; /* returned value of the temperature */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- --struct bcm2835_thermal_data { -- struct thermal_zone_device *thermal_dev; -- struct vc_msg msg; --}; -- --/* --- GLOBALS --- */ --static struct bcm2835_thermal_data bcm2835_data; -- --/* Thermal Device Operations */ --static struct thermal_zone_device_ops ops; -- --/* --- FUNCTIONS --- */ -- --static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id) -+static int bcm2835_thermal_get_property(struct thermal_zone_device *tz, -+ unsigned long *temp, u32 tag) - { -- int result = -1, retry = 3; -- print_debug("IN"); -+ struct rpi_firmware *fw = tz->devdata; -+ struct { -+ u32 id; -+ u32 val; -+ } packet; -+ int ret; - - *temp = 0; -- while (result != 0 && retry-- > 0) { -- /* wipe all previous message data */ -- memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg); -- -- /* prepare message */ -- bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg; -- bcm2835_data.msg.tag.buffer_size = 8; -- bcm2835_data.msg.tag.tag_id = tag_id; -- -- /* send the message */ -- result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg); -- print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code); -- if (!(bcm2835_data.msg.request_code & 0x80000000)) -- result = -1; -+ packet.id = 0; -+ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); -+ if (ret) { -+ dev_err(&tz->device, "Failed to get temperature\n"); -+ return ret; - } - -- /* check if it was all ok and return the rate in milli degrees C */ -- if (result == 0) -- *temp = (uint)bcm2835_data.msg.tag.val; -- else -- print_err("Failed to get temperature! (%x:%d)\n", tag_id, result); -- print_debug("OUT"); -- return result; -+ *temp = packet.val; -+ dev_dbg(&tz->device, "%stemp=%lu\n", -+ tag == RPI_FIRMWARE_GET_MAX_TEMPERATURE ? "max" : "", *temp); -+ -+ return 0; - } - --static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp) -+static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz, -+ unsigned long *temp) - { -- return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP); -+ return bcm2835_thermal_get_property(tz, temp, -+ RPI_FIRMWARE_GET_TEMPERATURE); - } - --static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp) -+static int bcm2835_thermal_get_max_temp(struct thermal_zone_device *tz, -+ int trip, unsigned long *temp) - { -- return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP); -+ /* -+ * The maximum safe temperature of the SoC. -+ * Overclock may be disabled above this temperature. -+ */ -+ return bcm2835_thermal_get_property(tz, temp, -+ RPI_FIRMWARE_GET_MAX_TEMPERATURE); - } - --static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type) -+static int bcm2835_thermal_get_trip_type(struct thermal_zone_device *tz, -+ int trip, enum thermal_trip_type *type) - { -- *trip_type = THERMAL_TRIP_HOT; -+ *type = THERMAL_TRIP_HOT; -+ - return 0; - } - -- --static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode) -+static int bcm2835_thermal_get_mode(struct thermal_zone_device *tz, -+ enum thermal_device_mode *mode) - { -- *dev_mode = THERMAL_DEVICE_ENABLED; -+ *mode = THERMAL_DEVICE_ENABLED; -+ - return 0; - } - -+static struct thermal_zone_device_ops ops = { -+ .get_temp = bcm2835_thermal_get_temp, -+ .get_trip_temp = bcm2835_thermal_get_max_temp, -+ .get_trip_type = bcm2835_thermal_get_trip_type, -+ .get_mode = bcm2835_thermal_get_mode, -+}; - - static int bcm2835_thermal_probe(struct platform_device *pdev) - { -- print_debug("IN"); -- print_debug("THERMAL Driver has been probed!"); -- -- /* check that the device isn't null!*/ -- if(pdev == NULL) -- { -- print_debug("Platform device is empty!"); -- return -ENODEV; -+ struct device_node *fw_np; -+ struct rpi_firmware *fw; -+ struct thermal_zone_device *tz; -+ -+ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0); -+/* Remove comment when booting without Device Tree is no longer supported -+ if (!fw_np) { -+ dev_err(&pdev->dev, "Missing firmware node\n"); -+ return -ENOENT; - } -- -- if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0))) -- { -- print_debug("Unable to register the thermal device!"); -- return -EFAULT; -+*/ -+ fw = rpi_firmware_get(fw_np); -+ if (!fw) -+ return -EPROBE_DEFER; -+ -+ tz = thermal_zone_device_register("bcm2835_thermal", 1, 0, fw, &ops, -+ NULL, 0, 0); -+ if (IS_ERR(tz)) { -+ dev_err(&pdev->dev, "Failed to register the thermal device\n"); -+ return PTR_ERR(tz); - } -+ -+ platform_set_drvdata(pdev, tz); -+ - return 0; - } - -- - static int bcm2835_thermal_remove(struct platform_device *pdev) - { -- print_debug("IN"); -- -- thermal_zone_device_unregister(bcm2835_data.thermal_dev); -- -- print_debug("OUT"); -+ thermal_zone_device_unregister(platform_get_drvdata(pdev)); - - return 0; - } - --static struct thermal_zone_device_ops ops = { -- .get_temp = bcm2835_get_temp, -- .get_trip_temp = bcm2835_get_max_temp, -- .get_trip_type = bcm2835_get_trip_type, -- .get_mode = bcm2835_get_mode, --}; -- - static const struct of_device_id bcm2835_thermal_of_match_table[] = { - { .compatible = "brcm,bcm2835-thermal", }, - {}, -@@ -177,14 +129,13 @@ static struct platform_driver bcm2835_thermal_driver = { - .probe = bcm2835_thermal_probe, - .remove = bcm2835_thermal_remove, - .driver = { -- .name = "bcm2835_thermal", -- .owner = THIS_MODULE, -- .of_match_table = bcm2835_thermal_of_match_table, -- }, -+ .name = "bcm2835_thermal", -+ .of_match_table = bcm2835_thermal_of_match_table, -+ }, - }; -+module_platform_driver(bcm2835_thermal_driver); - --MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Dorian Peake"); -+MODULE_AUTHOR("Noralf Trønnes"); - MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); -- --module_platform_driver(bcm2835_thermal_driver); -+MODULE_LICENSE("GPL"); - -From c2e3b884a9498adb58d4d403465e2d99ddd79e61 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:18:36 +0200 -Subject: [PATCH 136/204] cpufreq: bcm2835: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. - -Signed-off-by: Noralf Trønnes ---- - drivers/cpufreq/bcm2835-cpufreq.c | 117 +++++++++++++++++--------------------- - 1 file changed, 53 insertions(+), 64 deletions(-) - -diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c -index 6735da9..3eb9e93 100644 ---- a/drivers/cpufreq/bcm2835-cpufreq.c -+++ b/drivers/cpufreq/bcm2835-cpufreq.c -@@ -26,7 +26,7 @@ - #include - #include - #include --#include -+#include - - /* ---------- DEFINES ---------- */ - /*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ -@@ -43,23 +43,6 @@ - #define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) - #define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__) - --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the message id */ -- uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -- uint32_t data_size; /* amount of data being sent or received */ -- uint32_t dev_id; /* the ID of the clock/voltage to get or set */ -- uint32_t val; /* the value (e.g. rate (in Hz)) to set */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- - /* ---------- GLOBALS ---------- */ - static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */ - -@@ -74,62 +57,63 @@ static struct cpufreq_frequency_table bcm2835_freq_table[] = { - clk_rate either gets or sets the clock rates. - =============================================== - */ --static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) -+ -+static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) - { -- int s, actual_rate=0; -- struct vc_msg msg; -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); -+ struct { -+ u32 id; -+ u32 val; -+ } packet; -+ int ret; -+ -+ packet.id = id; -+ packet.val = *val; -+ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); -+ if (ret) -+ return ret; - -- /* wipe all previous message data */ -- memset(&msg, 0, sizeof msg); -+ *val = packet.val; - -- msg.msg_size = sizeof msg; -+ return 0; -+} - -- msg.tag.tag_id = VCMSG_SET_CLOCK_RATE; -- msg.tag.buffer_size = 8; -- msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */ -- msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; -- msg.tag.val = arm_rate * 1000; -+static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) -+{ -+ u32 rate = arm_rate * 1000; -+ int ret; - -- /* send the message */ -- s = bcm_mailbox_property(&msg, sizeof msg); -+ ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate); -+ if (ret) { -+ print_err("Failed to set clock: %d (%d)\n", arm_rate, ret); -+ return 0; -+ } - -- /* check if it was all ok and return the rate in KHz */ -- if (s == 0 && (msg.request_code & 0x80000000)) -- actual_rate = msg.tag.val/1000; -+ rate /= 1000; -+ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate); - -- print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate); -- return actual_rate; -+ return rate; - } - - static uint32_t bcm2835_cpufreq_get_clock(int tag) - { -- int s; -- int arm_rate = 0; -- struct vc_msg msg; -- -- /* wipe all previous message data */ -- memset(&msg, 0, sizeof msg); -- -- msg.msg_size = sizeof msg; -- msg.tag.tag_id = tag; -- msg.tag.buffer_size = 8; -- msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */ -- msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; -+ u32 rate; -+ int ret; - -- /* send the message */ -- s = bcm_mailbox_property(&msg, sizeof msg); -- -- /* check if it was all ok and return the rate in KHz */ -- if (s == 0 && (msg.request_code & 0x80000000)) -- arm_rate = msg.tag.val/1000; -+ ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate); -+ if (ret) { -+ print_err("Failed to get clock (%d)\n", ret); -+ return 0; -+ } - -- print_debug("%s frequency = %d\n", -- tag == VCMSG_GET_CLOCK_RATE ? "Current": -- tag == VCMSG_GET_MIN_CLOCK ? "Min": -- tag == VCMSG_GET_MAX_CLOCK ? "Max": -- "Unexpected", arm_rate); -+ rate /= 1000; -+ print_debug("%s frequency = %u\n", -+ tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current": -+ tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min": -+ tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max": -+ "Unexpected", rate); - -- return arm_rate; -+ return rate; - } - - /* -@@ -165,9 +149,14 @@ static int bcm2835_cpufreq_driver_init(struct cpufreq_policy *policy) - /* measured value of how long it takes to change frequency */ - const unsigned int transition_latency = 355000; /* ns */ - -+ if (!rpi_firmware_get(NULL)) { -+ print_err("Firmware is not available\n"); -+ return -ENODEV; -+ } -+ - /* now find out what the maximum and minimum frequencies are */ -- bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK); -- bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK); -+ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); - - print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency); - return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency); -@@ -201,8 +190,8 @@ static int bcm2835_cpufreq_driver_target_index(struct cpufreq_policy *policy, un - - static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu) - { -- unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE); -- print_debug("%d: freq=%d\n", cpu, actual_rate); -+ unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ print_debug("cpu%d: freq=%d\n", cpu, actual_rate); - return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency; - } - - -From 1ef7396bd8f7fa5452d762b9c534552604c0ec35 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:20:59 +0200 -Subject: [PATCH 137/204] fbdev: bcm2708: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 1 + - drivers/video/fbdev/bcm2708_fb.c | 273 +++++++++++++++++++--------------- - 2 files changed, 152 insertions(+), 122 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index bd8ac0a..d1c3bdf 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -217,6 +217,7 @@ - - fb: fb { - compatible = "brcm,bcm2708-fb"; -+ firmware = <&firmware>; - status = "disabled"; - }; - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index f6ac7da..06a96d16 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -25,7 +25,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -34,6 +33,7 @@ - #include - #include - #include -+#include - - //#define BCM2708_FB_DEBUG - #define MODULE_NAME "bcm2708_fb" -@@ -58,15 +58,19 @@ static u32 dma_busy_wait_threshold = 1<<15; - module_param(dma_busy_wait_threshold, int, 0644); - MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); - --/* this data structure describes each frame buffer device we find */ -- --struct fbinfo_s { -- u32 xres, yres, xres_virtual, yres_virtual; -- u32 pitch, bpp; -+struct fb_alloc_tags { -+ struct rpi_firmware_property_tag_header tag1; -+ u32 xres, yres; -+ struct rpi_firmware_property_tag_header tag2; -+ u32 xres_virtual, yres_virtual; -+ struct rpi_firmware_property_tag_header tag3; -+ u32 bpp; -+ struct rpi_firmware_property_tag_header tag4; - u32 xoffset, yoffset; -- u32 base; -- u32 screen_size; -- u16 cmap[256]; -+ struct rpi_firmware_property_tag_header tag5; -+ u32 base, screen_size; -+ struct rpi_firmware_property_tag_header tag6; -+ u32 pitch; - }; - - struct bcm2708_fb_stats { -@@ -78,9 +82,9 @@ struct bcm2708_fb_stats { - struct bcm2708_fb { - struct fb_info fb; - struct platform_device *dev; -- struct fbinfo_s *info; -- dma_addr_t dma; -+ struct rpi_firmware *fw; - u32 cmap[16]; -+ u32 gpu_cmap[256]; - int dma_chan; - int dma_irq; - void __iomem *dma_chan_base; -@@ -270,69 +274,71 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, - - static int bcm2708_fb_set_par(struct fb_info *info) - { -- uint32_t val = 0; - struct bcm2708_fb *fb = to_bcm2708(info); -- volatile struct fbinfo_s *fbinfo = fb->info; -- fbinfo->xres = info->var.xres; -- fbinfo->yres = info->var.yres; -- fbinfo->xres_virtual = info->var.xres_virtual; -- fbinfo->yres_virtual = info->var.yres_virtual; -- fbinfo->bpp = info->var.bits_per_pixel; -- fbinfo->xoffset = info->var.xoffset; -- fbinfo->yoffset = info->var.yoffset; -- fbinfo->base = 0; /* filled in by VC */ -- fbinfo->pitch = 0; /* filled in by VC */ -+ struct fb_alloc_tags fbinfo = { -+ .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ .xres = info->var.xres, -+ .yres = info->var.yres, -+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ .xres_virtual = info->var.xres_virtual, -+ .yres_virtual = info->var.yres_virtual, -+ .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, -+ .bpp = info->var.bits_per_pixel, -+ .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, -+ .xoffset = info->var.xoffset, -+ .yoffset = info->var.yoffset, -+ .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -+ .base = 0, -+ .screen_size = 0, -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, -+ .pitch = 0, -+ }; -+ int ret; - - print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, - info->var.xres, info->var.yres, info->var.xres_virtual, - info->var.yres_virtual, (int)info->screen_size, - info->var.bits_per_pixel); - -- /* ensure last write to fbinfo is visible to GPU */ -- wmb(); -- -- /* inform vc about new framebuffer */ -- bcm_mailbox_write(MBOX_CHAN_FB, fb->dma); -- -- /* TODO: replace fb driver with vchiq version */ -- /* wait for response */ -- bcm_mailbox_read(MBOX_CHAN_FB, &val); -- -- /* ensure GPU writes are visible to us */ -- rmb(); -- -- if (val == 0) { -- fb->fb.fix.line_length = fbinfo->pitch; -- -- if (info->var.bits_per_pixel <= 8) -- fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; -- else -- fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; -- -- fb->fb_bus_address = fbinfo->base; -- fbinfo->base &= ~0xc0000000; -- fb->fb.fix.smem_start = fbinfo->base; -- fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; -- fb->fb.screen_size = fbinfo->screen_size; -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- fb->fb.screen_base = -- (void *)ioremap_wc(fbinfo->base, fb->fb.screen_size); -- if (!fb->fb.screen_base) { -- /* the console may currently be locked */ -- console_trylock(); -- console_unlock(); -- pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); -- return -EIO; -- } -+ ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); -+ if (ret) { -+ dev_err(info->device, -+ "Failed to allocate GPU framebuffer (%d)\n", ret); -+ return ret; - } -+ -+ if (info->var.bits_per_pixel <= 8) -+ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ else -+ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; -+ -+ fb->fb.fix.line_length = fbinfo.pitch; -+ fbinfo.base |= 0x40000000; -+ fb->fb_bus_address = fbinfo.base; -+ fbinfo.base &= ~0xc0000000; -+ fb->fb.fix.smem_start = fbinfo.base; -+ fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; -+ fb->fb.screen_size = fbinfo.screen_size; -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); -+ if (!fb->fb.screen_base) { -+ /* the console may currently be locked */ -+ console_trylock(); -+ console_unlock(); -+ dev_err(info->device, "Failed to set screen_base\n"); -+ return -ENOMEM; -+ } -+ - print_debug -- ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", -+ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", - (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, -- fbinfo->xres, fbinfo->yres, fbinfo->bpp, -- fbinfo->pitch, (int)fb->fb.screen_size, val); -+ fbinfo.xres, fbinfo.yres, fbinfo.bpp, -+ fbinfo.pitch, (int)fb->fb.screen_size); - -- return val; -+ return 0; - } - - static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) -@@ -352,15 +358,34 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, - /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ - if (fb->fb.var.bits_per_pixel <= 8) { - if (regno < 256) { -- /* blue [0:4], green [5:10], red [11:15] */ -- fb->info->cmap[regno] = ((red >> (16-5)) & 0x1f) << 11 | -- ((green >> (16-6)) & 0x3f) << 5 | -- ((blue >> (16-5)) & 0x1f) << 0; -+ /* blue [23:16], green [15:8], red [7:0] */ -+ fb->gpu_cmap[regno] = ((red >> 8) & 0xff) << 0 | -+ ((green >> 8) & 0xff) << 8 | -+ ((blue >> 8) & 0xff) << 16; - } - /* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */ - /* So just call it for what looks like the last colour in a list for now. */ -- if (regno == 15 || regno == 255) -- bcm2708_fb_set_par(info); -+ if (regno == 15 || regno == 255) { -+ struct packet { -+ u32 offset; -+ u32 length; -+ u32 cmap[256]; -+ } *packet; -+ int ret; -+ -+ packet = kmalloc(sizeof(*packet), GFP_KERNEL); -+ if (!packet) -+ return -ENOMEM; -+ packet->offset = 0; -+ packet->length = regno + 1; -+ memcpy(packet->cmap, fb->gpu_cmap, sizeof(packet->cmap)); -+ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, -+ packet, (2 + packet->length) * sizeof(u32)); -+ if (ret || packet->offset) -+ dev_err(info->device, "Failed to set palette (%d,%u)\n", -+ ret, packet->offset); -+ kfree(packet); -+ } - } else if (regno < 16) { - fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | - convert_bitfield(blue, &fb->fb.var.blue) | -@@ -372,27 +397,31 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, - - static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) - { -- s32 result = -1; -- u32 p[7]; -- if ( (blank_mode == FB_BLANK_NORMAL) || -- (blank_mode == FB_BLANK_UNBLANK)) { -- -- p[0] = 28; // size = sizeof u32 * length of p -- p[1] = VCMSG_PROCESS_REQUEST; // process request -- p[2] = VCMSG_SET_BLANK_SCREEN; // (the tag id) -- p[3] = 4; // (size of the response buffer) -- p[4] = 4; // (size of the request data) -- p[5] = blank_mode; -- p[6] = VCMSG_PROPERTY_END; // end tag -- -- bcm_mailbox_property(&p, p[0]); -- -- if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -- result = 0; -- else -- pr_err("bcm2708_fb_blank(%d) returns=%d p[1]=0x%x\n", blank_mode, p[5], p[1]); -+ struct bcm2708_fb *fb = to_bcm2708(info); -+ u32 value; -+ int ret; -+ -+ switch (blank_mode) { -+ case FB_BLANK_UNBLANK: -+ value = 0; -+ break; -+ case FB_BLANK_NORMAL: -+ case FB_BLANK_VSYNC_SUSPEND: -+ case FB_BLANK_HSYNC_SUSPEND: -+ case FB_BLANK_POWERDOWN: -+ value = 1; -+ break; -+ default: -+ return -EINVAL; - } -- return result; -+ -+ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, -+ &value, sizeof(value)); -+ if (ret) -+ dev_err(info->device, "bcm2708_fb_blank(%d) failed: %d\n", -+ blank_mode, ret); -+ -+ return ret; - } - - static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) -@@ -408,25 +437,25 @@ static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info - - static int bcm2708_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) - { -- s32 result = -1; -- u32 p[7]; -- if (cmd == FBIO_WAITFORVSYNC) { -- p[0] = 28; // size = sizeof u32 * length of p -- p[1] = VCMSG_PROCESS_REQUEST; // process request -- p[2] = VCMSG_SET_VSYNC; // (the tag id) -- p[3] = 4; // (size of the response buffer) -- p[4] = 4; // (size of the request data) -- p[5] = 0; // dummy -- p[6] = VCMSG_PROPERTY_END; // end tag -- -- bcm_mailbox_property(&p, p[0]); -- -- if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -- result = 0; -- else -- pr_err("bcm2708_fb_ioctl %x,%lx returns=%d p[1]=0x%x\n", cmd, arg, p[5], p[1]); -+ struct bcm2708_fb *fb = to_bcm2708(info); -+ u32 dummy = 0; -+ int ret; -+ -+ switch (cmd) { -+ case FBIO_WAITFORVSYNC: -+ ret = rpi_firmware_property(fb->fw, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC, -+ &dummy, sizeof(dummy)); -+ break; -+ default: -+ dev_err(info->device, "Unknown ioctl 0x%x\n", cmd); -+ return -EINVAL; - } -- return result; -+ -+ if (ret) -+ dev_err(info->device, "ioctl 0x%x failed (%d)\n", cmd, ret); -+ -+ return ret; - } - static void bcm2708_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -@@ -621,20 +650,7 @@ static struct fb_ops bcm2708_fb_ops = { - static int bcm2708_fb_register(struct bcm2708_fb *fb) - { - int ret; -- dma_addr_t dma; -- void *mem; -- -- mem = -- dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, -- GFP_KERNEL); - -- if (NULL == mem) { -- pr_err(": unable to allocate fbinfo buffer\n"); -- ret = -ENOMEM; -- } else { -- fb->info = (struct fbinfo_s *)mem; -- fb->dma = dma; -- } - fb->fb.fbops = &bcm2708_fb_ops; - fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA; - fb->fb.pseudo_palette = fb->cmap; -@@ -693,9 +709,22 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - - static int bcm2708_fb_probe(struct platform_device *dev) - { -+ struct device_node *fw_np; -+ struct rpi_firmware *fw; - struct bcm2708_fb *fb; - int ret; - -+ fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0); -+/* Remove comment when booting without Device Tree is no longer supported -+ if (!fw_np) { -+ dev_err(&dev->dev, "Missing firmware node\n"); -+ return -ENOENT; -+ } -+*/ -+ fw = rpi_firmware_get(fw_np); -+ if (!fw) -+ return -EPROBE_DEFER; -+ - fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); - if (!fb) { - dev_err(&dev->dev, -@@ -704,6 +733,7 @@ static int bcm2708_fb_probe(struct platform_device *dev) - goto free_region; - } - -+ fb->fw = fw; - bcm2708_fb_debugfs_init(fb); - - fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, -@@ -737,6 +767,7 @@ static int bcm2708_fb_probe(struct platform_device *dev) - fb->dma_chan, fb->dma_chan_base); - - fb->dev = dev; -+ fb->fb.device = &dev->dev; - - ret = bcm2708_fb_register(fb); - if (ret == 0) { -@@ -769,8 +800,6 @@ static int bcm2708_fb_remove(struct platform_device *dev) - dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); - bcm_dma_chan_free(fb->dma_chan); - -- dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, -- fb->dma); - bcm2708_fb_debugfs_deinit(fb); - - free_irq(fb->dma_irq, fb); - -From e24a0ff68aeded060486f55911653aec60ea87c7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:27:17 +0200 -Subject: [PATCH 138/204] bcm2835: Add firmware property to affected devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Also move firmware depending devices to the rpi dtsi file since -they depend on the Pi specific firmware. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 22 ++++++++++++++++++---- - arch/arm/boot/dts/bcm2835.dtsi | 15 --------------- - 2 files changed, 18 insertions(+), 19 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index 5cdfd5a..6c3daaf 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -32,6 +32,24 @@ - compatible = "raspberrypi,bcm2835-firmware"; - mboxes = <&mailbox>; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ firmware = <&firmware>; -+ }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ firmware = <&firmware>; -+ }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ cache-line-size = <32>; -+ firmware = <&firmware>; -+ }; - }; - - /* Onboard audio */ -@@ -101,10 +119,6 @@ - bus-width = <4>; - }; - --&fb { -- status = "okay"; --}; -- - / { - __overrides__ { - i2s = <&i2s>,"status"; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 1135120..807264d 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -160,21 +160,6 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -- -- fb: fb { -- compatible = "brcm,bcm2708-fb"; -- status = "disabled"; -- }; -- -- vchiq: vchiq { -- compatible = "brcm,bcm2835-vchiq"; -- reg = <0x7e00b840 0xf>; -- interrupts = <0 2>; -- }; -- -- thermal: thermal { -- compatible = "brcm,bcm2835-thermal"; -- }; - }; - - clocks { - -From 4fa2f3a62adf17ef122476d8fc63b132a717d71f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 21 Jul 2015 19:09:39 +0200 -Subject: [PATCH 139/204] rpi-ft5406: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 1 + - drivers/input/touchscreen/rpi-ft5406.c | 74 ++++++++++------------- - 2 files changed, 32 insertions(+), 43 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -index 40deab5..2e53a17 100644 ---- a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -@@ -9,6 +9,7 @@ - __overlay__ { - rpi_ft5406: rpi_ft5406 { - compatible = "rpi,rpi-ft5406"; -+ firmware = <&firmware>; - status = "okay"; - }; - }; -diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c -index d41851d..c08817e 100644 ---- a/drivers/input/touchscreen/rpi-ft5406.c -+++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -21,7 +21,7 @@ - #include - #include - #include --#include -+#include - - #define MAXIMUM_SUPPORTED_POINTS 10 - struct ft5406_regs { -@@ -49,23 +49,6 @@ struct ft5406 { - struct task_struct * thread; - }; - -- --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the message id */ -- uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -- uint32_t data_size; /* amount of data being sent or received */ -- uint32_t val; /* data buffer */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- - /* Thread to poll for touchscreen events - * - * This thread polls the memory based register copy of the ft5406 registers -@@ -136,11 +119,37 @@ static int ft5406_probe(struct platform_device *pdev) - { - int ret; - struct input_dev * input_dev = input_allocate_device(); -- struct vc_msg request; - struct ft5406 * ts; -+ struct device_node *fw_node; -+ struct rpi_firmware *fw; -+ u32 touchbuf; - - dev_info(&pdev->dev, "Probing device\n"); - -+ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); -+ if (!fw_node) { -+ dev_err(&pdev->dev, "Missing firmware node\n"); -+ return -ENOENT; -+ } -+ -+ fw = rpi_firmware_get(fw_node); -+ if (!fw) -+ return -EPROBE_DEFER; -+ -+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF, -+ &touchbuf, sizeof(touchbuf)); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to get touch buffer\n"); -+ return ret; -+ } -+ -+ if (!touchbuf) { -+ dev_err(&pdev->dev, "Touchscreen not detected\n"); -+ return -ENODEV; -+ } -+ -+ dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", touchbuf); -+ - ts = kzalloc(sizeof(struct ft5406), GFP_KERNEL); - - if (!ts || !input_dev) { -@@ -174,36 +183,15 @@ static int ft5406_probe(struct platform_device *pdev) - return ret; - } - -- memset(&request, 0, sizeof request); -- -- request.msg_size = sizeof request; -- request.request_code = VCMSG_PROCESS_REQUEST; -- request.tag.tag_id = VCMSG_GET_TOUCHBUF; -- request.tag.buffer_size = 4; -- request.tag.data_size = 4; -- -- bcm_mailbox_property(&request, sizeof(request)); -- -- if(request.request_code == VCMSG_REQUEST_SUCCESSFUL && request.tag.val != 0) -- { -- dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", request.tag.val); -- } -- else -- { -- input_unregister_device(input_dev); -- kzfree(ts); -- return -1; -- } -- - // mmap the physical memory -- request.tag.val &= ~0xc0000000; -- ts->ts_base = ioremap(request.tag.val, sizeof(*ts->regs)); -+ touchbuf &= ~0xc0000000; -+ ts->ts_base = ioremap(touchbuf, sizeof(*ts->regs)); - if(ts->ts_base == NULL) - { - dev_err(&pdev->dev, "Failed to map physical address\n"); - input_unregister_device(input_dev); - kzfree(ts); -- return -1; -+ return -ENOMEM; - } - - ts->regs = (struct ft5406_regs *) ts->ts_base; - -From 70b5d66ef90adc3ee74708ecf15fd5fd3c6a3f9e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 12 Jun 2015 19:01:05 +0200 -Subject: [PATCH 140/204] irqchip: bcm2835: Add FIQ support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a duplicate irq range with an offset on the hwirq's so the -driver can detect that enable_fiq() is used. -Tested with downstream dwc_otg USB controller driver. - -Signed-off-by: Noralf Trønnes -Reviewed-by: Eric Anholt -Acked-by: Stephen Warren ---- - arch/arm/mach-bcm/Kconfig | 1 + - drivers/irqchip/irq-bcm2835.c | 53 ++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 48 insertions(+), 6 deletions(-) - -diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig -index 8b11f44..7cfef7b 100644 ---- a/arch/arm/mach-bcm/Kconfig -+++ b/arch/arm/mach-bcm/Kconfig -@@ -114,6 +114,7 @@ config ARCH_BCM2835 - select ARM_ERRATA_411920 - select ARM_TIMER_SP804 - select CLKSRC_OF -+ select FIQ - select PINCTRL - select PINCTRL_BCM2835 - help -diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c -index 5916d6c..db66246 100644 ---- a/drivers/irqchip/irq-bcm2835.c -+++ b/drivers/irqchip/irq-bcm2835.c -@@ -56,7 +56,7 @@ - #include "irqchip.h" - - /* Put the bank and irq (32 bits) into the hwirq */ --#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) -+#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) - #define HWIRQ_BANK(i) (i >> 5) - #define HWIRQ_BIT(i) BIT(i & 0x1f) - -@@ -72,9 +72,13 @@ - | SHORTCUT1_MASK | SHORTCUT2_MASK) - - #define REG_FIQ_CONTROL 0x0c -+#define REG_FIQ_ENABLE 0x80 -+#define REG_FIQ_DISABLE 0 - - #define NR_BANKS 3 - #define IRQS_PER_BANK 32 -+#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) -+#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) - - static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; - static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; -@@ -98,14 +102,38 @@ static struct armctrl_ic intc __read_mostly; - static void __exception_irq_entry bcm2835_handle_irq( - struct pt_regs *regs); - -+static inline unsigned int hwirq_to_fiq(unsigned long hwirq) -+{ -+ hwirq -= NUMBER_IRQS; -+ /* -+ * The hwirq numbering used in this driver is: -+ * BASE (0-7) GPU1 (32-63) GPU2 (64-95). -+ * This differ from the one used in the FIQ register: -+ * GPU1 (0-31) GPU2 (32-63) BASE (64-71) -+ */ -+ if (hwirq >= 32) -+ return hwirq - 32; -+ -+ return hwirq + 64; -+} -+ - static void armctrl_mask_irq(struct irq_data *d) - { -- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); -+ if (d->hwirq >= NUMBER_IRQS) -+ writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); -+ else -+ writel_relaxed(HWIRQ_BIT(d->hwirq), -+ intc.disable[HWIRQ_BANK(d->hwirq)]); - } - - static void armctrl_unmask_irq(struct irq_data *d) - { -- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); -+ if (d->hwirq >= NUMBER_IRQS) -+ writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), -+ intc.base + REG_FIQ_CONTROL); -+ else -+ writel_relaxed(HWIRQ_BIT(d->hwirq), -+ intc.enable[HWIRQ_BANK(d->hwirq)]); - } - - static struct irq_chip armctrl_chip = { -@@ -150,8 +178,9 @@ static int __init armctrl_of_init(struct device_node *node, - panic("%s: unable to map IC registers\n", - node->full_name); - -- intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), -- &armctrl_ops, NULL); -+ intc.base = base; -+ intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2, -+ &armctrl_ops, NULL); - if (!intc.domain) - panic("%s: unable to create IRQ domain\n", node->full_name); - -@@ -168,8 +197,20 @@ static int __init armctrl_of_init(struct device_node *node, - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - } -- - set_handle_irq(bcm2835_handle_irq); -+ -+ /* Make a duplicate irq range which is used to enable FIQ */ -+ for (b = 0; b < NR_BANKS; b++) { -+ for (i = 0; i < bank_irqs[b]; i++) { -+ irq = irq_create_mapping(intc.domain, -+ MAKE_HWIRQ(b, i) + NUMBER_IRQS); -+ BUG_ON(irq <= 0); -+ irq_set_chip(irq, &armctrl_chip); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -+ } -+ } -+ init_FIQ(FIQ_START); -+ - return 0; - } - - -From 48ff5ec47ad9778a6d2eb5d75ee2e161302673fa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 15:50:04 +0200 -Subject: [PATCH 141/204] dwc_otg: Add ARCH_BCM2835 support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1 + - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 1 - - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 4 ++++ - 3 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -index 53307f0..95edadf 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -723,6 +723,7 @@ static int dwc_otg_driver_probe( - - memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); - dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF; -+ dwc_otg_device->os_dep.platformdev = _dev; - - /* - * Map the DWC_otg Core memory into virtual address space. -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index 8a31562..3f71f29 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -36,7 +36,6 @@ - #include "dwc_otg_regs.h" - - #include --#include - #include - - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -index 0f4ebcd..5c83309 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -445,7 +445,11 @@ static void hcd_init_fiq(void *cookie) - DWC_WARN("MPHI periph has NOT been enabled"); - #endif - // Enable FIQ interrupt from USB peripheral -+#ifdef CONFIG_ARCH_BCM2835 -+ enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1)); -+#else - enable_fiq(INTERRUPT_VC_USB); -+#endif - local_fiq_enable(); - } - - -From 28a1fd2b8afaf5524cca8890394f9fc07c8a8b71 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 15:50:24 +0200 -Subject: [PATCH 142/204] bcm2835: Use DWC_OTG -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 8 +++++--- - arch/arm/configs/bcm2835_defconfig | 1 + - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 807264d..8a5d6ec 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -152,9 +152,11 @@ - }; - - usb: usb@7e980000 { -- compatible = "brcm,bcm2835-usb"; -- reg = <0x7e980000 0x10000>; -- interrupts = <1 9>; -+ compatible = "brcm,bcm2708-usb"; -+ reg = <0x7e980000 0x10000>, -+ <0x7e006000 0x1000>; -+ interrupts = <2 0>, -+ <1 9>; - }; - - arm-pmu { -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index c284414..14ef294 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -869,6 +869,7 @@ CONFIG_USB_HIDDEV=y - CONFIG_USB=y - CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_MON=m -+CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m - CONFIG_USB_STORAGE=y - CONFIG_USB_STORAGE_REALTEK=m - -From cf7a056866fba1d602de661a47cd0548dfe2304b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:33:16 +0200 -Subject: [PATCH 143/204] Fix RASPBERRYPI_FIRMWARE dependents -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If forgot this when converting the drivers. - -Signed-off-by: Noralf Trønnes ---- - drivers/cpufreq/Kconfig.arm | 2 +- - drivers/input/touchscreen/Kconfig | 2 +- - drivers/misc/vc04_services/Kconfig | 2 +- - drivers/thermal/Kconfig | 2 +- - drivers/video/fbdev/Kconfig | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index a1039f0..0037516 100644 ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -259,7 +259,7 @@ config ARM_SPEAR_CPUFREQ - This adds the CPUFreq driver support for SPEAr SOCs. - - config ARM_BCM2835_CPUFREQ -- depends on BCM2708_MBOX -+ depends on RASPBERRYPI_FIRMWARE - bool "BCM2835 Driver" - default y - help -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 5848562..d7e74a1 100644 ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -585,7 +585,7 @@ config TOUCHSCREEN_EDT_FT5X06 - - config TOUCHSCREEN_RPI_FT5406 - tristate "Raspberry Pi FT5406 driver" -- depends on ARCH_BCM2708 || ARCH_BCM2709 -+ depends on RASPBERRYPI_FIRMWARE - help - Say Y here to enable the Raspberry Pi memory based FT5406 device - -diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig -index c5ba283..db8e1be 100644 ---- a/drivers/misc/vc04_services/Kconfig -+++ b/drivers/misc/vc04_services/Kconfig -@@ -1,6 +1,6 @@ - config BCM2708_VCHIQ - tristate "Videocore VCHIQ" -- depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX -+ depends on RASPBERRYPI_FIRMWARE - default y - help - Kernel to VideoCore communication interface for the -diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index ddc77ad..b911213 100644 ---- a/drivers/thermal/Kconfig -+++ b/drivers/thermal/Kconfig -@@ -239,7 +239,7 @@ config INTEL_POWERCLAMP - user interface is exposed via generic thermal framework. - - config THERMAL_BCM2835 -- depends on BCM2708_MBOX -+ depends on RASPBERRYPI_FIRMWARE - tristate "BCM2835 Thermal Driver" - help - This will enable temperature monitoring for the Broadcom BCM2835 -diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index b89998b7..08678b9 100644 ---- a/drivers/video/fbdev/Kconfig -+++ b/drivers/video/fbdev/Kconfig -@@ -226,7 +226,7 @@ comment "Frame buffer hardware drivers" - - config FB_BCM2708 - tristate "BCM2708 framebuffer support" -- depends on FB && ARM && BCM2708_MBOX -+ depends on FB && RASPBERRYPI_FIRMWARE - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - -From 16b9943dbfbc7d7f19f44e91808dc1450ca9d4b4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:33:46 +0200 -Subject: [PATCH 144/204] vc_mem: Remove unnecessary include -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - drivers/char/broadcom/vc_mem.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c -index fcde6b1..be64f23 100644 ---- a/drivers/char/broadcom/vc_mem.c -+++ b/drivers/char/broadcom/vc_mem.c -@@ -22,7 +22,6 @@ - #include - #include - #include --#include - #include - - #define DRIVER_NAME "vc-mem" - -From d98428b8e2a5bb9815aaa3eed3e0777f50f55196 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:34:06 +0200 -Subject: [PATCH 145/204] configs: Remove BCM2708_MBOX -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 1 - - arch/arm/configs/bcm2835_defconfig | 1 - - arch/arm/configs/bcmrpi_defconfig | 1 - - 3 files changed, 3 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index dd00e7c..e3155da 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1078,7 +1078,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y --CONFIG_BCM2708_MBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 14ef294..24d4df6 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -1065,7 +1065,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y --CONFIG_BCM2708_MBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 7b24274..0859113 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1071,7 +1071,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y --CONFIG_BCM2708_MBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - -From b3b0ebfd9dd4bcd6fe8d787aa7740a47f419da9f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:34:31 +0200 -Subject: [PATCH 146/204] bcm2708-vcio: Remove module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -All drivers have been converted to the new firmware API, so this -module is not needed anymore. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 6 -- - drivers/mailbox/Makefile | 2 - - drivers/mailbox/bcm2708-vcio.c | 86 ----------------- - include/linux/platform_data/mailbox-bcm2708.h | 127 -------------------------- - 4 files changed, 221 deletions(-) - delete mode 100644 drivers/mailbox/bcm2708-vcio.c - delete mode 100644 include/linux/platform_data/mailbox-bcm2708.h - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index d1a6671..3965e10 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -7,12 +7,6 @@ menuconfig MAILBOX - - if MAILBOX - --config BCM2708_MBOX -- bool "Broadcom BCM2708 Mailbox (vcio)" -- depends on BCM2835_MBOX -- help -- Broadcom BCM2708 Mailbox (vcio) -- - config ARM_MHU - tristate "ARM MHU Mailbox" - depends on ARM_AMBA -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index c86bc91..8e6d822 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -2,8 +2,6 @@ - - obj-$(CONFIG_MAILBOX) += mailbox.o - --obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o -- - obj-$(CONFIG_ARM_MHU) += arm_mhu.o - - obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -deleted file mode 100644 -index 2e4031b..0000000 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ /dev/null -@@ -1,86 +0,0 @@ --/* -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for writing to the mailboxes, -- * semaphores, doorbells etc. that are shared between the ARM and the -- * VideoCore processor -- */ -- --#include --#include --#include --#include --#include --#include -- --#define DRIVER_NAME "bcm2708_vcio" -- --extern int bcm_mailbox_write(unsigned chan, uint32_t data28) --{ -- struct rpi_firmware *fw = rpi_firmware_get(NULL); -- -- if (!fw) -- return -ENODEV; -- -- return rpi_firmware_transaction(fw, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_write); -- --extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) --{ -- struct rpi_firmware *fw = rpi_firmware_get(NULL); -- -- if (!fw) -- return -ENODEV; -- -- *data28 = rpi_firmware_transaction_received(fw); -- -- return 0; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -- --static DEFINE_MUTEX(mailbox_lock); --extern int bcm_mailbox_property(void *data, int size) --{ -- uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -- int s = 0; -- -- mutex_lock(&mailbox_lock); -- /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -- GFP_KERNEL); -- if (mem_kern) { -- /* create the message */ -- memcpy(mem_kern, data, size); -- -- /* send the message */ -- wmb(); -- s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) -- s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- if (s == 0) { -- /* copy the response */ -- rmb(); -- memcpy(data, mem_kern, size); -- } -- dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -- } else { -- s = -ENOMEM; -- } -- if (s != 0) -- pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -- -- mutex_unlock(&mailbox_lock); -- return s; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_property); -- --MODULE_AUTHOR("Gray Girling"); --MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); --MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -deleted file mode 100644 -index d3ea839..0000000 ---- a/include/linux/platform_data/mailbox-bcm2708.h -+++ /dev/null -@@ -1,127 +0,0 @@ --/* -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- */ --#ifndef _PLAT_MAILBOX_BCM2708_H --#define _PLAT_MAILBOX_BCM2708_H -- --/* Routines to handle I/O via the VideoCore "ARM control" registers -- * (semaphores, doorbells, mailboxes) -- */ -- --/* Constants shared with the ARM identifying separate mailbox channels */ --#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ --#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ --#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ --#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ --#define MBOX_CHAN_COUNT 9 -- --enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 --}; -- --enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 --}; -- --/* Mailbox property tags */ --enum { -- VCMSG_PROPERTY_END = 0x00000000, -- VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -- VCMSG_GET_BOARD_MODEL = 0x00010001, -- VCMSG_GET_BOARD_REVISION = 0x00010002, -- VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -- VCMSG_GET_BOARD_SERIAL = 0x00010004, -- VCMSG_GET_ARM_MEMORY = 0x00010005, -- VCMSG_GET_VC_MEMORY = 0x00010006, -- VCMSG_GET_CLOCKS = 0x00010007, -- VCMSG_GET_COMMAND_LINE = 0x00050001, -- VCMSG_GET_DMA_CHANNELS = 0x00060001, -- VCMSG_GET_POWER_STATE = 0x00020001, -- VCMSG_GET_TIMING = 0x00020002, -- VCMSG_SET_POWER_STATE = 0x00028001, -- VCMSG_GET_CLOCK_STATE = 0x00030001, -- VCMSG_SET_CLOCK_STATE = 0x00038001, -- VCMSG_GET_CLOCK_RATE = 0x00030002, -- VCMSG_SET_CLOCK_RATE = 0x00038002, -- VCMSG_GET_VOLTAGE = 0x00030003, -- VCMSG_SET_VOLTAGE = 0x00038003, -- VCMSG_GET_MAX_CLOCK = 0x00030004, -- VCMSG_GET_MAX_VOLTAGE = 0x00030005, -- VCMSG_GET_TEMPERATURE = 0x00030006, -- VCMSG_GET_MIN_CLOCK = 0x00030007, -- VCMSG_GET_MIN_VOLTAGE = 0x00030008, -- VCMSG_GET_TURBO = 0x00030009, -- VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -- VCMSG_GET_STC = 0x0003000b, -- VCMSG_SET_TURBO = 0x00038009, -- VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -- VCMSG_SET_LOCK_MEM = 0x0003000d, -- VCMSG_SET_UNLOCK_MEM = 0x0003000e, -- VCMSG_SET_RELEASE_MEM = 0x0003000f, -- VCMSG_SET_EXECUTE_CODE = 0x00030010, -- VCMSG_SET_EXECUTE_QPU = 0x00030011, -- VCMSG_SET_ENABLE_QPU = 0x00030012, -- VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -- VCMSG_GET_EDID_BLOCK = 0x00030020, -- VCMSG_GET_CUSTOMER_OTP = 0x00030021, -- VCMSG_SET_CUSTOMER_OTP = 0x00038021, -- VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -- VCMSG_SET_RELEASE_BUFFER = 0x00048001, -- VCMSG_SET_BLANK_SCREEN = 0x00040002, -- VCMSG_TST_BLANK_SCREEN = 0x00044002, -- VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -- VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -- VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -- VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -- VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -- VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -- VCMSG_GET_DEPTH = 0x00040005, -- VCMSG_TST_DEPTH = 0x00044005, -- VCMSG_SET_DEPTH = 0x00048005, -- VCMSG_GET_PIXEL_ORDER = 0x00040006, -- VCMSG_TST_PIXEL_ORDER = 0x00044006, -- VCMSG_SET_PIXEL_ORDER = 0x00048006, -- VCMSG_GET_ALPHA_MODE = 0x00040007, -- VCMSG_TST_ALPHA_MODE = 0x00044007, -- VCMSG_SET_ALPHA_MODE = 0x00048007, -- VCMSG_GET_PITCH = 0x00040008, -- VCMSG_TST_PITCH = 0x00044008, -- VCMSG_SET_PITCH = 0x00048008, -- VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -- VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -- VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -- VCMSG_GET_OVERSCAN = 0x0004000a, -- VCMSG_TST_OVERSCAN = 0x0004400a, -- VCMSG_SET_OVERSCAN = 0x0004800a, -- VCMSG_GET_PALETTE = 0x0004000b, -- VCMSG_TST_PALETTE = 0x0004400b, -- VCMSG_SET_PALETTE = 0x0004800b, -- VCMSG_GET_LAYER = 0x0004000c, -- VCMSG_TST_LAYER = 0x0004400c, -- VCMSG_SET_LAYER = 0x0004800c, -- VCMSG_GET_TRANSFORM = 0x0004000d, -- VCMSG_TST_TRANSFORM = 0x0004400d, -- VCMSG_SET_TRANSFORM = 0x0004800d, -- VCMSG_TST_VSYNC = 0x0004400e, -- VCMSG_SET_VSYNC = 0x0004800e, -- VCMSG_GET_TOUCHBUF = 0x0004000f, -- VCMSG_SET_CURSOR_INFO = 0x00008010, -- VCMSG_SET_CURSOR_STATE = 0x00008011, --}; -- --int bcm_mailbox_read(unsigned chan, uint32_t *data28); --int bcm_mailbox_write(unsigned chan, uint32_t data28); --int bcm_mailbox_property(void *data, int size); -- --#endif - -From 6fadac31b6bf0690059342642ff4453d6d95a2d8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:34:55 +0200 -Subject: [PATCH 147/204] Revert "firmware: bcm2835: Support legacy mailbox - API" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 40aa3c4f0c430cd5c574498f4d1d5e9f0bc1cf11. - -The legacy mailbox API has been removed so this is not needed. - -Signed-off-by: Noralf Trønnes ---- - drivers/firmware/raspberrypi.c | 15 ++------------- - include/soc/bcm2835/raspberrypi-firmware.h | 2 -- - 2 files changed, 2 insertions(+), 15 deletions(-) - -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -index 89421a9..b980d53 100644 ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -19,7 +19,6 @@ - #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) - #define MBOX_CHAN(msg) ((msg) & 0xf) - #define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_CHAN_VCHIQ 3 - #define MBOX_CHAN_PROPERTY 8 - - struct rpi_firmware { -@@ -27,7 +26,6 @@ struct rpi_firmware { - struct mbox_chan *chan; /* The property channel. */ - struct completion c; - u32 enabled; -- u32 received; - }; - - static struct platform_device *g_pdev; -@@ -37,7 +35,6 @@ static DEFINE_MUTEX(transaction_lock); - static void response_callback(struct mbox_client *cl, void *msg) - { - struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); -- fw->received = *(u32 *)msg; - complete(&fw->c); - } - -@@ -45,7 +42,7 @@ static void response_callback(struct mbox_client *cl, void *msg) - * Sends a request to the firmware through the BCM2835 mailbox driver, - * and synchronously waits for the reply. - */ --int -+static int - rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - { - u32 message = MBOX_MSG(chan, data); -@@ -57,8 +54,7 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - reinit_completion(&fw->c); - ret = mbox_send_message(fw->chan, &message); - if (ret >= 0) { -- if (chan != MBOX_CHAN_VCHIQ) -- wait_for_completion(&fw->c); -+ wait_for_completion(&fw->c); - ret = 0; - } else { - dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); -@@ -67,13 +63,6 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - - return ret; - } --EXPORT_SYMBOL(rpi_firmware_transaction); -- --u32 rpi_firmware_transaction_received(struct rpi_firmware *fw) --{ -- return MBOX_DATA28(fw->received); --} --EXPORT_SYMBOL(rpi_firmware_transaction_received); - - /** - * rpi_firmware_property_list - Submit firmware property list -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index 9a08cf1..d3933af 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -116,8 +116,6 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - }; - --int rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data); --u32 rpi_firmware_transaction_received(struct rpi_firmware *fw); - int rpi_firmware_property(struct rpi_firmware *fw, - u32 tag, void *data, size_t len); - int rpi_firmware_property_list(struct rpi_firmware *fw, - -From 9418fab5167ef4095a62ba3b11d9e420595cf559 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 30 Jun 2015 12:35:39 +0100 -Subject: [PATCH 148/204] pinctrl: bcm2835: Clear the event latch register when - disabling interrupts - -It's possible to hit a race condition if interrupts are generated on a GPIO -pin when the IRQ line in question is being disabled. - -If the interrupt is freed, bcm2835_gpio_irq_disable() is called which -disables the event generation sources (edge, level). If an event occurred -between the last disabling of hard IRQs and the write to the event -source registers, a bit would be set in the GPIO event detect register -(GPEDSn) which goes unacknowledged by bcm2835_gpio_irq_handler() -so Linux complains loudly. - -There is no per-GPIO mask register, so when disabling GPIO interrupts -write 1 to the relevant bit in GPEDSn to clear out any stale events. - -Signed-off-by: Jonathan Bell -Acked-by: Stephen Warren -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 986779a..61ef002 100644 ---- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -@@ -503,6 +503,8 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data) - - spin_lock_irqsave(&pc->irq_lock[bank], flags); - bcm2835_gpio_irq_config(pc, gpio, false); -+ /* Clear events that were latched prior to clearing event sources */ -+ bcm2835_gpio_set_bit(pc, GPEDS0, gpio); - clear_bit(offset, &pc->enabled_irq_map[bank]); - spin_unlock_irqrestore(&pc->irq_lock[bank], flags); - } - -From 1a099cd189c09d3dc5d2e0ed2061cb9b0dcd2a0b Mon Sep 17 00:00:00 2001 -From: P33M -Date: Tue, 4 Aug 2015 01:15:20 +0100 -Subject: [PATCH 149/204] dwc_otg: fiq_fsm: Make high-speed isochronous strided - transfers work properly - -Certain low-bandwidth high-speed USB devices (specialist audio devices, -compressed-frame webcams) have packet intervals > 1 microframe. - -Stride these transfers in the FIQ by using the start-of-frame interrupt -to restart the channel at the right time. ---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 17 +++++++++++++---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 5 ++++- - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 7 ++++++- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 6 ++++-- - 4 files changed, 27 insertions(+), 8 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -index 7e0c726..85d82f3 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -615,8 +615,11 @@ static int notrace noinline fiq_fsm_do_sof(struct fiq_state *state, int num_chan - break; - - case FIQ_HS_ISOC_SLEEPING: -- state->channel[n].fsm = FIQ_HS_ISOC_TURBO; -- fiq_fsm_restart_channel(state, n, 0); -+ /* Is it time to wake this channel yet? */ -+ if (--state->channel[n].uframe_sleeps == 0) { -+ state->channel[n].fsm = FIQ_HS_ISOC_TURBO; -+ fiq_fsm_restart_channel(state, n, 0); -+ } - break; - - case FIQ_PER_SSPLIT_QUEUED: -@@ -624,7 +627,7 @@ static int notrace noinline fiq_fsm_do_sof(struct fiq_state *state, int num_chan - break; - if(!fiq_fsm_tt_in_use(state, num_channels, n)) { - if (!fiq_fsm_too_late(state, n)) { -- fiq_print(FIQDBG_INT, st, "SOF GO %01d", n); -+ fiq_print(FIQDBG_INT, state, "SOF GO %01d", n); - fiq_fsm_restart_channel(state, n, 0); - state->channel[n].fsm = FIQ_PER_SSPLIT_STARTED; - } else { -@@ -1069,8 +1072,14 @@ static int notrace noinline fiq_fsm_do_hcintr(struct fiq_state *state, int num_c - if (fiq_fsm_update_hs_isoc(state, n, hcint)) { - /* more transactions to come */ - handled = 1; -- restart = 1; - fiq_print(FIQDBG_INT, state, "HSISO M "); -+ /* For strided transfers, put ourselves to sleep */ -+ if (st->hs_isoc_info.stride > 1) { -+ st->uframe_sleeps = st->hs_isoc_info.stride - 1; -+ st->fsm = FIQ_HS_ISOC_SLEEPING; -+ } else { -+ restart = 1; -+ } - } else { - st->fsm = FIQ_HS_ISOC_DONE; - fiq_print(FIQDBG_INT, state, "HSISO F "); -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -index 8455324..f9fddfb 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -260,12 +260,13 @@ struct fiq_dma_blob { - * @iso_frame: Pointer to the array of OTG URB iso_frame_descs. - * @nrframes: Total length of iso_frame_desc array - * @index: Current index (FIQ-maintained) -- * -+ * @stride: Interval in uframes between HS isoc transactions - */ - struct fiq_hs_isoc_info { - struct dwc_otg_hcd_iso_packet_desc *iso_desc; - unsigned int nrframes; - unsigned int index; -+ unsigned int stride; - }; - - /** -@@ -296,6 +297,8 @@ struct fiq_channel_state { - /* Hardware bug workaround: sometimes channel halt interrupts are - * delayed until the next SOF. Keep track of when we expected to get interrupted. */ - unsigned int expected_uframe; -+ /* number of uframes remaining (for interval > 1 HS isoc transfers) before next transfer */ -+ unsigned int uframe_sleeps; - /* in/out for communicating number of dma buffers used, or number of ISOC to do */ - unsigned int nrpackets; - struct fiq_dma_info dma_info; -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -index 4d7c7bb..135b611 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -1678,6 +1678,9 @@ int fiq_fsm_queue_isoc_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) - } - } - -+ st->hs_isoc_info.stride = qh->interval; -+ st->uframe_sleeps = 0; -+ - fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d ", hc->hc_num); - fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hcchar_copy.d32); - fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hctsiz_copy.d32); -@@ -1692,9 +1695,11 @@ int fiq_fsm_queue_isoc_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) - DWC_WRITE_REG32(&hc_regs->hcintmsk, st->hcintmsk_copy.d32); - if (hfnum.b.frrem < PERIODIC_FRREM_BACKOFF) { - /* Prevent queueing near EOF1. Bad things happen if a periodic -- * split transaction is queued very close to EOF. -+ * split transaction is queued very close to EOF. SOF interrupt handler -+ * will wake this channel at the next interrupt. - */ - st->fsm = FIQ_HS_ISOC_SLEEPING; -+ st->uframe_sleeps = 1; - } else { - st->fsm = FIQ_HS_ISOC_TURBO; - st->hcchar_copy.b.chen = 1; -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index 3f71f29..8db3dfc 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -2297,10 +2297,10 @@ void dwc_otg_fiq_unmangle_isoc(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, dwc_otg_qtd - dwc_urb->error_count++; - } - } -+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval * (nr_frames - 1)); -+ - //printk_ratelimited(KERN_INFO "%s: HS isochronous of %d/%d frames with %d errors complete\n", - // __FUNCTION__, i, dwc_urb->packet_count, dwc_urb->error_count); -- hcd->fops->complete(hcd, dwc_urb->priv, dwc_urb, 0); -- release_channel(hcd, qh->channel, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); - } - - /** -@@ -2543,6 +2543,8 @@ void dwc_otg_hcd_handle_hc_fsm(dwc_otg_hcd_t *hcd, uint32_t num) - * fail. - */ - dwc_otg_fiq_unmangle_isoc(hcd, qh, qtd, num); -+ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); -+ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); - break; - - case FIQ_PER_SPLIT_LS_ABORTED: - -From 671205b0f0ec871b8fcabbab6d9a2ffb3444378c Mon Sep 17 00:00:00 2001 -From: Uli Middelberg -Date: Wed, 17 Jun 2015 10:36:56 +0200 -Subject: [PATCH 150/204] added basic docker support - ---- - arch/arm/configs/bcm2709_defconfig | 3 +++ - arch/arm/configs/bcmrpi_defconfig | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index e3155da..661f09a 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -17,6 +17,7 @@ CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y - CONFIG_MEMCG=y - CONFIG_BLK_CGROUP=y -@@ -418,6 +419,7 @@ CONFIG_MD_RAID0=m - CONFIG_BLK_DEV_DM=m - CONFIG_DM_CRYPT=m - CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m - CONFIG_DM_MIRROR=m - CONFIG_DM_LOG_USERSPACE=m - CONFIG_DM_RAID=m -@@ -1115,6 +1117,7 @@ CONFIG_QFMT_V2=m - CONFIG_AUTOFS4_FS=y - CONFIG_FUSE_FS=m - CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m - CONFIG_FSCACHE=y - CONFIG_FSCACHE_STATS=y - CONFIG_FSCACHE_HISTOGRAM=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0859113..06e7529 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -16,6 +16,7 @@ CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y - CONFIG_MEMCG=y - CONFIG_BLK_CGROUP=y -@@ -411,6 +412,7 @@ CONFIG_MD_RAID0=m - CONFIG_BLK_DEV_DM=m - CONFIG_DM_CRYPT=m - CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m - CONFIG_DM_MIRROR=m - CONFIG_DM_LOG_USERSPACE=m - CONFIG_DM_RAID=m -@@ -1108,6 +1110,7 @@ CONFIG_QFMT_V2=m - CONFIG_AUTOFS4_FS=y - CONFIG_FUSE_FS=m - CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m - CONFIG_FSCACHE=y - CONFIG_FSCACHE_STATS=y - CONFIG_FSCACHE_HISTOGRAM=y - -From 1621191b72eef418410908e1b789381f2956275e Mon Sep 17 00:00:00 2001 -From: Garrett -Date: Thu, 2 Jul 2015 19:32:04 -0500 -Subject: [PATCH 151/204] bcm2835 camera planar/packed stride length - -Added a field to the mmal_fmt struct used to compute the bytes per line -when using a particular format. This results in the correct stride being -calculated even when the format is planar. - -Signed-off-by: Garrett Wilson ---- - drivers/media/platform/bcm2835/bcm2835-camera.c | 26 +++++++++++++++++++------ - drivers/media/platform/bcm2835/mmal-common.h | 1 + - 2 files changed, 21 insertions(+), 6 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c -index eb4d831..04a1711 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.c -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -88,12 +88,13 @@ static const struct v4l2_fract - /* video formats */ - static struct mmal_fmt formats[] = { - { -- .name = "4:2:0, packed YUV", -+ .name = "4:2:0, planar, YUV", - .fourcc = V4L2_PIX_FMT_YUV420, - .flags = 0, - .mmal = MMAL_ENCODING_I420, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { - .name = "4:2:2, packed, YUYV", -@@ -102,6 +103,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_YUYV, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { - .name = "RGB24 (LE)", -@@ -110,6 +112,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_BGR24, - .depth = 24, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 3, - }, - { - .name = "JPEG", -@@ -118,6 +121,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_JPEG, - .depth = 8, - .mmal_component = MMAL_COMPONENT_IMAGE_ENCODE, -+ .ybbp = 0, - }, - { - .name = "H264", -@@ -126,6 +130,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_H264, - .depth = 8, - .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, -+ .ybbp = 0, - }, - { - .name = "MJPEG", -@@ -134,6 +139,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_MJPEG, - .depth = 8, - .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, -+ .ybbp = 0, - }, - { - .name = "4:2:2, packed, YVYU", -@@ -142,6 +148,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_YVYU, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { - .name = "4:2:2, packed, VYUY", -@@ -150,6 +157,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_VYUY, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { - .name = "4:2:2, packed, UYVY", -@@ -158,14 +166,16 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_UYVY, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { -- .name = "4:2:0, packed, NV12", -+ .name = "4:2:0, planar, NV12", - .fourcc = V4L2_PIX_FMT_NV12, - .flags = 0, - .mmal = MMAL_ENCODING_NV12, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { - .name = "RGB24 (BE)", -@@ -174,22 +184,25 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_RGB24, - .depth = 24, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 3, - }, - { -- .name = "4:2:0, packed YVU", -+ .name = "4:2:0, planar, YVU", - .fourcc = V4L2_PIX_FMT_YVU420, - .flags = 0, - .mmal = MMAL_ENCODING_YV12, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { -- .name = "4:2:0, packed, NV21", -+ .name = "4:2:0, planar, NV21", - .fourcc = V4L2_PIX_FMT_NV21, - .flags = 0, - .mmal = MMAL_ENCODING_NV21, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { - .name = "RGB32 (BE)", -@@ -198,6 +211,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_BGRA, - .depth = 32, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 4, - }, - }; - -@@ -771,7 +785,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, - a->fmt.width = preview_port->es.video.width; - a->fmt.height = preview_port->es.video.height; - a->fmt.pixelformat = V4L2_PIX_FMT_YUV420; -- a->fmt.bytesperline = (preview_port->es.video.width * 3)>>1; -+ a->fmt.bytesperline = preview_port->es.video.width; - a->fmt.sizeimage = (preview_port->es.video.width * - preview_port->es.video.height * 3)>>1; - a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; -@@ -894,7 +908,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - - v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1, - &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0); -- f->fmt.pix.bytesperline = (f->fmt.pix.width * mfmt->depth)>>3; -+ f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; - - /* Image buffer has to be padded to allow for alignment, even though - * we then remove that padding before delivering the buffer. -diff --git a/drivers/media/platform/bcm2835/mmal-common.h b/drivers/media/platform/bcm2835/mmal-common.h -index 35698c8..15788a1 100644 ---- a/drivers/media/platform/bcm2835/mmal-common.h -+++ b/drivers/media/platform/bcm2835/mmal-common.h -@@ -30,6 +30,7 @@ struct mmal_fmt { - u32 mmal; - int depth; - u32 mmal_component; /* MMAL component index to be used to encode */ -+ u32 ybbp; /* depth of first Y plane for planar formats */ - }; - - /* buffer for one video frame */ - -From 86b0488fa249c00bd7c381fe637026a7f33a6ffa Mon Sep 17 00:00:00 2001 +From 1b74d2a8ea6ab1741caa2e2a0d0f477366f640d6 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 17 Aug 2015 10:49:44 +0100 -Subject: [PATCH 154/204] BCM270X_DT: Add pwm and pwm-2chan overlays +Subject: [PATCH 090/113] BCM270X_DT: Add pwm and pwm-2chan overlays From the README entries: Legal pin,function combinations for each channel: @@ -144046,243 +139781,11 @@ From the README entries: See: https://github.com/raspberrypi/linux/issues/756 --- - arch/arm/boot/dts/bcm2708_common.dtsi | 16 +++++++++ - arch/arm/boot/dts/overlays/Makefile | 2 ++ - arch/arm/boot/dts/overlays/README | 41 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 46 ++++++++++++++++++++++++ - arch/arm/boot/dts/overlays/pwm-overlay.dts | 42 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/pwm/Kconfig | 2 +- - 8 files changed, 150 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts + drivers/pwm/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index d1c3bdf..ea3bd9ca 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -154,6 +154,14 @@ - status = "disabled"; - }; - -+ pwm: pwm@7e20c000 { -+ compatible = "brcm,bcm2835-pwm"; -+ reg = <0x7e20c000 0x28>; -+ clocks = <&clk_pwm>; -+ #pwm-cells = <2>; -+ status = "disabled"; -+ }; -+ - uart1: uart@7e215040 { - compatible = "brcm,bcm2835-aux-uart", "ns16550"; - reg = <0x7e215040 0x40>; -@@ -279,6 +287,14 @@ - clock-output-names = "apb_pclk"; - clock-frequency = <126000000>; - }; -+ -+ clk_pwm: clock@5 { -+ compatible = "fixed-clock"; -+ reg = <3>; -+ #clock-cells = <0>; -+ clock-output-names = "pwm"; -+ clock-frequency = <100000000>; -+ }; - }; - - __overrides__ { -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 5f6082f..753554b 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -35,6 +35,8 @@ dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index ed484ae..1cd2140 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -410,6 +410,47 @@ Load: dtoverlay=pps-gpio,= - Params: gpiopin Input GPIO (default "18") - - -+Name: pwm -+Info: Configures a single PWM channel -+ Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+ 4) Currently the clock must have been enabled and configured -+ by other means. -+Load: dtoverlay=pwm-2chan,= -+Load: dtoverlay=pwm,= -+Params: pin Output pin (default 18) - see table -+ func Pin function (default 2 = Alt5) - see above -+ clock PWM clock frequency (informational) -+ -+ -+Name: pwm-2chan -+Info: Configures both PWM channels -+ Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+ 4) Currently the clock must have been enabled and configured -+ by other means. -+Load: dtoverlay=pwm-2chan,= -+Params: pin Output pin (default 18) - see table -+ pin2 Output pin for other channel (default 19) -+ func Pin function (default 2 = Alt5) - see above -+ func2 Function for pin2 (default 2 = Alt5) -+ clock PWM clock frequency (informational) -+ -+ - Name: rpi-dac - Info: Configures the RPi DAC audio card - Load: dtoverlay=rpi-dac -diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -new file mode 100644 -index 0000000..957e1a4 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -@@ -0,0 +1,46 @@ -+/dts-v1/; -+/plugin/; -+ -+/* -+This is the 2-channel overlay - only use it if you need both channels. -+ -+Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ -+N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+*/ -+ -+/ { -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <18 19>; -+ brcm,function = <2 2>; /* Alt5 */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pwm>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ pin = <&pwm_pins>,"brcm,pins:0"; -+ pin2 = <&pwm_pins>,"brcm,pins:4"; -+ func = <&pwm_pins>,"brcm,function:0"; -+ func2 = <&pwm_pins>,"brcm,function:4"; -+ clock = <&clk_pwm>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts -new file mode 100644 -index 0000000..ddd67ff ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts -@@ -0,0 +1,42 @@ -+/dts-v1/; -+/plugin/; -+ -+/* -+Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ -+N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+*/ -+ -+/ { -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <18>; -+ brcm,function = <2>; /* Alt5 */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pwm>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ pin = <&pwm_pins>,"brcm,pins:0"; -+ func = <&pwm_pins>,"brcm,function:0"; -+ clock = <&clk_pwm>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index e5af037..d7457fc 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1091,6 +1091,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index a377222..59b2fdd 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1084,6 +1084,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig -index b1541f4..90591a9 100644 +index 062630a..30b0186 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -85,7 +85,7 @@ config PWM_BCM_KONA @@ -144295,1217 +139798,243 @@ index b1541f4..90591a9 100644 PWM framework driver for BCM2835 controller (Raspberry Pi) -From 0d1f86de027a4406151de275663b2cb68d3b39f5 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 22 Apr 2015 07:33:03 +0000 -Subject: [PATCH 155/204] spi: bcm2835: fallback to interrupt for polling - timeouts exceeding 2 jiffies - -The polling mode of the driver is designed for transfers that run -less than 30us - it will only execute under those circumstances. -So it should run comfortably without getting interrupted by the -scheduler. - -But there are situations where the raspberry pi is so overloaded -that it can take up to 80 jiffies until the polling thread gets -rescheduled - this has been observed especially under heavy -IO situations. - -In such a situation we now fall back to the interrupt handler and -log the situation at debug level. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit a750b124cfd27bae1a12df22318db5a2083dfb12) ---- - drivers/spi/spi-bcm2835.c | 87 +++++++++++++++++++++++++++-------------------- - 1 file changed, 50 insertions(+), 37 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index cf3190f..505a993 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -69,7 +69,7 @@ - #define BCM2835_SPI_CS_CS_01 0x00000001 - - #define BCM2835_SPI_POLLING_LIMIT_US 30 --#define BCM2835_SPI_TIMEOUT_MS 30000 -+#define BCM2835_SPI_POLLING_JIFFIES 2 - #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_NO_CS | SPI_3WIRE) - -@@ -157,42 +157,6 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - return IRQ_HANDLED; - } - --static int bcm2835_spi_transfer_one_poll(struct spi_master *master, -- struct spi_device *spi, -- struct spi_transfer *tfr, -- u32 cs, -- unsigned long xfer_time_us) --{ -- struct bcm2835_spi *bs = spi_master_get_devdata(master); -- /* set timeout to 1 second of maximum polling */ -- unsigned long timeout = jiffies + HZ; -- -- /* enable HW block without interrupts */ -- bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); -- -- /* loop until finished the transfer */ -- while (bs->rx_len) { -- /* read from fifo as much as possible */ -- bcm2835_rd_fifo(bs); -- /* fill in tx fifo as much as possible */ -- bcm2835_wr_fifo(bs); -- /* if we still expect some data after the read, -- * check for a possible timeout -- */ -- if (bs->rx_len && time_after(jiffies, timeout)) { -- /* Transfer complete - reset SPI HW */ -- bcm2835_spi_reset_hw(master); -- /* and return timeout */ -- return -ETIMEDOUT; -- } -- } -- -- /* Transfer complete - reset SPI HW */ -- bcm2835_spi_reset_hw(master); -- /* and return without waiting for completion */ -- return 0; --} -- - static int bcm2835_spi_transfer_one_irq(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr, -@@ -229,6 +193,55 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master, - return 1; - } - -+static int bcm2835_spi_transfer_one_poll(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs, -+ unsigned long xfer_time_us) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ unsigned long timeout; -+ -+ /* enable HW block without interrupts */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); -+ -+ /* fill in the fifo before timeout calculations -+ * if we are interrupted here, then the data is -+ * getting transferred by the HW while we are interrupted -+ */ -+ bcm2835_wr_fifo(bs); -+ -+ /* set the timeout */ -+ timeout = jiffies + BCM2835_SPI_POLLING_JIFFIES; -+ -+ /* loop until finished the transfer */ -+ while (bs->rx_len) { -+ /* fill in tx fifo with remaining data */ -+ bcm2835_wr_fifo(bs); -+ -+ /* read from fifo as much as possible */ -+ bcm2835_rd_fifo(bs); -+ -+ /* if there is still data pending to read -+ * then check the timeout -+ */ -+ if (bs->rx_len && time_after(jiffies, timeout)) { -+ dev_dbg_ratelimited(&spi->dev, -+ "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n", -+ jiffies - timeout, -+ bs->tx_len, bs->rx_len); -+ /* fall back to interrupt mode */ -+ return bcm2835_spi_transfer_one_irq(master, spi, -+ tfr, cs); -+ } -+ } -+ -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* and return without waiting for completion */ -+ return 0; -+} -+ - static int bcm2835_spi_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr) - -From 9a96e7390f5bb3db6138d07ffe6145c17e53246d Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 10 May 2015 20:47:28 +0000 -Subject: [PATCH 156/204] spi: bcm2835: enable dma modes for transfers meeting - certain conditions +From 8b83f4fc351924e62e52b4cdc5e9f8711ccb4274 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:44:02 +0200 +Subject: [PATCH 091/113] lirc-rpi: Make buildable on bcm2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Conditions per spi_transfer are: -* transfer.len >= 96 bytes (to avoid mapping overhead costs) -* transfer.len < 65536 bytes (limitaion by spi-hw block - could get extended) -* an individual scatter/gather transfer length must be a multiple of 4 - for anything but the last transfer - spi-hw block limit. - (some shortcut has been taken in can_dma to avoid unnecessary mapping of - pages which, for which there is a chance that there is a split with a - transfer length not a multiple of 4) - -If it becomes a necessity these restrictions can get removed by additional -code. - -Note that this patch requires a patch to dma-bcm2835.c by Noralf to -enable scatter-gather mode inside the dmaengine, which has not been -merged yet. - -That is why no patch to arch/arm/boot/dts/bcm2835.dtsi is included - the -code works as before without dma when tx/rx are not set, but it writes -a message warning about dma not used: -spi-bcm2835 20204000.spi: no tx-dma configuration found - not using dma mode - -To enable dma-mode add the following lines to the device-tree: - dmas = <&dma 6>, <&dma 7>; - dma-names = "tx", "rx"; - -Tested-by: Noralf Trønnes (private communication) -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit 3ecd37edaa2a6ba3246e2c35714be9316b1087fe) +Signed-off-by: Noralf Trønnes --- - drivers/spi/spi-bcm2835.c | 303 +++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 301 insertions(+), 2 deletions(-) + drivers/staging/media/lirc/lirc_rpi.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 505a993..27fb5b0 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -23,15 +23,18 @@ - #include - #include +diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c +index 24563ec..e1c3cb6 100644 +--- a/drivers/staging/media/lirc/lirc_rpi.c ++++ b/drivers/staging/media/lirc/lirc_rpi.c +@@ -39,11 +39,12 @@ + #include + #include + #include +-#include + #include + #include +- + #include ++#ifndef CONFIG_ARCH_BCM2835 ++#include ++#endif + + #define LIRC_DRIVER_NAME "lirc_rpi" + #define RBUF_LEN 256 +@@ -388,6 +389,10 @@ static int init_port(void) + } + else + { ++#ifdef CONFIG_ARCH_BCM2835 ++ ret = -EINVAL; ++ goto exit_init_port; ++#else + if (gpio_in_pin >= BCM2708_NR_GPIOS || + gpio_out_pin >= BCM2708_NR_GPIOS) { + ret = -EINVAL; +@@ -413,6 +418,7 @@ static int init_port(void) + bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); + gpiochip->direction_input(gpiochip, gpio_in_pin); + gpiochip->direction_output(gpiochip, gpio_out_pin, 1); ++#endif + } + + gpiochip->set(gpiochip, gpio_out_pin, invert); + +From 12c4848d2b2a44c1953b7bf560f21eab68d5ede3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:44:36 +0200 +Subject: [PATCH 092/113] i2c-bcm2708: Make buildable on bcm2835 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + drivers/i2c/busses/Kconfig | 2 +- + drivers/i2c/busses/i2c-bcm2708.c | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index eb5f729..aab0b52 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -10,7 +10,7 @@ comment "PC SMBus host controller drivers" + + config I2C_BCM2708 + tristate "BCM2708 BSC" +- depends on MACH_BCM2708 || MACH_BCM2709 ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 + help + Enabling this option will add BSC (Broadcom Serial Controller) + support for the BCM2708. BSC is a Broadcom proprietary bus compatible +diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c +index 8b8762d..5b4fd7b 100644 +--- a/drivers/i2c/busses/i2c-bcm2708.c ++++ b/drivers/i2c/busses/i2c-bcm2708.c +@@ -96,6 +96,9 @@ struct bcm2708_i2c { + bool error; + }; + ++#ifdef CONFIG_ARCH_BCM2835 ++static void bcm2708_i2c_init_pinmode(int id) { } ++#else + /* + * This function sets the ALT mode on the I2C pins so that we can use them with + * the BSC hardware. +@@ -123,6 +126,7 @@ static void bcm2708_i2c_init_pinmode(int id) + #undef INP_GPIO + #undef SET_GPIO_ALT + } ++#endif + + static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) + { + +From 13a84b674bb9f073f129d948dab08852ac2124f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:45:08 +0200 +Subject: [PATCH 093/113] bcm2708-i2s: Make buildable on bcm2835 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + sound/soc/bcm/Kconfig | 2 +- + sound/soc/bcm/bcm2708-i2s.c | 6 ++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index fc151ea..257faa78 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -10,7 +10,7 @@ config SND_BCM2835_SOC_I2S + + config SND_BCM2708_SOC_I2S + tristate "SoC Audio support for the Broadcom BCM2708 I2S module" +- depends on MACH_BCM2708 || MACH_BCM2709 ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 + select REGMAP_MMIO + select SND_SOC_DMAENGINE_PCM + select SND_SOC_GENERIC_DMAENGINE_PCM +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +index 5e93cd6..ad9ca2c 100644 +--- a/sound/soc/bcm/bcm2708-i2s.c ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -40,7 +40,9 @@ #include -+#include -+#include - #include - #include #include - #include - #include - #include --#include --#include -+#include - #include -+#include -+#include - #include - - /* SPI register offsets */ -@@ -70,6 +73,7 @@ - - #define BCM2835_SPI_POLLING_LIMIT_US 30 - #define BCM2835_SPI_POLLING_JIFFIES 2 -+#define BCM2835_SPI_DMA_MIN_LENGTH 96 - #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_NO_CS | SPI_3WIRE) - -@@ -83,6 +87,7 @@ struct bcm2835_spi { - u8 *rx_buf; - int tx_len; - int rx_len; -+ bool dma_pending; - }; - - static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg) -@@ -128,12 +133,15 @@ static void bcm2835_spi_reset_hw(struct spi_master *master) - /* Disable SPI interrupts and transfer */ - cs &= ~(BCM2835_SPI_CS_INTR | - BCM2835_SPI_CS_INTD | -+ BCM2835_SPI_CS_DMAEN | - BCM2835_SPI_CS_TA); - /* and reset RX/TX FIFOS */ - cs |= BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX; - - /* and reset the SPI_HW */ - bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+ /* as well as DLEN */ -+ bcm2835_wr(bs, BCM2835_SPI_DLEN, 0); - } - - static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) -@@ -193,6 +201,279 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master, - return 1; - } - -+/* -+ * DMA support -+ * -+ * this implementation has currently a few issues in so far as it does -+ * not work arrount limitations of the HW. -+ * -+ * the main one being that DMA transfers are limited to 16 bit -+ * (so 0 to 65535 bytes) by the SPI HW due to BCM2835_SPI_DLEN -+ * -+ * also we currently assume that the scatter-gather fragments are -+ * all multiple of 4 (except the last) - otherwise we would need -+ * to reset the FIFO before subsequent transfers... -+ * this also means that tx/rx transfers sg's need to be of equal size! -+ * -+ * there may be a few more border-cases we may need to address as well -+ * but unfortunately this would mean splitting up the scatter-gather -+ * list making it slightly unpractical... -+ */ -+static void bcm2835_spi_dma_done(void *data) -+{ -+ struct spi_master *master = data; -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ -+ /* reset fifo and HW */ -+ bcm2835_spi_reset_hw(master); -+ -+ /* and terminate tx-dma as we do not have an irq for it -+ * because when the rx dma will terminate and this callback -+ * is called the tx-dma must have finished - can't get to this -+ * situation otherwise... -+ */ -+ dmaengine_terminate_all(master->dma_tx); -+ -+ /* mark as no longer pending */ -+ bs->dma_pending = 0; -+ -+ /* and mark as completed */; -+ complete(&master->xfer_completion); -+} -+ -+static int bcm2835_spi_prepare_sg(struct spi_master *master, -+ struct spi_transfer *tfr, -+ bool is_tx) -+{ -+ struct dma_chan *chan; -+ struct scatterlist *sgl; -+ unsigned int nents; -+ enum dma_transfer_direction dir; -+ unsigned long flags; -+ -+ struct dma_async_tx_descriptor *desc; -+ dma_cookie_t cookie; -+ -+ if (is_tx) { -+ dir = DMA_MEM_TO_DEV; -+ chan = master->dma_tx; -+ nents = tfr->tx_sg.nents; -+ sgl = tfr->tx_sg.sgl; -+ flags = 0 /* no tx interrupt */; -+ -+ } else { -+ dir = DMA_DEV_TO_MEM; -+ chan = master->dma_rx; -+ nents = tfr->rx_sg.nents; -+ sgl = tfr->rx_sg.sgl; -+ flags = DMA_PREP_INTERRUPT; -+ } -+ /* prepare the channel */ -+ desc = dmaengine_prep_slave_sg(chan, sgl, nents, dir, flags); -+ if (!desc) -+ return -EINVAL; -+ -+ /* set callback for rx */ -+ if (!is_tx) { -+ desc->callback = bcm2835_spi_dma_done; -+ desc->callback_param = master; -+ } -+ -+ /* submit it to DMA-engine */ -+ cookie = dmaengine_submit(desc); -+ -+ return dma_submit_error(cookie); -+} -+ -+static inline int bcm2835_check_sg_length(struct sg_table *sgt) -+{ -+ int i; -+ struct scatterlist *sgl; -+ -+ /* check that the sg entries are word-sized (except for last) */ -+ for_each_sg(sgt->sgl, sgl, (int)sgt->nents - 1, i) { -+ if (sg_dma_len(sgl) % 4) -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_spi_transfer_one_dma(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ int ret; -+ -+ /* check that the scatter gather segments are all a multiple of 4 */ -+ if (bcm2835_check_sg_length(&tfr->tx_sg) || -+ bcm2835_check_sg_length(&tfr->rx_sg)) { -+ dev_warn_once(&spi->dev, -+ "scatter gather segment length is not a multiple of 4 - falling back to interrupt mode\n"); -+ return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); -+ } -+ -+ /* setup tx-DMA */ -+ ret = bcm2835_spi_prepare_sg(master, tfr, true); -+ if (ret) -+ return ret; -+ -+ /* start TX early */ -+ dma_async_issue_pending(master->dma_tx); -+ -+ /* mark as dma pending */ -+ bs->dma_pending = 1; -+ -+ /* set the DMA length */ -+ bcm2835_wr(bs, BCM2835_SPI_DLEN, tfr->len); -+ -+ /* start the HW */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, -+ cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN); -+ -+ /* setup rx-DMA late - to run transfers while -+ * mapping of the rx buffers still takes place -+ * this saves 10us or more. -+ */ -+ ret = bcm2835_spi_prepare_sg(master, tfr, false); -+ if (ret) { -+ /* need to reset on errors */ -+ dmaengine_terminate_all(master->dma_tx); -+ bcm2835_spi_reset_hw(master); -+ return ret; -+ } -+ -+ /* start rx dma late */ -+ dma_async_issue_pending(master->dma_rx); -+ -+ /* wait for wakeup in framework */ -+ return 1; -+} -+ -+static bool bcm2835_spi_can_dma(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr) -+{ -+ /* only run for gpio_cs */ -+ if (!gpio_is_valid(spi->cs_gpio)) -+ return false; -+ -+ /* we start DMA efforts only on bigger transfers */ -+ if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH) -+ return false; -+ -+ /* BCM2835_SPI_DLEN has defined a max transfer size as -+ * 16 bit, so max is 65535 -+ * we can revisit this by using an alternative transfer -+ * method - ideally this would get done without any more -+ * interaction... -+ */ -+ if (tfr->len > 65535) { -+ dev_warn_once(&spi->dev, -+ "transfer size of %d too big for dma-transfer\n", -+ tfr->len); -+ return false; -+ } -+ -+ /* if we run rx/tx_buf with word aligned addresses then we are OK */ -+ if (((u32)tfr->tx_buf % 4 == 0) && ((u32)tfr->tx_buf % 4 == 0)) -+ return true; -+ -+ /* otherwise we only allow transfers within the same page -+ * to avoid wasting time on dma_mapping when it is not practical -+ */ -+ if (((u32)tfr->tx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ dev_warn_once(&spi->dev, -+ "Unaligned spi tx-transfer bridging page\n"); -+ return false; -+ } -+ if (((u32)tfr->rx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ dev_warn_once(&spi->dev, -+ "Unaligned spi tx-transfer bridging page\n"); -+ return false; -+ } -+ -+ /* return OK */ -+ return true; -+} -+ -+void bcm2835_dma_release(struct spi_master *master) -+{ -+ if (master->dma_tx) { -+ dmaengine_terminate_all(master->dma_tx); -+ dma_release_channel(master->dma_tx); -+ master->dma_tx = NULL; -+ } -+ if (master->dma_rx) { -+ dmaengine_terminate_all(master->dma_rx); -+ dma_release_channel(master->dma_rx); -+ master->dma_rx = NULL; -+ } -+} -+ -+void bcm2835_dma_init(struct spi_master *master, struct device *dev) -+{ -+ struct dma_slave_config slave_config; -+ const __be32 *addr; -+ dma_addr_t dma_reg_base; -+ int ret; -+ -+ /* base address in dma-space */ -+ addr = of_get_address(master->dev.of_node, 0, NULL, NULL); -+ if (!addr) { -+ dev_err(dev, "could not get DMA-register address - not using dma mode\n"); -+ goto err; -+ } -+ dma_reg_base = be32_to_cpup(addr); -+ -+ /* get tx/rx dma */ -+ master->dma_tx = dma_request_slave_channel(dev, "tx"); -+ if (!master->dma_tx) { -+ dev_err(dev, "no tx-dma configuration found - not using dma mode\n"); -+ goto err; -+ } -+ master->dma_rx = dma_request_slave_channel(dev, "rx"); -+ if (!master->dma_rx) { -+ dev_err(dev, "no rx-dma configuration found - not using dma mode\n"); -+ goto err_release; -+ } -+ -+ /* configure DMAs */ -+ slave_config.direction = DMA_MEM_TO_DEV; -+ slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO); -+ slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ -+ ret = dmaengine_slave_config(master->dma_tx, &slave_config); -+ if (ret) -+ goto err_config; -+ -+ slave_config.direction = DMA_DEV_TO_MEM; -+ slave_config.src_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO); -+ slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ -+ ret = dmaengine_slave_config(master->dma_rx, &slave_config); -+ if (ret) -+ goto err_config; -+ -+ /* all went well, so set can_dma */ -+ master->can_dma = bcm2835_spi_can_dma; -+ master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */ -+ /* need to do TX AND RX DMA, so we need dummy buffers */ -+ master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; -+ -+ return; -+ -+err_config: -+ dev_err(dev, "issue configuring dma: %d - not using DMA mode\n", -+ ret); -+err_release: -+ bcm2835_dma_release(master); -+err: -+ return; -+} -+ - static int bcm2835_spi_transfer_one_poll(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr, -@@ -299,6 +580,11 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - return bcm2835_spi_transfer_one_poll(master, spi, tfr, - cs, xfer_time_us); - -+ /* run in dma mode if conditions are right */ -+ if (master->can_dma && bcm2835_spi_can_dma(master, spi, tfr)) -+ return bcm2835_spi_transfer_one_dma(master, spi, tfr, cs); -+ -+ /* run in interrupt-mode */ - return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); - } - -@@ -324,6 +610,15 @@ static int bcm2835_spi_prepare_message(struct spi_master *master, - static void bcm2835_spi_handle_err(struct spi_master *master, - struct spi_message *msg) - { -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ -+ /* if an error occurred and we have an active dma, then terminate */ -+ if (bs->dma_pending) { -+ dmaengine_terminate_all(master->dma_tx); -+ dmaengine_terminate_all(master->dma_rx); -+ bs->dma_pending = 0; -+ } -+ /* and reset */ - bcm2835_spi_reset_hw(master); - } - -@@ -523,6 +818,8 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - goto out_clk_disable; - } - -+ bcm2835_dma_init(master, &pdev->dev); -+ - /* initialise the hardware with the default polarities */ - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); -@@ -553,6 +850,8 @@ static int bcm2835_spi_remove(struct platform_device *pdev) - - clk_disable_unprepare(bs->clk); - -+ bcm2835_dma_release(master); -+ - return 0; - } - - -From 6e92fd1644001ba7827e2706c0ed4fd4c2d85bc1 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Tue, 12 May 2015 10:32:08 +0000 -Subject: [PATCH 157/204] spi: bcm2835: fix kbuild compile warnings/errors and - a typo - -fixes several warnings/error emmitted by the kbuild system: -* warn: cast from pointer to integer of different size - using size_t instead of u32 -* error: 'SZ_4K' undeclared - moved to PAGE_SIZE and PAGE_MASK instead - -Review showed also a typo in the same code where tx_buff -was checked twice instead of checking both rx and tx_buff. - -Reported by: Stephen Rothwell -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit 7e52be0d576e8f7bc99a606f07b9d000c4340f04) ---- - drivers/spi/spi-bcm2835.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 27fb5b0..52aaf2d 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -20,6 +20,7 @@ - * GNU General Public License for more details. - */ - -+#include #include - #include - #include -@@ -378,18 +379,19 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, - } ++#ifndef CONFIG_ARCH_BCM2835 + #include ++#endif - /* if we run rx/tx_buf with word aligned addresses then we are OK */ -- if (((u32)tfr->tx_buf % 4 == 0) && ((u32)tfr->tx_buf % 4 == 0)) -+ if ((((size_t)tfr->rx_buf & 3) == 0) && -+ (((size_t)tfr->tx_buf & 3) == 0)) - return true; - - /* otherwise we only allow transfers within the same page - * to avoid wasting time on dma_mapping when it is not practical - */ -- if (((u32)tfr->tx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); - return false; - } -- if (((u32)tfr->rx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); - return false; - -From 63ad0b9f2b638c3968473d46f732de9f28ad184b Mon Sep 17 00:00:00 2001 -From: kbuild test robot -Date: Tue, 12 May 2015 19:43:59 +0800 -Subject: [PATCH 158/204] spi: bcm2835: bcm2835_dma_release() can be static - -Signed-off-by: Fengguang Wu -Signed-off-by: Mark Brown -(cherry picked from commit 29ad1a7a9e08f1d2b6795c5278a0c0fd23679ded) ---- - drivers/spi/spi-bcm2835.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 52aaf2d..bad36c5 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -401,7 +401,7 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, - return true; + #include + #include +@@ -320,6 +322,9 @@ static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, } --void bcm2835_dma_release(struct spi_master *master) -+static void bcm2835_dma_release(struct spi_master *master) + ++#ifdef CONFIG_ARCH_BCM2835 ++static void bcm2708_i2s_setup_gpio(void) { } ++#else + static int bcm2708_i2s_set_function(unsigned offset, int function) { - if (master->dma_tx) { - dmaengine_terminate_all(master->dma_tx); -@@ -415,7 +415,7 @@ void bcm2835_dma_release(struct spi_master *master) + #define GPIOFSEL(x) (0x00+(x)*4) +@@ -379,6 +384,7 @@ static void bcm2708_i2s_setup_gpio(void) + bcm2708_i2s_set_function(pin, alt); } } ++#endif --void bcm2835_dma_init(struct spi_master *master, struct device *dev) -+static void bcm2835_dma_init(struct spi_master *master, struct device *dev) - { - struct dma_slave_config slave_config; - const __be32 *addr; + static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, -From f3260b7d15164b1ddd0f080592defb79949db0aa Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 22 Jul 2015 08:34:41 +0000 -Subject: [PATCH 159/204] dt-overlay to enable dma for spi driver +From f876ec23ff9316417ab43b252c989992984922f4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:50:02 +0200 +Subject: [PATCH 094/113] bcm2835: Add support for uart1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit -Signed-off-by: Martin Sperl +This is a hack until a proper solution is agreed upon. +Martin Sperl is doing some work in this area. + +Signed-off-by: Noralf Trønnes --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/spi-dma-overlay.dts | 20 ++++++++++++++++++++ - 2 files changed, 21 insertions(+) - create mode 100755 arch/arm/boot/dts/overlays/spi-dma-overlay.dts + arch/arm/mach-bcm/board_bcm2835.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 753554b..956e395 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -45,6 +45,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/spi-dma-overlay.dts b/arch/arm/boot/dts/overlays/spi-dma-overlay.dts -new file mode 100755 -index 0000000..266cf9d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-dma-overlay.dts -@@ -0,0 +1,20 @@ -+/* -+ * Device tree overlay for spi-bcm2835 to allow dma -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ dmas = <&dma 6>, <&dma 7>; -+ dma-names = "tx", "rx"; -+ }; -+ }; -+ }; - -From 67c4106248a6d4eaee1de239e8f18da5e08ed8fd Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 22 Jul 2015 12:41:54 +0000 -Subject: [PATCH 160/204] dt: overlay: added documentation of spi-dma overlay - -Signed-off-by: Martin Sperl ---- - arch/arm/boot/dts/overlays/README | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1cd2140..bda8c14 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -515,6 +515,12 @@ Load: dtoverlay=spi-bcm2835 - Params: +diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c +index 1e6f1cf9..ea36eec 100644 +--- a/arch/arm/mach-bcm/board_bcm2835.c ++++ b/arch/arm/mach-bcm/board_bcm2835.c +@@ -22,6 +22,29 @@ + #include + #include - -+Name: spi-dma -+Info: enables dma modes for spi-bcm2835 -+Load: dtoverlay=spi-dma -+Params: -+ -+ - Name: tinylcd35 - Info: 3.5" Color TFT Display by www.tinylcd.com - Options: Touch, RTC, keypad - -From 1981274d8b58c613e5f3f0f40068f25ffcdbe481 Mon Sep 17 00:00:00 2001 -From: Serge Schneider -Date: Mon, 17 Aug 2015 18:06:16 +0100 -Subject: [PATCH 161/204] rpisense-fb: add low-light mode and gamma control - ---- - drivers/video/fbdev/rpisense-fb.c | 68 +++++++++++++++++++++++++++++--- - include/linux/mfd/rpisense/framebuffer.h | 6 ++- - 2 files changed, 68 insertions(+), 6 deletions(-) - -diff --git a/drivers/video/fbdev/rpisense-fb.c b/drivers/video/fbdev/rpisense-fb.c -index 99bb8ea..90553fa 100644 ---- a/drivers/video/fbdev/rpisense-fb.c -+++ b/drivers/video/fbdev/rpisense-fb.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -26,22 +27,35 @@ - #include - #include - -+static bool lowlight; -+module_param(lowlight, bool, 0); -+MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); -+ - struct rpisense *rpisense; - - struct rpisense_fb_param { - char __iomem *vmem; - u8 *vmem_work; - u32 vmemsize; -- u8 gamma[32]; -+ u8 *gamma; - }; - -+static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -+ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, -+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, -+ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}; -+ -+static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, -+ 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, -+ 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,}; -+ -+static u8 gamma_user[32]; -+ - static struct rpisense_fb_param rpisense_fb_param = { - .vmem = NULL, - .vmemsize = 128, -- .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -- 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, -- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, -- 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}, -+ .gamma = gamma_default, - }; - - static struct fb_deferred_io rpisense_fb_defio; -@@ -127,6 +141,46 @@ static struct fb_deferred_io rpisense_fb_defio = { - .deferred_io = rpisense_fb_deferred_io, - }; - -+static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd, -+ unsigned long arg) ++/* Use this hack until a proper solution is agreed upon */ ++static void __init bcm2835_init_uart1(void) +{ -+ switch (cmd) { -+ case SENSEFB_FBIOGET_GAMMA: -+ if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma, -+ sizeof(u8[32]))) -+ return -EFAULT; -+ return 0; -+ case SENSEFB_FBIOSET_GAMMA: -+ if (copy_from_user(gamma_user, (void __user *)arg, -+ sizeof(u8[32]))) -+ return -EFAULT; -+ rpisense_fb_param.gamma = gamma_user; -+ schedule_delayed_work(&info->deferred_work, -+ rpisense_fb_defio.delay); -+ return 0; -+ case SENSEFB_FBIORESET_GAMMA: -+ switch (arg) { -+ case 0: -+ rpisense_fb_param.gamma = gamma_default; -+ break; -+ case 1: -+ rpisense_fb_param.gamma = gamma_low; -+ break; -+ case 2: -+ rpisense_fb_param.gamma = gamma_user; -+ break; -+ default: -+ return -EINVAL; ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); ++ if (of_device_is_available(np)) { ++ np = of_find_compatible_node(NULL, NULL, ++ "bcrm,bcm2835-aux-enable"); ++ if (np) { ++ void __iomem *base = of_iomap(np, 0); ++ ++ if (!base) { ++ pr_err("bcm2835: Failed enabling Mini UART\n"); ++ return; ++ } ++ ++ writel(1, base); ++ pr_info("bcm2835: Mini UART enabled\n"); + } -+ schedule_delayed_work(&info->deferred_work, -+ rpisense_fb_defio.delay); -+ break; -+ default: -+ return -EINVAL; + } -+ return 0; +} + - static struct fb_ops rpisense_fb_ops = { - .owner = THIS_MODULE, - .fb_read = fb_sys_read, -@@ -134,6 +188,7 @@ static struct fb_ops rpisense_fb_ops = { - .fb_fillrect = rpisense_fb_fillrect, - .fb_copyarea = rpisense_fb_copyarea, - .fb_imageblit = rpisense_fb_imageblit, -+ .fb_ioctl = rpisense_fb_ioctl, - }; - - static int rpisense_fb_probe(struct platform_device *pdev) -@@ -171,6 +226,9 @@ static int rpisense_fb_probe(struct platform_device *pdev) - info->screen_base = rpisense_fb_param.vmem; - info->screen_size = rpisense_fb_param.vmemsize; - -+ if (lowlight) -+ rpisense_fb_param.gamma = gamma_low; + static void __init bcm2835_init(void) + { + struct device_node *np = of_find_node_by_path("/system"); +@@ -42,6 +65,8 @@ static void __init bcm2835_init(void) + system_rev = val; + if (!of_property_read_u64(np, "linux,serial", &val64)) + system_serial_low = val64; + - fb_deferred_io_init(info); - - ret = register_framebuffer(info); -diff --git a/include/linux/mfd/rpisense/framebuffer.h b/include/linux/mfd/rpisense/framebuffer.h -index c4c1118..2ba95d7 100644 ---- a/include/linux/mfd/rpisense/framebuffer.h -+++ b/include/linux/mfd/rpisense/framebuffer.h -@@ -16,7 +16,11 @@ - #ifndef __LINUX_RPISENSE_FB_H_ - #define __LINUX_RPISENSE_FB_H_ - --#include -+#define SENSEFB_FBIO_IOC_MAGIC 0xF1 -+ -+#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0) -+#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1) -+#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2) - - struct rpisense; - - -From 82bd9aca8c50e84e17b9c62a6d5c528aa8f0e490 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 19 Aug 2015 11:38:10 +0100 -Subject: [PATCH 162/204] BCM270X_DT: README - add note on indentation - ---- - arch/arm/boot/dts/overlays/README | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index bda8c14..ac9c427 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -74,6 +74,10 @@ behaviour. See the list of overlays below for a description of the parameters an - The Overlay and Parameter Reference - =================================== - -+N.B. When editing this file, please preserve the indentation levels to make it simple to parse -+programmatically. NO HARD TABS. -+ -+ - Name: - Info: Configures the base Raspberry Pi hardware - Load: - -From b6277bf87e266469ee14448d41209f79f3caa8d1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 20 Aug 2015 13:50:18 +0100 -Subject: [PATCH 163/204] bcm2708-dmaengine: Use more DMA channels (but not 12) - -1) Only the bcm2708_fb drivers uses the legacy DMA API, and -it requires a BULK-capable channel, so all other types -(FAST, NORMAL and LITE) can be made available to the regular -DMA API. - -2) DMA channels 11-14 share an interrupt. The driver can't -handle this, so don't use channels 12-14 (12 was used, probably -because it appears to have an interrupt, but in reality that -interrupt is for activity on ANY channel). This may explain -a lockup encountered when running out of DMA channels. - -The combined effect of this patch is to leave 7 DMA channels -available + channel 0 for bcm2708_fb via the legacy API. - -See: https://github.com/raspberrypi/linux/issues/1110 - https://github.com/raspberrypi/linux/issues/1108 ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 ++-- - drivers/dma/bcm2708-dmaengine.c | 43 +++++++++++++++++++++++------------ - 2 files changed, 31 insertions(+), 17 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index ea3bd9ca..f096f45 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -59,11 +59,10 @@ - <1 24>, - <1 25>, - <1 26>, -- <1 27>, -- <1 28>; -+ <1 27>; - - #dma-cells = <1>; -- brcm,dma-channel-mask = <0x7f35>; -+ brcm,dma-channel-mask = <0x0f35>; - }; - - intc: interrupt-controller { -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 73c6c00..85ce18b 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -184,7 +184,7 @@ static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, ++ bcm2835_init_uart1(); } - static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -- unsigned preferred_feature_set) -+ unsigned required_feature_set) - { - u32 chans; - int chan = 0; -@@ -193,10 +193,8 @@ static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, - chans = dmaman->chan_available; - for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) - /* select the subset of available channels with the desired -- feature so long as some of the candidate channels have that -- feature */ -- if ((preferred_feature_set & (1 << feature)) && -- (chans & dmaman->has_feature[feature])) -+ features */ -+ if (required_feature_set & (1 << feature)) - chans &= dmaman->has_feature[feature]; - - if (!chans) -@@ -228,7 +226,7 @@ static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) - - /* DMA Manager Monitor */ - --extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+extern int bcm_dma_chan_alloc(unsigned required_feature_set, - void __iomem **out_dma_base, int *out_dma_irq) - { - struct vc_dmaman *dmaman = g_dmaman; -@@ -240,7 +238,7 @@ extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, - return -ENODEV; - - mutex_lock(&dmaman->lock); -- chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ chan = vc_dmaman_chan_alloc(dmaman, required_feature_set); - if (chan < 0) - goto out; - -@@ -442,6 +440,7 @@ static inline struct bcm2835_desc *to_bcm2835_dma_desc( - return container_of(t, struct bcm2835_desc, vd.tx); - } - -+#if 0 - static void dma_dumpregs(struct bcm2835_chan *c) - { - pr_debug("-------------DMA DUMPREGS-------------\n"); -@@ -457,6 +456,7 @@ static void dma_dumpregs(struct bcm2835_chan *c) - readl(c->chan_base + BCM2835_DMA_NEXTCB)); - pr_debug("--------------------------------------\n"); - } -+#endif - - static void bcm2835_dma_desc_free(struct virt_dma_desc *vd) - { -@@ -862,6 +862,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( - uint32_t len = sg_dma_len(sgent); - - for (j = 0; j < len; j += max_size) { -+ u32 waits; - struct bcm2835_dma_cb *control_block = - &d->control_block_base[i+splitct]; - -@@ -879,7 +880,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( - } - - /* Common part */ -- u32 waits = SDHCI_BCM_DMA_WAITS; -+ waits = SDHCI_BCM_DMA_WAITS; - if ((dma_debug >> 0) & 0x1f) - waits = (dma_debug >> 0) & 0x1f; - control_block->info |= BCM2835_DMA_WAITS(waits); -@@ -1074,6 +1075,14 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - int rc; - int i; - int irq; -+#ifdef CONFIG_DMA_BCM2708_LEGACY -+ static const u32 wanted_features[] = { -+ BCM_DMA_FEATURE_FAST, -+ BCM_DMA_FEATURE_NORMAL, -+ BCM_DMA_FEATURE_LITE -+ }; -+ int j; -+#endif - - - if (!pdev->dev.dma_mask) -@@ -1120,20 +1129,24 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, od); - -- for (i = 0; i < 5; i++) { -+ for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) { -+ - void __iomem *chan_base; - int chan_id; - -- chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE, -- &chan_base, -- &irq); -+ chan_id = bcm_dma_chan_alloc(wanted_features[j], -+ &chan_base, -+ &irq); - -- if (chan_id < 0) -- break; -+ if (chan_id < 0) { -+ j++; -+ continue; -+ } - - rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq); - if (rc) - goto err_no_dma; -+ i++; - } - - if (pdev->dev.of_node) { -@@ -1146,6 +1159,8 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - } - } - -+ dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i); -+ - #else - rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (rc) + static const char * const bcm2835_compat[] = { -From 72de9ce92b348a0f4f9230affa0e27d3f775342e Mon Sep 17 00:00:00 2001 +From 00cc274f98a714532579d62a113b3b48a6a341c1 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:03:47 +0100 -Subject: [PATCH 164/204] RaspiDAC3 support +Subject: [PATCH 095/113] RaspiDAC3 support Signed-off-by: Jan Grulich --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - sound/soc/bcm/Kconfig | 8 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/raspidac3.c | 191 +++++++++++++++++++++++ - 8 files changed, 255 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts + sound/soc/bcm/Kconfig | 8 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/raspidac3.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 201 insertions(+) create mode 100644 sound/soc/bcm/raspidac3.c -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 956e395..9b03b1f 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -37,6 +37,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index ac9c427..7e38eb3 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -455,6 +455,12 @@ Params: pin Output pin (default 18) - see table - clock PWM clock frequency (informational) - - -+Name: raspidac3 -+Info: Configures the RaspiDAV Rev.3x audio card -+Load: dtoverlay=raspidac3 -+Params: -+ -+ - Name: rpi-dac - Info: Configures the RPi DAC audio card - Load: dtoverlay=rpi-dac -diff --git a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts -new file mode 100644 -index 0000000..1bd8054 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts -@@ -0,0 +1,45 @@ -+// Definitions for RaspiDACv3 -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "jg,raspidacv3"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ -+ tpa6130a2: tpa6130a2@60 { -+ compatible = "ti,tpa6130a2"; -+ reg = <0x60>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d7457fc..0d457a3 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -832,6 +832,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 59b2fdd..8979f23 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -825,6 +825,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index fc151ea..3db2852 100644 +index 257faa78..f465dd2 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -67,3 +67,11 @@ config SND_BCM2708_SOC_IQAUDIO_DAC @@ -145735,537 +140264,10 @@ index 0000000..fddaeec +MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x"); +MODULE_LICENSE("GPL v2"); -From 5639b22eb081048b07152c5bd90d25d7768cb1cf Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 14 Jul 2015 16:55:02 +0100 -Subject: [PATCH 165/204] config: Add SND_SOC_ADAU1701 module - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 0d457a3..16a8354 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -833,6 +833,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m -+CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 8979f23..7dd4fd4 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -826,6 +826,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m -+CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - -From 6a0f88404b8cc24c073b1d157be02fbc9007788a Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 29 Jul 2015 07:34:10 +0000 -Subject: [PATCH 166/204] spi: bcm2835: fix overflow in calculation of transfer - time - -This resulted in the use of polling mode when other approaches -(dma or interrupts) would have been more appropriate. - -Happened for transfers longer than 477 bytes. - -Reported-by: Noralf Tronnes -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit 0122a5183088e3117bb9c8fbe248914efb502f3f) ---- - drivers/spi/spi-bcm2835.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index bad36c5..b68991c 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr, - u32 cs, -- unsigned long xfer_time_us) -+ unsigned long long xfer_time_us) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long timeout; -@@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long spi_hz, clk_hz, cdiv; -- unsigned long spi_used_hz, xfer_time_us; -+ unsigned long spi_used_hz; -+ unsigned long long xfer_time_us; - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - - /* set clock */ -@@ -573,9 +574,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - bs->rx_len = tfr->len; - - /* calculate the estimated time in us the transfer runs */ -- xfer_time_us = tfr->len -+ xfer_time_us = (unsigned long long)tfr->len - * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */ -- * 1000000 / spi_used_hz; -+ * 1000000; -+ do_div(xfer_time_us, spi_used_hz); - - /* for short requests run polling*/ - if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US) - -From 74f48a53e476a7d34ab0a58c883149b19e5bbdec Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 8 Sep 2015 15:14:50 +0100 -Subject: [PATCH 167/204] BCM270X_DT: Add SDIO overlay - -Enable SDIO from MMC interface via GPIOs 22-27. Includes the sdhost -overlay to free up the MMC interface. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 15 +++++++++++++++ - arch/arm/boot/dts/overlays/sdio-overlay.dts | 29 +++++++++++++++++++++++++++++ - 3 files changed, 45 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 9b03b1f..43e9c96 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -44,6 +44,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7e38eb3..a749ff7 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -513,6 +513,21 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - debug Enable debug output (default off) - - -+Name: sdio -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, -+ and enables SDIO via GPIOs 22-27. -+Load: dtoverlay=sdio,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 1) -+ -+ debug Enable debug output (default off) -+ -+ - Name: spi-bcm2708 - Info: Selects the bcm2708-spi SPI driver - Load: dtoverlay=spi-bcm2708 -diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts -new file mode 100644 -index 0000000..164f269 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -0,0 +1,29 @@ -+/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ -+ -+/include/ "sdhost-overlay.dts" -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@3 { -+ target = <&mmc>; -+ __overlay__ { -+ compatible = "brcm,bcm2835-mmc"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ non-removable; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ sdio_pins: sdio_pins { -+ brcm,pins = <22 23 24 25 26 27>; -+ brcm,function = <7 7 7 7 7 7>; /* ALT3 = SD1 */ -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ }; -+ }; -+}; - -From a216fc64bde9a95901c92deb7bcd7f3fe4567f75 Mon Sep 17 00:00:00 2001 -From: Luke Wren -Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 168/204] Add /dev/gpiomem device for rootless user GPIO access - -Signed-off-by: Luke Wren ---- - arch/arm/boot/dts/bcm2708.dtsi | 6 + - arch/arm/boot/dts/bcm2709.dtsi | 6 + - drivers/char/broadcom/Kconfig | 9 ++ - drivers/char/broadcom/Makefile | 3 + - drivers/char/broadcom/bcm2835-gpiomem.c | 265 ++++++++++++++++++++++++++++++++ - 5 files changed, 289 insertions(+) - create mode 100644 drivers/char/broadcom/bcm2835-gpiomem.c - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 0d47427..3bed0a6 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -15,5 +15,11 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -+ -+ gpiomem { -+ compatible = "brcm,bcm2835-gpiomem"; -+ reg = <0x7e200000 0x1000>; -+ status = "okay"; -+ }; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index 5e0b935..811d825 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -16,6 +16,12 @@ - compatible = "arm,cortex-a7-pmu"; - interrupts = <3 9>; - }; -+ -+ gpiomem { -+ compatible = "brcm,bcm2835-gpiomem"; -+ reg = <0x7e200000 0x1000>; -+ status = "okay"; -+ }; - }; - - timer { -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index fc40846..bc2eb1e 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -38,3 +38,12 @@ config BCM_VC_SM - help - Support for the VC shared memory on the Broadcom reference - design. Uses the VCHIQ stack. -+ -+config BCM2835_DEVGPIOMEM -+ tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835" -+ default m -+ help -+ Provides users with root-free access to the GPIO registers -+ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO -+ register page to the user's pointer. -+ -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 18171e2..664e2c4 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -2,3 +2,6 @@ obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o - obj-$(CONFIG_BCM_VCIO) += vcio.o - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ -+ -+obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o -+ -diff --git a/drivers/char/broadcom/bcm2835-gpiomem.c b/drivers/char/broadcom/bcm2835-gpiomem.c -new file mode 100644 -index 0000000..0085e13 ---- /dev/null -+++ b/drivers/char/broadcom/bcm2835-gpiomem.c -@@ -0,0 +1,265 @@ -+/** -+ * GPIO memory device driver -+ * -+ * Creates a chardev /dev/gpiomem which will provide user access to -+ * the BCM2835's GPIO registers when it is mmap()'d. -+ * No longer need root for user GPIO access, but without relaxing permissions -+ * on /dev/mem. -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DEVICE_NAME "bcm2835-gpiomem" -+#define DRIVER_NAME "gpiomem-bcm2835" -+#define DEVICE_MINOR 0 -+ -+struct bcm2835_gpiomem_instance { -+ unsigned long gpio_regs_phys; -+ struct device *dev; -+}; -+ -+static struct cdev bcm2835_gpiomem_cdev; -+static dev_t bcm2835_gpiomem_devid; -+static struct class *bcm2835_gpiomem_class; -+static struct device *bcm2835_gpiomem_dev; -+static struct bcm2835_gpiomem_instance *inst; -+ -+ -+/**************************************************************************** -+* -+* GPIO mem chardev file ops -+* -+***************************************************************************/ -+ -+static int bcm2835_gpiomem_open(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ int ret = 0; -+ -+ dev_info(inst->dev, "gpiomem device opened."); -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, "Unknown minor device: %d", dev); -+ ret = -ENXIO; -+ } -+ return ret; -+} -+ -+static int bcm2835_gpiomem_release(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ int ret = 0; -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, "Unknown minor device %d", dev); -+ ret = -ENXIO; -+ } -+ return ret; -+} -+ -+static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = { -+#ifdef CONFIG_HAVE_IOREMAP_PROT -+ .access = generic_access_phys -+#endif -+}; -+ -+static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ /* Ignore what the user says - they're getting the GPIO regs -+ whether they like it or not! */ -+ unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT; -+ -+ vma->vm_page_prot = phys_mem_access_prot(file, gpio_page, -+ PAGE_SIZE, -+ vma->vm_page_prot); -+ vma->vm_ops = &bcm2835_gpiomem_vm_ops; -+ if (remap_pfn_range(vma, vma->vm_start, -+ gpio_page, -+ PAGE_SIZE, -+ vma->vm_page_prot)) { -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+static const struct file_operations -+bcm2835_gpiomem_fops = { -+ .owner = THIS_MODULE, -+ .open = bcm2835_gpiomem_open, -+ .release = bcm2835_gpiomem_release, -+ .mmap = bcm2835_gpiomem_mmap, -+}; -+ -+ -+ /**************************************************************************** -+* -+* Probe and remove functions -+* -+***************************************************************************/ -+ -+ -+static int bcm2835_gpiomem_probe(struct platform_device *pdev) -+{ -+ int err; -+ void *ptr_err; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct resource *ioresource; -+ -+ /* Allocate buffers and instance data */ -+ -+ inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL); -+ -+ if (!inst) { -+ err = -ENOMEM; -+ goto failed_inst_alloc; -+ } -+ -+ inst->dev = dev; -+ -+ /* Create character device entries */ -+ -+ err = alloc_chrdev_region(&bcm2835_gpiomem_devid, -+ DEVICE_MINOR, 1, DEVICE_NAME); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to allocate device number"); -+ goto failed_alloc_chrdev; -+ } -+ cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops); -+ bcm2835_gpiomem_cdev.owner = THIS_MODULE; -+ err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to register device"); -+ goto failed_cdev_add; -+ } -+ -+ /* Create sysfs entries */ -+ -+ bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME); -+ ptr_err = bcm2835_gpiomem_class; -+ if (IS_ERR(ptr_err)) -+ goto failed_class_create; -+ -+ bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL, -+ bcm2835_gpiomem_devid, NULL, -+ "gpiomem"); -+ ptr_err = bcm2835_gpiomem_dev; -+ if (IS_ERR(ptr_err)) -+ goto failed_device_create; -+ -+ /* Get address from device tree if available (*_resource() correctly -+ converts the bus address in device tree to a physical address), -+ or use hardcoded offset + BCM2708_PERI_BASE if not. -+ (In spite of its name 2708 actually seems to have the correct -+ mach-dependent value on 2709 etc, as it is defined in -+ mach-bcm270x/platform.h) */ -+ -+ if (node) { -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ inst->gpio_regs_phys = ioresource->start; -+ } else { -+ inst->gpio_regs_phys = GPIO_BASE; -+ } -+ -+ dev_info(inst->dev, "Initialised: Registers at 0x%08lx", -+ inst->gpio_regs_phys); -+ -+ return 0; -+ -+failed_device_create: -+ class_destroy(bcm2835_gpiomem_class); -+failed_class_create: -+ cdev_del(&bcm2835_gpiomem_cdev); -+ err = PTR_ERR(ptr_err); -+failed_cdev_add: -+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); -+failed_alloc_chrdev: -+ kfree(inst); -+failed_inst_alloc: -+ dev_err(inst->dev, "could not load bcm2835_gpiomem"); -+ return err; -+} -+ -+static int bcm2835_gpiomem_remove(struct platform_device *pdev) -+{ -+ struct device *dev = inst->dev; -+ -+ kfree(inst); -+ device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid); -+ class_destroy(bcm2835_gpiomem_class); -+ cdev_del(&bcm2835_gpiomem_cdev); -+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); -+ -+ dev_info(dev, "GPIO mem driver removed - OK"); -+ return 0; -+} -+ -+ /**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_gpiomem_of_match[] = { -+ {.compatible = "brcm,bcm2835-gpiomem",}, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match); -+ -+static struct platform_driver bcm2835_gpiomem_driver = { -+ .probe = bcm2835_gpiomem_probe, -+ .remove = bcm2835_gpiomem_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_gpiomem_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_gpiomem_driver); -+ -+MODULE_ALIAS("platform:gpiomem-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); -+MODULE_AUTHOR("Luke Wren "); - -From 4e9cf1447a7ef0f8f46c6a8170f44c78c1690a96 Mon Sep 17 00:00:00 2001 +From d1de66724543ef739151e4d9af7e46c1fce5044a Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:02:34 +0100 -Subject: [PATCH 169/204] tpa6130a2: Add headphone switch control +Subject: [PATCH 096/113] tpa6130a2: Add headphone switch control Signed-off-by: Jan Grulich --- @@ -146273,7 +140275,7 @@ Signed-off-by: Jan Grulich 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c -index 6fac9e0..f60ebe1c 100644 +index 11d85c5..3caaa17 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -4,6 +4,7 @@ @@ -146334,8 +140336,8 @@ index 6fac9e0..f60ebe1c 100644 + * TPA6130 volume. From -59.5 to +4.0 dB with increasing step size when going * down in gain. */ - static const unsigned int tpa6130_tlv[] = { -@@ -278,6 +295,9 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = { + static const DECLARE_TLV_DB_RANGE(tpa6130_tlv, +@@ -277,6 +294,9 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = { TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0, tpa6130a2_get_volsw, tpa6130a2_put_volsw, tpa6130_tlv), @@ -146344,8 +140346,8 @@ index 6fac9e0..f60ebe1c 100644 + tpa6130a2_get_volsw, tpa6130a2_put_hp_sw), }; - static const unsigned int tpa6140_tlv[] = { -@@ -292,6 +312,9 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = { + static const DECLARE_TLV_DB_RANGE(tpa6140_tlv, +@@ -290,6 +310,9 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = { TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0, tpa6130a2_get_volsw, tpa6130a2_put_volsw, tpa6140_tlv), @@ -146356,3901 +140358,250 @@ index 6fac9e0..f60ebe1c 100644 /* -From bdad59048f5910ea3c4439ba40a4a14ca8f1be90 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 11 Jul 2015 18:48:10 +0200 -Subject: [PATCH 170/204] staging: fbtft: Add reset to fbtft_init_display_dt() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +From 04e1e096a209d02766e03e576637171b3a749246 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 28 Sep 2015 17:28:01 +0100 +Subject: [PATCH 097/113] vchiq: hack: Add include depecated dma include file -When an init sequence is present in the Device Tree, -fbtft_init_display_dt() is used to initialize the display. -Add missing reset function call and activation of -chip select for parallel bus. - -Signed-off-by: Noralf Trønnes --- - drivers/staging/fbtft/fbtft-core.c | 5 +++++ - 1 file changed, 5 insertions(+) + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c -index 53b748b..4f165d3 100644 ---- a/drivers/staging/fbtft/fbtft-core.c -+++ b/drivers/staging/fbtft/fbtft-core.c -@@ -1074,6 +1074,11 @@ static int fbtft_init_display_dt(struct fbtft_par *par) - p = of_prop_next_u32(prop, NULL, &val); - if (!p) - return -EINVAL; +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index c9febcc..c29040f 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -45,6 +45,12 @@ + #include + #include + ++#define dmac_map_area __glue(_CACHE,_dma_map_area) ++#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area) + -+ par->fbtftops.reset(par); -+ if (par->gpio.cs != -1) -+ gpio_set_value(par->gpio.cs, 0); /* Activate chip */ ++extern void dmac_map_area(const void *, size_t, int); ++extern void dmac_unmap_area(const void *, size_t, int); + - while (p) { - if (val & FBTFT_OF_INIT_CMD) { - val &= 0xFFFF; + #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + + #define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset)) -From 928b8dbc73acdb75d3f03ef7d5cf9fc639e0280c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 19 Jul 2015 18:57:06 +0200 -Subject: [PATCH 171/204] BCM270X_DT: mz61581: Revert to spi-bcm2708 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +From 0701ed82c6c110f9415476289e94bf773e32d2f6 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 28 Sep 2015 19:06:42 +0100 +Subject: [PATCH 098/113] bcm2709: Remove custom barrier implementation it is + no different to default -The MZ61581 display does not work with spi-bcm2835 and software -chip select. It works before the commit: -spi: bcm2835: transform native-cs to gpio-cs on first spi_setup - -Revert to spi-bcm2708 until the cause has been detected and the -issue resolved. - -Signed-off-by: Noralf Trønnes --- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++ - 1 file changed, 2 insertions(+) + arch/arm/Kconfig | 1 - + arch/arm/mach-bcm2709/include/mach/barriers.h | 3 --- + 2 files changed, 4 deletions(-) + delete mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index c06fe12..f674a66 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -12,6 +12,8 @@ - fragment@0 { - target = <&spi0>; - __overlay__ { -+ /* does not work with spi-bcm2835 using software chip selects */ -+ compatible = "brcm,bcm2708-spi"; - status = "okay"; +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index f40e621..063454c 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -337,7 +337,6 @@ config ARCH_BCM2708 - spidev@0{ + config ARCH_BCM2709 + bool "Broadcom BCM2709 family" +- select ARCH_HAS_BARRIERS if SMP + select CPU_V7 + select HAVE_SMP + select ARM_AMBA +diff --git a/arch/arm/mach-bcm2709/include/mach/barriers.h b/arch/arm/mach-bcm2709/include/mach/barriers.h +deleted file mode 100644 +index 723cdad..0000000 +--- a/arch/arm/mach-bcm2709/include/mach/barriers.h ++++ /dev/null +@@ -1,3 +0,0 @@ +-#define mb() dsb() +-#define rmb() dsb() +-#define wmb() mb() -From 707866acc48470ec677f1fb6befdfd928d9994f1 Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Tue, 1 Sep 2015 16:52:34 +0000 -Subject: [PATCH 172/204] vchiq: fix NULL pointer dereference when closing - driver +From ccab1d0a335b48bcbd1fd3d53a03e0d70f6661b4 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 28 Sep 2015 23:38:59 +0100 +Subject: [PATCH 099/113] irq-bcm2835: Fix building with 2708 -The following code run as root will cause a null pointer dereference oops: - - int fd = open("/dev/vc-cma", O_RDONLY); - if (fd < 0) - err(1, "open failed"); - (void)close(fd); - -[ 1704.877721] Unable to handle kernel NULL pointer dereference at virtual address 00000000 -[ 1704.877725] pgd = b899c000 -[ 1704.877736] [00000000] *pgd=37fab831, *pte=00000000, *ppte=00000000 -[ 1704.877748] Internal error: Oops: 817 [#1] PREEMPT SMP ARM -[ 1704.877765] Modules linked in: evdev i2c_bcm2708 uio_pdrv_genirq uio -[ 1704.877774] CPU: 2 PID: 3656 Comm: stress-ng-fstat Not tainted 3.19.1-12-generic-bcm2709 #12-Ubuntu -[ 1704.877777] Hardware name: BCM2709 -[ 1704.877783] task: b8ab9b00 ti: b7e68000 task.ti: b7e68000 -[ 1704.877798] PC is at __down_interruptible+0x50/0xec -[ 1704.877806] LR is at down_interruptible+0x5c/0x68 -[ 1704.877813] pc : [<80630ee8>] lr : [<800704b0>] psr: 60080093 -sp : b7e69e50 ip : b7e69e88 fp : b7e69e84 -[ 1704.877817] r10: b88123c8 r9 : 00000010 r8 : 00000001 -[ 1704.877822] r7 : b8ab9b00 r6 : 7fffffff r5 : 80a1cc34 r4 : 80a1cc34 -[ 1704.877826] r3 : b7e69e50 r2 : 00000000 r1 : 00000000 r0 : 80a1cc34 -[ 1704.877833] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user -[ 1704.877838] Control: 10c5387d Table: 3899c06a DAC: 00000015 -[ 1704.877843] Process do-oops (pid: 3656, stack limit = 0xb7e68238) -[ 1704.877848] Stack: (0xb7e69e50 to 0xb7e6a000) -[ 1704.877856] 9e40: 80a1cc3c 00000000 00000010 b88123c8 -[ 1704.877865] 9e60: b7e69e84 80a1cc34 fff9fee9 ffffffff b7e68000 00000009 b7e69ea4 b7e69e88 -[ 1704.877874] 9e80: 800704b0 80630ea4 fff9fee9 60080013 80a1cc28 fff9fee9 b7e69edc b7e69ea8 -[ 1704.877884] 9ea0: 8040f558 80070460 fff9fee9 ffffffff 00000000 00000000 00000009 80a1cb7c -[ 1704.877893] 9ec0: 00000000 80a1cb7c 00000000 00000010 b7e69ef4 b7e69ee0 803e1ba4 8040f514 -[ 1704.877902] 9ee0: 00000e48 80a1cb7c b7e69f14 b7e69ef8 803e1c9c 803e1b74 b88123c0 b92acb18 -[ 1704.877911] 9f00: b8812790 b8d815d8 b7e69f24 b7e69f18 803e2250 803e1bc8 b7e69f5c b7e69f28 -[ 1704.877921] 9f20: 80167bac 803e222c 00000000 00000000 b7e69f54 b8ab9ffc 00000000 8098c794 -[ 1704.877930] 9f40: b8ab9b00 8000efc4 b7e68000 00000000 b7e69f6c b7e69f60 80167d6c 80167b28 -[ 1704.877939] 9f60: b7e69f8c b7e69f70 80047d38 80167d60 b7e68000 b7e68010 8000efc4 b7e69fb0 -[ 1704.877949] 9f80: b7e69fac b7e69f90 80012820 80047c84 01155490 011549a8 00000001 00000006 -[ 1704.877957] 9fa0: 00000000 b7e69fb0 8000ee5c 80012790 00000000 353d8c0f 7efc4308 00000000 -[ 1704.877966] 9fc0: 01155490 011549a8 00000001 00000006 00000000 00000000 76cf3ba0 00000003 -[ 1704.877975] 9fe0: 00000000 7efc42e4 0002272f 76e2ed66 60080030 00000003 00000000 00000000 -[ 1704.877998] [<80630ee8>] (__down_interruptible) from [<800704b0>] (down_interruptible+0x5c/0x68) -[ 1704.878015] [<800704b0>] (down_interruptible) from [<8040f558>] (vchiu_queue_push+0x50/0xd8) -[ 1704.878032] [<8040f558>] (vchiu_queue_push) from [<803e1ba4>] (send_worker_msg+0x3c/0x54) -[ 1704.878045] [<803e1ba4>] (send_worker_msg) from [<803e1c9c>] (vc_cma_set_reserve+0xe0/0x1c4) -[ 1704.878057] [<803e1c9c>] (vc_cma_set_reserve) from [<803e2250>] (vc_cma_release+0x30/0x38) -[ 1704.878069] [<803e2250>] (vc_cma_release) from [<80167bac>] (__fput+0x90/0x1e0) -[ 1704.878082] [<80167bac>] (__fput) from [<80167d6c>] (____fput+0x18/0x1c) -[ 1704.878094] [<80167d6c>] (____fput) from [<80047d38>] (task_work_run+0xc0/0xf8) -[ 1704.878109] [<80047d38>] (task_work_run) from [<80012820>] (do_work_pending+0x9c/0xc4) -[ 1704.878123] [<80012820>] (do_work_pending) from [<8000ee5c>] (work_pending+0xc/0x20) -[ 1704.878133] Code: e50b1034 e3a01000 e50b2030 e580300c (e5823000) - -..the fix is to ensure that we have actually initialized the queue before we attempt -to push any items onto it. This occurs if we do an open() followed by a close() without -any activity in between. - -Signed-off-by: Colin Ian King --- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c | 4 ++++ - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h | 1 + - 2 files changed, 5 insertions(+) + drivers/irqchip/irq-bcm2835.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -index 05e7979..384acb8 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -@@ -46,6 +46,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size) - queue->size = size; - queue->read = 0; - queue->write = 0; -+ queue->initialized = 1; +diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c +index 3f601f9..3478e75 100644 +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -77,6 +77,7 @@ + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 + #define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) ++#undef FIQ_START + #define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) - sema_init(&queue->pop, 0); - sema_init(&queue->push, 0); -@@ -76,6 +77,9 @@ int vchiu_queue_is_full(VCHIU_QUEUE_T *queue) - - void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) - { -+ if (!queue->initialized) -+ return; -+ - while (queue->write == queue->read + queue->size) { - if (down_interruptible(&queue->pop) != 0) { - flush_signals(current); -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -index f4d0b66..4055d4b 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -@@ -60,6 +60,7 @@ typedef struct { - int size; - int read; - int write; -+ int initialized; - - struct semaphore pop; - struct semaphore push; - -From 2c90639076be957e3e5eb9f44e0c09719db83f7e Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:13:17 -0400 -Subject: [PATCH 173/204] bcm2708_fb: remove redundant code as detected by - static analysis - -static analysis with cppcheck detected some redundant code which -should probably be removed: - -[drivers/video/fbdev/bcm2708_fb.c:269]: (style) Variable 'yres' - is assigned a value that is never used. - -Signed-off-by: Colin Ian King ---- - drivers/video/fbdev/bcm2708_fb.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 06a96d16..fed0672 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -263,12 +263,6 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, - if (var->yoffset > var->yres_virtual - var->yres) - var->yoffset = var->yres_virtual - var->yres - 1; - -- yres = var->yres; -- if (var->vmode & FB_VMODE_DOUBLE) -- yres *= 2; -- else if (var->vmode & FB_VMODE_INTERLACED) -- yres = (yres + 1) / 2; -- - return 0; - } - - -From 473b4d43abe530f11f07dbdd9be666a90d75313c Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:15:38 -0400 -Subject: [PATCH 174/204] bcm2708_fb: remove unnecessary initialization of - result - -static analysis by cppcheck detected an unnecessary initialization -of variable 'result' which is re-assigned almost immediately after -the initialization. Remove the redundant initialization. - -[drivers/video/fbdev/bcm2708_fb.c:406]: (performance) Variable - 'result' is reassigned a value before the old one has been used. - -Signed-off-by: Colin Ian King ---- - drivers/video/fbdev/bcm2708_fb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index fed0672..0f62d76 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -420,7 +420,7 @@ static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) - - static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) - { -- s32 result = -1; -+ s32 result; - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - result = bcm2708_fb_set_par(info); - -From 94946643df81ee3acaeed9a5e0eb8944ab8492fe Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:27:36 -0400 -Subject: [PATCH 175/204] vcsm: increment res_stats MAP_FAIL stats before we - potentially release the resource - -resource can be kfree'd when the reference count is zero, so we should -not bump the res_stats of the resource after the vmcs_sm_release_resource -call since the resource may have been kfree'd by this call. Instead, bump -the stats before we call vmcs_sm_release_resource to avoid a potential -NULL pointer derefernce. - -Bug found using cppcheck static analysis: - -[drivers/char/broadcom/vc_sm/vmcs_sm.c:1373]: (error) Dereferencing - 'resource' after it is deallocated / released - -Signed-off-by: Colin Ian King ---- - drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index 0bfb42e..b62a3b2 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -1368,8 +1368,8 @@ static int vc_sm_mmap(struct file *file, struct vm_area_struct *vma) - return 0; - - error: -- vmcs_sm_release_resource(resource, 0); - resource->res_stats[MAP_FAIL]++; -+ vmcs_sm_release_resource(resource, 0); - return ret; - } - - -From 874c6177f126c4fdb31ed9234fe053581ff632fb Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:33:39 -0400 -Subject: [PATCH 176/204] bcm2835: camera: check for scene not being found - -static analysis by cppcheck detected some potential NULL pointer -dereference issues: - -[drivers/media/platform/bcm2835/controls.c:854]: (error) Possible null - pointer dereference: scene - (and lines 858, 859 too) - -it is possible that scene is not found because of an invalue ctrl->val -and is therefore NULL and hence causing a null pointer dereference. - -Signed-off-by: Colin Ian King ---- - drivers/media/platform/bcm2835/controls.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c -index 3017b94..f9f903f 100644 ---- a/drivers/media/platform/bcm2835/controls.c -+++ b/drivers/media/platform/bcm2835/controls.c -@@ -845,6 +845,8 @@ static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev, - break; - } + static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; +@@ -218,7 +219,7 @@ static int __init armctrl_of_init(struct device_node *node, + MAKE_HWIRQ(b, i) + NUMBER_IRQS); + BUG_ON(irq <= 0); + irq_set_chip(irq, &armctrl_chip); +- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); } -+ if (!scene) -+ return -EINVAL; - if (i >= ARRAY_SIZE(scene_configs)) - return -EINVAL; - + } + init_FIQ(FIQ_START); -From a255eb898f2ff3d63de6dbc201797ff732499dca Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:47:51 -0400 -Subject: [PATCH 177/204] bcm2835: memcpy port data to m rather than rmsg - -static analysis by cppcheck detected a memcpy to rmsg which is -not actually initialized at that point. The memcpy should be copying -to variable m instead. - -Signed-off-by: Colin Ian King ---- - drivers/media/platform/bcm2835/mmal-vchiq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c -index 76f249e..7813225 100644 ---- a/drivers/media/platform/bcm2835/mmal-vchiq.c -+++ b/drivers/media/platform/bcm2835/mmal-vchiq.c -@@ -851,7 +851,7 @@ static int port_info_set(struct vchiq_mmal_instance *instance, - sizeof(union mmal_es_specific_format)); - - m.u.port_info_set.format.extradata_size = port->format.extradata_size; -- memcpy(rmsg->u.port_info_set.extradata, port->format.extradata, -+ memcpy(&m.u.port_info_set.extradata, port->format.extradata, - port->format.extradata_size); - - ret = send_synchronous_mmal_msg(instance, &m, - -From bd4d78dcb66955bc2ea1c81232db499e1f662ac6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 13 Sep 2015 15:54:28 +0200 -Subject: [PATCH 178/204] Revert "BCM270X_DT: mz61581: Revert to spi-bcm2708" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 1820cd05d93b2d465d1616202772efe5bf0d11fe. - -The spi-bcm2835 driver has been fixed, so now we can use it again. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index f674a66..c06fe12 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -12,8 +12,6 @@ - fragment@0 { - target = <&spi0>; - __overlay__ { -- /* does not work with spi-bcm2835 using software chip selects */ -- compatible = "brcm,bcm2708-spi"; - status = "okay"; - - spidev@0{ - -From 63103cf8b12f79c02f1a6d7a851fbb6727528d33 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 13 Sep 2015 17:17:14 +0200 -Subject: [PATCH 179/204] BCM270X_DT: mz61581: Set txbuflen to 32k -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Because of the spi dma mapping/engine overhead with spi-bcm2835, -txbuflen has to be increased from 4096 to 32768 to maximize -throughput (11MB/s at 128MHz). - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index a749ff7..0aa5aa1 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -368,6 +368,8 @@ Params: speed Display SPI bus speed - - fps Delay between frame updates - -+ txbuflen Transmit buffer length (default 32768) -+ - debug Debug output level {0-7} - - xohms Touchpanel sensitivity (X-plate resistance) -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index c06fe12..9242a6e 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -57,6 +57,7 @@ - bgr; - fps = <30>; - buswidth = <8>; -+ txbuflen = <32768>; - - reset-gpios = <&gpio 15 0>; - dc-gpios = <&gpio 25 0>; -@@ -103,6 +104,7 @@ - speed = <&mz61581>, "spi-max-frequency:0"; - rotate = <&mz61581>, "rotate:0"; - fps = <&mz61581>, "fps:0"; -+ txbuflen = <&mz61581>, "txbuflen:0"; - debug = <&mz61581>, "debug:0"; - xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; - }; - -From 6881996989b77354049455c95e8af67f278cfa48 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 11 Sep 2015 12:10:15 +0100 -Subject: [PATCH 180/204] bcm2835-mmc: Don't overwrite MMC capabilities from DT +From a7362ad916d411d3a9df4af0a8261a1baea83f80 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 30 Sep 2015 13:58:30 +0100 +Subject: [PATCH 100/113] dwc_otg: Remove duplicate gadget probe/unregister + function --- - drivers/mmc/host/bcm2835-mmc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) + drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 84 +--------------------------- + 1 file changed, 2 insertions(+), 82 deletions(-) -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index b7c4883..164bfad 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1327,8 +1327,9 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; - #endif - /* host controller capabilities */ -- mmc->caps = MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ | -- MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; -+ mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | -+ MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | -+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; - - host->flags = SDHCI_AUTO_CMD23; - - -From 7bbc4815e21230a8a011d3f3cf794d765cdacb35 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 11 Sep 2015 09:14:01 +0100 -Subject: [PATCH 181/204] BCM270X_DT: Use fixed-factor-clock for uart1 - -The BCM2835 mini-UART is almost 8250-compatible, but there is -a factor-of-two difference in the clock divider for the baud rate. -The standard 8250 driver can be used unmodified provided we lie to it -about the clock frequency, pretending it is double the actual value. -The mini-UART block shares the core clock, and the current firmware -uses a DT-parameter to update the clock-frequency property. Although it -works, this isn't ideal because it exposes the firmware to a driver -problem. - -This patch uses the fixed-factor-clock module to create a clock that is -always twice the frequency of the core clock. (N.B. These "fixed" clocks -just describe an existing clock, rather than changing any hardware -settings.) ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 - - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 - - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 - - arch/arm/boot/dts/bcm2708_common.dtsi | 10 +++++++++- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 - - 5 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 3ad2e0d..e3ae8e6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -103,7 +103,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e2b1491..2adc248 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -97,7 +97,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 96d8b97..bddc369 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -79,7 +79,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index f096f45..4d1cc67 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -165,7 +165,7 @@ - compatible = "brcm,bcm2835-aux-uart", "ns16550"; - reg = <0x7e215040 0x40>; - interrupts = <1 29>; -- clock-frequency = <500000000>; -+ clocks = <&clk_uart1>; - reg-shift = <2>; - no-loopback-test; - status = "disabled"; -@@ -294,6 +294,14 @@ - clock-output-names = "pwm"; - clock-frequency = <100000000>; - }; -+ -+ clk_uart1: clock@6 { -+ compatible = "fixed-factor-clock"; -+ clocks = <&clk_core>; -+ #clock-cells = <0>; -+ clock-div = <1>; -+ clock-mult = <2>; -+ }; - }; - - __overrides__ { -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index f25f0a2..76d44a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -103,7 +103,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - -From d851a069d33dba42c5c7fa023ee13f994643fa90 Mon Sep 17 00:00:00 2001 -From: Luke Wren -Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 182/204] Add SMI driver - -Signed-off-by: Luke Wren ---- - .../bindings/misc/brcm,bcm2835-smi-dev.txt | 17 + - .../devicetree/bindings/misc/brcm,bcm2835-smi.txt | 48 + - arch/arm/boot/dts/bcm2708_common.dtsi | 11 + - arch/arm/boot/dts/overlays/Makefile | 2 + - arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + - arch/arm/boot/dts/overlays/smi-overlay.dts | 37 + - drivers/char/broadcom/Kconfig | 8 + - drivers/char/broadcom/Makefile | 2 +- - drivers/char/broadcom/bcm2835_smi_dev.c | 402 +++++++++ - drivers/misc/Kconfig | 8 + - drivers/misc/Makefile | 1 + - drivers/misc/bcm2835_smi.c | 985 +++++++++++++++++++++ - include/linux/broadcom/bcm2835_smi.h | 391 ++++++++ - 13 files changed, 1929 insertions(+), 1 deletion(-) - create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt - create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt - create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts - create mode 100644 drivers/char/broadcom/bcm2835_smi_dev.c - create mode 100644 drivers/misc/bcm2835_smi.c - create mode 100644 include/linux/broadcom/bcm2835_smi.h - -diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt -new file mode 100644 -index 0000000..68cc8eb ---- /dev/null -+++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt -@@ -0,0 +1,17 @@ -+* Broadcom BCM2835 SMI character device driver. -+ -+SMI or secondary memory interface is a peripheral specific to certain Broadcom -+SOCs, and is helpful for talking to things like parallel-interface displays -+and NAND flashes (in fact, most things with a parallel register interface). -+ -+This driver adds a character device which provides a user-space interface to -+an instance of the SMI driver. -+ -+Required properties: -+- compatible: "brcm,bcm2835-smi-dev" -+- smi_handle: a phandle to the smi node. -+ -+Optional properties: -+- None. -+ -+ -diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt -new file mode 100644 -index 0000000..b76dc69 ---- /dev/null -+++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt -@@ -0,0 +1,48 @@ -+* Broadcom BCM2835 SMI driver. -+ -+SMI or secondary memory interface is a peripheral specific to certain Broadcom -+SOCs, and is helpful for talking to things like parallel-interface displays -+and NAND flashes (in fact, most things with a parallel register interface). -+ -+Required properties: -+- compatible: "brcm,bcm2835-smi" -+- reg: Should contain location and length of SMI registers and SMI clkman regs -+- interrupts: *the* SMI interrupt. -+- pinctrl-names: should be "default". -+- pinctrl-0: the phandle of the gpio pin node. -+- brcm,smi-clock-source: the clock source for clkman -+- brcm,smi-clock-divisor: the integer clock divisor for clkman -+- dmas: the dma controller phandle and the DREQ number (4 on a 2835) -+- dma-names: the name used by the driver to request its channel. -+ Should be "rx-tx". -+ -+Optional properties: -+- None. -+ -+Examples: -+ -+8 data pin configuration: -+ -+smi: smi@7e600000 { -+ compatible = "brcm,bcm2835-smi"; -+ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; -+ interrupts = <2 16>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&smi_pins>; -+ brcm,smi-clock-source = <6>; -+ brcm,smi-clock-divisor = <4>; -+ dmas = <&dma 4>; -+ dma-names = "rx-tx"; -+ -+ status = "okay"; -+}; -+ -+smi_pins: smi_pins { -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15>; -+ /* Alt 1: SMI */ -+ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>; -+ /* /CS, /WE and /OE are pulled high, as they are -+ generally active low signals */ -+ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0>; -+}; -+ -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4d1cc67..933711e 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -205,6 +205,17 @@ - status = "disabled"; - }; - -+ smi: smi@7e600000 { -+ compatible = "brcm,bcm2835-smi"; -+ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; -+ interrupts = <2 16>; -+ brcm,smi-clock-source = <6>; -+ brcm,smi-clock-divisor = <4>; -+ dmas = <&dma 4>; -+ dma-names = "rx-tx"; -+ status = "disabled"; -+ }; -+ - usb: usb@7e980000 { - compatible = "brcm,bcm2708-usb"; - reg = <0x7e980000 0x10000>, -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 43e9c96..f8f2c034 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,8 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/smi-dev-overlay.dts b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts -new file mode 100644 -index 0000000..b610d82 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts -@@ -0,0 +1,18 @@ -+// Description: Overlay to enable character device interface for SMI. -+// Author: Luke Wren -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ fragment@0 { -+ target = <&soc>; -+ __overlay__ { -+ smi_dev { -+ compatible = "brcm,bcm2835-smi-dev"; -+ smi_handle = <&smi>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/smi-overlay.dts b/arch/arm/boot/dts/overlays/smi-overlay.dts -new file mode 100644 -index 0000000..095f52c ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/smi-overlay.dts -@@ -0,0 +1,37 @@ -+// Description: Overlay to enable the secondary memory interface peripheral -+// Author: Luke Wren -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&smi>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&smi_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ smi_pins: smi_pins { -+ /* Don't configure the top two address bits, as -+ these are already used as ID_SD and ID_SC */ -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 -+ 16 17 18 19 20 21 22 23 24 25>; -+ /* Alt 0: SMI */ -+ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 -+ 5 5 5 5 5 5 5 5 5>; -+ /* /CS, /WE and /OE are pulled high, as they are -+ generally active low signals */ -+ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 -+ 0 0 0 0 0 0 0>; -+ }; -+ }; -+ }; -+}; -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index bc2eb1e..5489f19 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -47,3 +47,11 @@ config BCM2835_DEVGPIOMEM - on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO - register page to the user's pointer. - -+config BCM2835_SMI_DEV -+ tristate "Character device driver for BCM2835 Secondary Memory Interface" -+ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI -+ default m -+ help -+ This driver provides a character device interface (ioctl + read/write) to -+ Broadcom's Secondary Memory interface. The low-level functionality is provided -+ by the SMI driver itself. -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 664e2c4..14775c9 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -4,4 +4,4 @@ obj-$(CONFIG_BCM_VCIO) += vcio.o - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ - - obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o -- -+obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o -diff --git a/drivers/char/broadcom/bcm2835_smi_dev.c b/drivers/char/broadcom/bcm2835_smi_dev.c -new file mode 100644 -index 0000000..d6efd92 ---- /dev/null -+++ b/drivers/char/broadcom/bcm2835_smi_dev.c -@@ -0,0 +1,402 @@ -+/** -+ * Character device driver for Broadcom Secondary Memory Interface -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DEVICE_NAME "bcm2835-smi-dev" -+#define DRIVER_NAME "smi-dev-bcm2835" -+#define DEVICE_MINOR 0 -+ -+static struct cdev bcm2835_smi_cdev; -+static dev_t bcm2835_smi_devid; -+static struct class *bcm2835_smi_class; -+static struct device *bcm2835_smi_dev; -+ -+struct bcm2835_smi_dev_instance { -+ struct device *dev; -+}; -+ -+static struct bcm2835_smi_instance *smi_inst; -+static struct bcm2835_smi_dev_instance *inst; -+ -+static const char *const ioctl_names[] = { -+ "READ_SETTINGS", -+ "WRITE_SETTINGS", -+ "ADDRESS" -+}; -+ -+/**************************************************************************** -+* -+* SMI chardev file ops -+* -+***************************************************************************/ -+static long -+bcm2835_smi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long ret = 0; -+ -+ dev_info(inst->dev, "serving ioctl..."); -+ -+ switch (cmd) { -+ case BCM2835_SMI_IOC_GET_SETTINGS:{ -+ struct smi_settings *settings; -+ -+ dev_info(inst->dev, "Reading SMI settings to user."); -+ settings = bcm2835_smi_get_settings_from_regs(smi_inst); -+ if (copy_to_user((void *)arg, settings, -+ sizeof(struct smi_settings))) -+ dev_err(inst->dev, "settings copy failed."); -+ break; -+ } -+ case BCM2835_SMI_IOC_WRITE_SETTINGS:{ -+ struct smi_settings *settings; -+ -+ dev_info(inst->dev, "Setting user's SMI settings."); -+ settings = bcm2835_smi_get_settings_from_regs(smi_inst); -+ if (copy_from_user(settings, (void *)arg, -+ sizeof(struct smi_settings))) -+ dev_err(inst->dev, "settings copy failed."); -+ else -+ bcm2835_smi_set_regs_from_settings(smi_inst); -+ break; -+ } -+ case BCM2835_SMI_IOC_ADDRESS: -+ dev_info(inst->dev, "SMI address set: 0x%02x", (int)arg); -+ bcm2835_smi_set_address(smi_inst, arg); -+ break; -+ default: -+ dev_err(inst->dev, "invalid ioctl cmd: %d", cmd); -+ ret = -ENOTTY; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int bcm2835_smi_open(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ -+ dev_dbg(inst->dev, "SMI device opened."); -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, -+ "bcm2835_smi_release: Unknown minor device: %d", -+ dev); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_smi_release(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, -+ "bcm2835_smi_release: Unknown minor device %d", dev); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ -+static ssize_t dma_bounce_user( -+ enum dma_transfer_direction dma_dir, -+ char __user *user_ptr, -+ size_t count, -+ struct bcm2835_smi_bounce_info *bounce) -+{ -+ int chunk_size; -+ int chunk_no = 0; -+ int count_left = count; -+ -+ while (count_left) { -+ int rv; -+ void *buf; -+ -+ /* Wait for current chunk to complete: */ -+ if (down_timeout(&bounce->callback_sem, -+ msecs_to_jiffies(1000))) { -+ dev_err(inst->dev, "DMA bounce timed out"); -+ count -= (count_left); -+ break; -+ } -+ -+ if (bounce->callback_sem.count >= DMA_BOUNCE_BUFFER_COUNT - 1) -+ dev_err(inst->dev, "WARNING: Ring buffer overflow"); -+ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? -+ DMA_BOUNCE_BUFFER_SIZE : count_left; -+ buf = bounce->buffer[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; -+ if (dma_dir == DMA_DEV_TO_MEM) -+ rv = copy_to_user(user_ptr, buf, chunk_size); -+ else -+ rv = copy_from_user(buf, user_ptr, chunk_size); -+ if (rv) -+ dev_err(inst->dev, "copy_*_user() failed!: %d", rv); -+ user_ptr += chunk_size; -+ count_left -= chunk_size; -+ chunk_no++; -+ } -+ return count; -+} -+ -+static ssize_t -+bcm2835_read_file(struct file *f, char __user *user_ptr, -+ size_t count, loff_t *offs) -+{ -+ int odd_bytes; -+ -+ dev_dbg(inst->dev, "User reading %d bytes from SMI.", count); -+ /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */ -+ if (count > DMA_THRESHOLD_BYTES) -+ odd_bytes = count & 0x3; -+ else -+ odd_bytes = count; -+ count -= odd_bytes; -+ if (count) { -+ struct bcm2835_smi_bounce_info *bounce; -+ -+ count = bcm2835_smi_user_dma(smi_inst, -+ DMA_DEV_TO_MEM, user_ptr, count, -+ &bounce); -+ if (count) -+ count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr, -+ count, bounce); -+ } -+ if (odd_bytes) { -+ /* Read from FIFO directly if not using DMA */ -+ uint8_t buf[DMA_THRESHOLD_BYTES]; -+ -+ bcm2835_smi_read_buf(smi_inst, buf, odd_bytes); -+ if (copy_to_user(user_ptr, buf, odd_bytes)) -+ dev_err(inst->dev, "copy_to_user() failed."); -+ count += odd_bytes; -+ -+ } -+ return count; -+} -+ -+static ssize_t -+bcm2835_write_file(struct file *f, const char __user *user_ptr, -+ size_t count, loff_t *offs) -+{ -+ int odd_bytes; -+ -+ dev_dbg(inst->dev, "User writing %d bytes to SMI.", count); -+ if (count > DMA_THRESHOLD_BYTES) -+ odd_bytes = count & 0x3; -+ else -+ odd_bytes = count; -+ count -= odd_bytes; -+ if (count) { -+ struct bcm2835_smi_bounce_info *bounce; -+ -+ count = bcm2835_smi_user_dma(smi_inst, -+ DMA_MEM_TO_DEV, (char __user *)user_ptr, count, -+ &bounce); -+ if (count) -+ count = dma_bounce_user(DMA_MEM_TO_DEV, -+ (char __user *)user_ptr, -+ count, bounce); -+ } -+ if (odd_bytes) { -+ uint8_t buf[DMA_THRESHOLD_BYTES]; -+ -+ if (copy_from_user(buf, user_ptr, odd_bytes)) -+ dev_err(inst->dev, "copy_from_user() failed."); -+ else -+ bcm2835_smi_write_buf(smi_inst, buf, odd_bytes); -+ count += odd_bytes; -+ } -+ return count; -+} -+ -+static const struct file_operations -+bcm2835_smi_fops = { -+ .owner = THIS_MODULE, -+ .unlocked_ioctl = bcm2835_smi_ioctl, -+ .open = bcm2835_smi_open, -+ .release = bcm2835_smi_release, -+ .read = bcm2835_read_file, -+ .write = bcm2835_write_file, -+}; -+ -+ -+/**************************************************************************** -+* -+* bcm2835_smi_probe - called when the driver is loaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_dev_probe(struct platform_device *pdev) -+{ -+ int err; -+ void *ptr_err; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node, *smi_node; -+ -+ if (!node) { -+ dev_err(dev, "No device tree node supplied!"); -+ return -EINVAL; -+ } -+ -+ smi_node = of_parse_phandle(node, "smi_handle", 0); -+ -+ if (!smi_node) { -+ dev_err(dev, "No such property: smi_handle"); -+ return -ENXIO; -+ } -+ -+ smi_inst = bcm2835_smi_get(smi_node); -+ -+ if (!smi_inst) -+ return -EPROBE_DEFER; -+ -+ /* Allocate buffers and instance data */ -+ -+ inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL); -+ -+ if (!inst) -+ return -ENOMEM; -+ -+ inst->dev = dev; -+ -+ /* Create character device entries */ -+ -+ err = alloc_chrdev_region(&bcm2835_smi_devid, -+ DEVICE_MINOR, 1, DEVICE_NAME); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to allocate device number"); -+ return -ENOMEM; -+ } -+ cdev_init(&bcm2835_smi_cdev, &bcm2835_smi_fops); -+ bcm2835_smi_cdev.owner = THIS_MODULE; -+ err = cdev_add(&bcm2835_smi_cdev, bcm2835_smi_devid, 1); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to register device"); -+ err = -ENOMEM; -+ goto failed_cdev_add; -+ } -+ -+ /* Create sysfs entries */ -+ -+ bcm2835_smi_class = class_create(THIS_MODULE, DEVICE_NAME); -+ ptr_err = bcm2835_smi_class; -+ if (IS_ERR(ptr_err)) -+ goto failed_class_create; -+ -+ bcm2835_smi_dev = device_create(bcm2835_smi_class, NULL, -+ bcm2835_smi_devid, NULL, -+ "smi"); -+ ptr_err = bcm2835_smi_dev; -+ if (IS_ERR(ptr_err)) -+ goto failed_device_create; -+ -+ dev_info(inst->dev, "initialised"); -+ -+ return 0; -+ -+failed_device_create: -+ class_destroy(bcm2835_smi_class); -+failed_class_create: -+ cdev_del(&bcm2835_smi_cdev); -+ err = PTR_ERR(ptr_err); -+failed_cdev_add: -+ unregister_chrdev_region(bcm2835_smi_devid, 1); -+ dev_err(dev, "could not load bcm2835_smi_dev"); -+ return err; -+} -+ -+/**************************************************************************** -+* -+* bcm2835_smi_remove - called when the driver is unloaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_dev_remove(struct platform_device *pdev) -+{ -+ device_destroy(bcm2835_smi_class, bcm2835_smi_devid); -+ class_destroy(bcm2835_smi_class); -+ cdev_del(&bcm2835_smi_cdev); -+ unregister_chrdev_region(bcm2835_smi_devid, 1); -+ -+ dev_info(inst->dev, "SMI character dev removed - OK"); -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_smi_dev_of_match[] = { -+ {.compatible = "brcm,bcm2835-smi-dev",}, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_smi_dev_of_match); -+ -+static struct platform_driver bcm2835_smi_dev_driver = { -+ .probe = bcm2835_smi_dev_probe, -+ .remove = bcm2835_smi_dev_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_smi_dev_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_smi_dev_driver); -+ -+MODULE_ALIAS("platform:smi-dev-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION( -+ "Character device driver for BCM2835's secondary memory interface"); -+MODULE_AUTHOR("Luke Wren "); -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 4e6f46c3..8b82c9b 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D - select INPUT_POLLDEV - default n - -+config BCM2835_SMI -+ tristate "Broadcom 283x Secondary Memory Interface driver" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ default m -+ help -+ Driver for enabling and using Broadcom's Secondary/Slow Memory Interface. -+ Appears as /dev/bcm2835_smi. For ioctl interface see drivers/misc/bcm2835_smi.h -+ - config AD525X_DPOT - tristate "Analog Devices Digital Potentiometers" - depends on (I2C || SPI) && SYSFS -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 43d2ac9..b668a08 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o - obj-$(CONFIG_INTEL_MID_PTI) += pti.o - obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o - obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o -+obj-$(CONFIG_BCM2835_SMI) += bcm2835_smi.o - obj-$(CONFIG_BMP085) += bmp085.o - obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o - obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o -diff --git a/drivers/misc/bcm2835_smi.c b/drivers/misc/bcm2835_smi.c -new file mode 100644 -index 0000000..63a4ea0 ---- /dev/null -+++ b/drivers/misc/bcm2835_smi.c -@@ -0,0 +1,985 @@ -+/** -+ * Broadcom Secondary Memory Interface driver -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BCM2835_SMI_IMPLEMENTATION -+#include -+ -+#define DRIVER_NAME "smi-bcm2835" -+ -+#define N_PAGES_FROM_BYTES(n) ((n + PAGE_SIZE-1) / PAGE_SIZE) -+ -+#define DMA_WRITE_TO_MEM true -+#define DMA_READ_FROM_MEM false -+ -+struct bcm2835_smi_instance { -+ struct device *dev; -+ struct smi_settings settings; -+ __iomem void *smi_regs_ptr, *cm_smi_regs_ptr; -+ dma_addr_t smi_regs_busaddr; -+ -+ struct dma_chan *dma_chan; -+ struct dma_slave_config dma_config; -+ -+ struct bcm2835_smi_bounce_info bounce; -+ -+ struct scatterlist buffer_sgl; -+ -+ int clock_source; -+ int clock_divisor; -+ -+ /* Sometimes we are called into in an atomic context (e.g. by -+ JFFS2 + MTD) so we can't use a mutex */ -+ spinlock_t transaction_lock; -+}; -+ -+/**************************************************************************** -+* -+* SMI clock manager setup -+* -+***************************************************************************/ -+ -+static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst, -+ u32 val, unsigned reg) -+{ -+ writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg); -+} -+ -+static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst, -+ unsigned reg) -+{ -+ return readl(inst->cm_smi_regs_ptr + reg); -+} -+ -+static void smi_setup_clock(struct bcm2835_smi_instance *inst) -+{ -+ dev_dbg(inst->dev, "Setting up clock..."); -+ /* Disable SMI clock and wait for it to stop. */ -+ write_smi_cm_reg(inst, 0, CM_SMI_CTL); -+ while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY) -+ ; -+ -+ write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS), -+ CM_SMI_DIV); -+ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS), -+ CM_SMI_CTL); -+ -+ /* Enable the clock */ -+ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) | -+ CM_SMI_CTL_ENAB, CM_SMI_CTL); -+} -+ -+/**************************************************************************** -+* -+* SMI peripheral setup -+* -+***************************************************************************/ -+ -+static inline void write_smi_reg(struct bcm2835_smi_instance *inst, -+ u32 val, unsigned reg) -+{ -+ writel(val, inst->smi_regs_ptr + reg); -+} -+ -+static inline u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg) -+{ -+ return readl(inst->smi_regs_ptr + reg); -+} -+ -+/* Token-paste macro for e.g SMIDSR_RSTROBE -> value of SMIDSR_RSTROBE_MASK */ -+#define _CONCAT(x, y) x##y -+#define CONCAT(x, y) _CONCAT(x, y) -+ -+#define SET_BIT_FIELD(dest, field, bits) ((dest) = \ -+ ((dest) & ~CONCAT(field, _MASK)) | (((bits) << CONCAT(field, _OFFS))& \ -+ CONCAT(field, _MASK))) -+#define GET_BIT_FIELD(src, field) (((src) & \ -+ CONCAT(field, _MASK)) >> CONCAT(field, _OFFS)) -+ -+static void smi_dump_context_labelled(struct bcm2835_smi_instance *inst, -+ const char *label) -+{ -+ dev_err(inst->dev, "SMI context dump: %s", label); -+ dev_err(inst->dev, "SMICS: 0x%08x", read_smi_reg(inst, SMICS)); -+ dev_err(inst->dev, "SMIL: 0x%08x", read_smi_reg(inst, SMIL)); -+ dev_err(inst->dev, "SMIDSR: 0x%08x", read_smi_reg(inst, SMIDSR0)); -+ dev_err(inst->dev, "SMIDSW: 0x%08x", read_smi_reg(inst, SMIDSW0)); -+ dev_err(inst->dev, "SMIDC: 0x%08x", read_smi_reg(inst, SMIDC)); -+ dev_err(inst->dev, "SMIFD: 0x%08x", read_smi_reg(inst, SMIFD)); -+ dev_err(inst->dev, " "); -+} -+ -+static inline void smi_dump_context(struct bcm2835_smi_instance *inst) -+{ -+ smi_dump_context_labelled(inst, ""); -+} -+ -+static void smi_get_default_settings(struct bcm2835_smi_instance *inst) -+{ -+ struct smi_settings *settings = &inst->settings; -+ -+ settings->data_width = SMI_WIDTH_16BIT; -+ settings->pack_data = true; -+ -+ settings->read_setup_time = 1; -+ settings->read_hold_time = 1; -+ settings->read_pace_time = 1; -+ settings->read_strobe_time = 3; -+ -+ settings->write_setup_time = settings->read_setup_time; -+ settings->write_hold_time = settings->read_hold_time; -+ settings->write_pace_time = settings->read_pace_time; -+ settings->write_strobe_time = settings->read_strobe_time; -+ -+ settings->dma_enable = true; -+ settings->dma_passthrough_enable = false; -+ settings->dma_read_thresh = 0x01; -+ settings->dma_write_thresh = 0x3f; -+ settings->dma_panic_read_thresh = 0x20; -+ settings->dma_panic_write_thresh = 0x20; -+} -+ -+void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst) -+{ -+ struct smi_settings *settings = &inst->settings; -+ int smidsr_temp = 0, smidsw_temp = 0, smics_temp, -+ smidcs_temp, smidc_temp = 0; -+ -+ spin_lock(&inst->transaction_lock); -+ -+ /* temporarily disable the peripheral: */ -+ smics_temp = read_smi_reg(inst, SMICS); -+ write_smi_reg(inst, 0, SMICS); -+ smidcs_temp = read_smi_reg(inst, SMIDCS); -+ write_smi_reg(inst, 0, SMIDCS); -+ -+ if (settings->pack_data) -+ smics_temp |= SMICS_PXLDAT; -+ else -+ smics_temp &= ~SMICS_PXLDAT; -+ -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time); -+ write_smi_reg(inst, smidsr_temp, SMIDSR0); -+ -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width); -+ if (settings->data_width == SMI_WIDTH_8BIT) -+ smidsw_temp |= SMIDSW_WSWAP; -+ else -+ smidsw_temp &= ~SMIDSW_WSWAP; -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time); -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time); -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time); -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE, -+ settings->write_strobe_time); -+ write_smi_reg(inst, smidsw_temp, SMIDSW0); -+ -+ SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh); -+ SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh); -+ SET_BIT_FIELD(smidc_temp, SMIDC_PANICR, -+ settings->dma_panic_read_thresh); -+ SET_BIT_FIELD(smidc_temp, SMIDC_PANICW, -+ settings->dma_panic_write_thresh); -+ if (settings->dma_passthrough_enable) { -+ smidc_temp |= SMIDC_DMAP; -+ smidsr_temp |= SMIDSR_RDREQ; -+ write_smi_reg(inst, smidsr_temp, SMIDSR0); -+ smidsw_temp |= SMIDSW_WDREQ; -+ write_smi_reg(inst, smidsw_temp, SMIDSW0); -+ } else -+ smidc_temp &= ~SMIDC_DMAP; -+ if (settings->dma_enable) -+ smidc_temp |= SMIDC_DMAEN; -+ else -+ smidc_temp &= ~SMIDC_DMAEN; -+ -+ write_smi_reg(inst, smidc_temp, SMIDC); -+ -+ /* re-enable (if was previously enabled) */ -+ write_smi_reg(inst, smics_temp, SMICS); -+ write_smi_reg(inst, smidcs_temp, SMIDCS); -+ -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_set_regs_from_settings); -+ -+struct smi_settings *bcm2835_smi_get_settings_from_regs -+ (struct bcm2835_smi_instance *inst) -+{ -+ struct smi_settings *settings = &inst->settings; -+ int smidsr, smidsw, smidc; -+ -+ spin_lock(&inst->transaction_lock); -+ -+ smidsr = read_smi_reg(inst, SMIDSR0); -+ smidsw = read_smi_reg(inst, SMIDSW0); -+ smidc = read_smi_reg(inst, SMIDC); -+ -+ settings->pack_data = (read_smi_reg(inst, SMICS) & SMICS_PXLDAT) ? -+ true : false; -+ -+ settings->data_width = GET_BIT_FIELD(smidsr, SMIDSR_RWIDTH); -+ settings->read_setup_time = GET_BIT_FIELD(smidsr, SMIDSR_RSETUP); -+ settings->read_hold_time = GET_BIT_FIELD(smidsr, SMIDSR_RHOLD); -+ settings->read_pace_time = GET_BIT_FIELD(smidsr, SMIDSR_RPACE); -+ settings->read_strobe_time = GET_BIT_FIELD(smidsr, SMIDSR_RSTROBE); -+ -+ settings->write_setup_time = GET_BIT_FIELD(smidsw, SMIDSW_WSETUP); -+ settings->write_hold_time = GET_BIT_FIELD(smidsw, SMIDSW_WHOLD); -+ settings->write_pace_time = GET_BIT_FIELD(smidsw, SMIDSW_WPACE); -+ settings->write_strobe_time = GET_BIT_FIELD(smidsw, SMIDSW_WSTROBE); -+ -+ settings->dma_read_thresh = GET_BIT_FIELD(smidc, SMIDC_REQR); -+ settings->dma_write_thresh = GET_BIT_FIELD(smidc, SMIDC_REQW); -+ settings->dma_panic_read_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICR); -+ settings->dma_panic_write_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICW); -+ settings->dma_passthrough_enable = (smidc & SMIDC_DMAP) ? true : false; -+ settings->dma_enable = (smidc & SMIDC_DMAEN) ? true : false; -+ -+ spin_unlock(&inst->transaction_lock); -+ -+ return settings; -+} -+EXPORT_SYMBOL(bcm2835_smi_get_settings_from_regs); -+ -+static inline void smi_set_address(struct bcm2835_smi_instance *inst, -+ unsigned int address) -+{ -+ int smia_temp = 0, smida_temp = 0; -+ -+ SET_BIT_FIELD(smia_temp, SMIA_ADDR, address); -+ SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address); -+ -+ /* Write to both address registers - user doesn't care whether we're -+ doing programmed or direct transfers. */ -+ write_smi_reg(inst, smia_temp, SMIA); -+ write_smi_reg(inst, smida_temp, SMIDA); -+} -+ -+static void smi_setup_regs(struct bcm2835_smi_instance *inst) -+{ -+ -+ dev_dbg(inst->dev, "Initialising SMI registers..."); -+ /* Disable the peripheral if already enabled */ -+ write_smi_reg(inst, 0, SMICS); -+ write_smi_reg(inst, 0, SMIDCS); -+ -+ smi_get_default_settings(inst); -+ bcm2835_smi_set_regs_from_settings(inst); -+ smi_set_address(inst, 0); -+ -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ENABLE, SMICS); -+ write_smi_reg(inst, read_smi_reg(inst, SMIDCS) | SMIDCS_ENABLE, -+ SMIDCS); -+} -+ -+/**************************************************************************** -+* -+* Low-level SMI access functions -+* Other modules should use the exported higher-level functions e.g. -+* bcm2835_smi_write_buf() unless they have a good reason to use these -+* -+***************************************************************************/ -+ -+static inline uint32_t smi_read_single_word(struct bcm2835_smi_instance *inst) -+{ -+ int timeout = 0; -+ -+ write_smi_reg(inst, SMIDCS_ENABLE, SMIDCS); -+ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_START, SMIDCS); -+ /* Make sure things happen in the right order...*/ -+ mb(); -+ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && -+ ++timeout < 10000) -+ ; -+ if (timeout < 10000) -+ return read_smi_reg(inst, SMIDD); -+ -+ dev_err(inst->dev, -+ "SMI direct read timed out (is the clock set up correctly?)"); -+ return 0; -+} -+ -+static inline void smi_write_single_word(struct bcm2835_smi_instance *inst, -+ uint32_t data) -+{ -+ int timeout = 0; -+ -+ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE, SMIDCS); -+ write_smi_reg(inst, data, SMIDD); -+ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE | SMIDCS_START, -+ SMIDCS); -+ -+ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && -+ ++timeout < 10000) -+ ; -+ if (timeout >= 10000) -+ dev_err(inst->dev, -+ "SMI direct write timed out (is the clock set up correctly?)"); -+} -+ -+/* Initiates a programmed read into the read FIFO. It is up to the caller to -+ * read data from the FIFO - either via paced DMA transfer, -+ * or polling SMICS_RXD to check whether data is available. -+ * SMICS_ACTIVE will go low upon completion. */ -+static void smi_init_programmed_read(struct bcm2835_smi_instance *inst, -+ int num_transfers) -+{ -+ int smics_temp; -+ -+ /* Disable the peripheral: */ -+ smics_temp = read_smi_reg(inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE); -+ write_smi_reg(inst, smics_temp, SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) -+ ; -+ -+ /* Program the transfer count: */ -+ write_smi_reg(inst, num_transfers, SMIL); -+ -+ /* re-enable and start: */ -+ smics_temp |= SMICS_ENABLE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ smics_temp |= SMICS_CLEAR; -+ /* Just to be certain: */ -+ mb(); -+ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) -+ ; -+ write_smi_reg(inst, smics_temp, SMICS); -+ smics_temp |= SMICS_START; -+ write_smi_reg(inst, smics_temp, SMICS); -+} -+ -+/* Initiates a programmed write sequence, using data from the write FIFO. -+ * It is up to the caller to initiate a DMA transfer before calling, -+ * or use another method to keep the write FIFO topped up. -+ * SMICS_ACTIVE will go low upon completion. -+ */ -+static void smi_init_programmed_write(struct bcm2835_smi_instance *inst, -+ int num_transfers) -+{ -+ int smics_temp; -+ -+ /* Disable the peripheral: */ -+ smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) -+ ; -+ -+ /* Program the transfer count: */ -+ write_smi_reg(inst, num_transfers, SMIL); -+ -+ /* setup, re-enable and start: */ -+ smics_temp |= SMICS_WRITE | SMICS_ENABLE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ smics_temp |= SMICS_START; -+ write_smi_reg(inst, smics_temp, SMICS); -+} -+ -+/* Initiate a read and then poll FIFO for data, reading out as it appears. */ -+static void smi_read_fifo(struct bcm2835_smi_instance *inst, -+ uint32_t *dest, int n_bytes) -+{ -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { -+ smi_dump_context_labelled(inst, -+ "WARNING: read FIFO not empty at start of read call."); -+ while (read_smi_reg(inst, SMICS)) -+ ; -+ } -+ -+ /* Dispatch the read: */ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_read(inst, n_bytes); -+ else if (inst->settings.data_width == SMI_WIDTH_16BIT) -+ smi_init_programmed_read(inst, n_bytes / 2); -+ else { -+ dev_err(inst->dev, "Unsupported data width for read."); -+ return; -+ } -+ -+ /* Poll FIFO to keep it empty */ -+ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) -+ *dest++ = read_smi_reg(inst, SMID); -+ -+ /* Ensure that the FIFO is emptied */ -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { -+ int fifo_count; -+ -+ fifo_count = GET_BIT_FIELD(read_smi_reg(inst, SMIFD), -+ SMIFD_FCNT); -+ while (fifo_count--) -+ *dest++ = read_smi_reg(inst, SMID); -+ } -+ -+ if (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) -+ smi_dump_context_labelled(inst, -+ "WARNING: transaction finished but done bit not set."); -+ -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) -+ smi_dump_context_labelled(inst, -+ "WARNING: read FIFO not empty at end of read call."); -+ -+} -+ -+/* Initiate a write, and then keep the FIFO topped up. */ -+static void smi_write_fifo(struct bcm2835_smi_instance *inst, -+ uint32_t *src, int n_bytes) -+{ -+ int i, timeout = 0; -+ -+ /* Empty FIFOs if not already so */ -+ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) { -+ smi_dump_context_labelled(inst, -+ "WARNING: write fifo not empty at start of write call."); -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_CLEAR, -+ SMICS); -+ } -+ -+ /* Initiate the transfer */ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_write(inst, n_bytes); -+ else if (inst->settings.data_width == SMI_WIDTH_16BIT) -+ smi_init_programmed_write(inst, n_bytes / 2); -+ else { -+ dev_err(inst->dev, "Unsupported data width for write."); -+ return; -+ } -+ /* Fill the FIFO: */ -+ for (i = 0; i < (n_bytes - 1) / 4 + 1; ++i) { -+ while (!(read_smi_reg(inst, SMICS) & SMICS_TXD)) -+ ; -+ write_smi_reg(inst, *src++, SMID); -+ } -+ /* Busy wait... */ -+ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE) && ++timeout < -+ 1000000) -+ ; -+ if (timeout >= 1000000) -+ smi_dump_context_labelled(inst, -+ "Timed out on write operation!"); -+ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) -+ smi_dump_context_labelled(inst, -+ "WARNING: FIFO not empty at end of write operation."); -+} -+ -+/**************************************************************************** -+* -+* SMI DMA operations -+* -+***************************************************************************/ -+ -+/* Disable SMI and put it into the correct direction before doing DMA setup. -+ Stops spurious DREQs during setup. Peripheral is re-enabled by init_*() */ -+static void smi_disable(struct bcm2835_smi_instance *inst, -+ enum dma_transfer_direction direction) -+{ -+ int smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; -+ -+ if (direction == DMA_DEV_TO_MEM) -+ smics_temp &= ~SMICS_WRITE; -+ else -+ smics_temp |= SMICS_WRITE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) -+ ; -+} -+ -+static struct scatterlist *smi_scatterlist_from_buffer( -+ struct bcm2835_smi_instance *inst, -+ dma_addr_t buf, -+ size_t len, -+ struct scatterlist *sg) -+{ -+ sg_init_table(sg, 1); -+ sg_dma_address(sg) = buf; -+ sg_dma_len(sg) = len; -+ return sg; -+} -+ -+static void smi_dma_callback_user_copy(void *param) -+{ -+ /* Notify the bottom half that a chunk is ready for user copy */ -+ struct bcm2835_smi_instance *inst = -+ (struct bcm2835_smi_instance *)param; -+ -+ up(&inst->bounce.callback_sem); -+} -+ -+/* Creates a descriptor, assigns the given callback, and submits the -+ descriptor to dmaengine. Does not block - can queue up multiple -+ descriptors and then wait for them all to complete. -+ sg_len is the number of control blocks, NOT the number of bytes. -+ dir can be DMA_MEM_TO_DEV or DMA_DEV_TO_MEM. -+ callback can be NULL - in this case it is not called. */ -+static inline struct dma_async_tx_descriptor *smi_dma_submit_sgl( -+ struct bcm2835_smi_instance *inst, -+ struct scatterlist *sgl, -+ size_t sg_len, -+ enum dma_transfer_direction dir, -+ dma_async_tx_callback callback) -+{ -+ struct dma_async_tx_descriptor *desc; -+ -+ desc = dmaengine_prep_slave_sg(inst->dma_chan, -+ sgl, -+ sg_len, -+ dir, -+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK | -+ DMA_PREP_FENCE); -+ if (!desc) { -+ dev_err(inst->dev, "read_sgl: dma slave preparation failed!"); -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) & ~SMICS_ACTIVE, -+ SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) -+ cpu_relax(); -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ACTIVE, -+ SMICS); -+ return NULL; -+ } -+ desc->callback = callback; -+ desc->callback_param = inst; -+ if (dmaengine_submit(desc) < 0) -+ return NULL; -+ return desc; -+} -+ -+/* NB this function blocks until the transfer is complete */ -+static void -+smi_dma_read_sgl(struct bcm2835_smi_instance *inst, -+ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) -+{ -+ struct dma_async_tx_descriptor *desc; -+ -+ /* Disable SMI and set to read before dispatching DMA - if SMI is in -+ * write mode and TX fifo is empty, it will generate a DREQ which may -+ * cause the read DMA to complete before the SMI read command is even -+ * dispatched! We want to dispatch DMA before SMI read so that reading -+ * is gapless, for logic analyser. -+ */ -+ -+ smi_disable(inst, DMA_DEV_TO_MEM); -+ -+ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL); -+ dma_async_issue_pending(inst->dma_chan); -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_read(inst, n_bytes); -+ else -+ smi_init_programmed_read(inst, n_bytes / 2); -+ -+ if (dma_wait_for_async_tx(desc) == DMA_ERROR) -+ smi_dump_context_labelled(inst, "DMA timeout!"); -+} -+ -+static void -+smi_dma_write_sgl(struct bcm2835_smi_instance *inst, -+ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) -+{ -+ struct dma_async_tx_descriptor *desc; -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_write(inst, n_bytes); -+ else -+ smi_init_programmed_write(inst, n_bytes / 2); -+ -+ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_MEM_TO_DEV, NULL); -+ dma_async_issue_pending(inst->dma_chan); -+ -+ if (dma_wait_for_async_tx(desc) == DMA_ERROR) -+ smi_dump_context_labelled(inst, "DMA timeout!"); -+ else -+ /* Wait for SMI to finish our writes */ -+ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) -+ cpu_relax(); -+} -+ -+ssize_t bcm2835_smi_user_dma( -+ struct bcm2835_smi_instance *inst, -+ enum dma_transfer_direction dma_dir, -+ char __user *user_ptr, size_t count, -+ struct bcm2835_smi_bounce_info **bounce) -+{ -+ int chunk_no = 0, chunk_size, count_left = count; -+ struct scatterlist *sgl; -+ void (*init_trans_func)(struct bcm2835_smi_instance *, int); -+ -+ spin_lock(&inst->transaction_lock); -+ -+ if (dma_dir == DMA_DEV_TO_MEM) -+ init_trans_func = smi_init_programmed_read; -+ else -+ init_trans_func = smi_init_programmed_write; -+ -+ smi_disable(inst, dma_dir); -+ -+ sema_init(&inst->bounce.callback_sem, 0); -+ if (bounce) -+ *bounce = &inst->bounce; -+ while (count_left) { -+ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? -+ DMA_BOUNCE_BUFFER_SIZE : count_left; -+ if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) { -+ sgl = -+ &inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; -+ } else { -+ sgl = smi_scatterlist_from_buffer( -+ inst, -+ inst->bounce.phys[ -+ chunk_no % DMA_BOUNCE_BUFFER_COUNT], -+ chunk_size, -+ &inst->buffer_sgl); -+ } -+ -+ if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir, -+ smi_dma_callback_user_copy -+ )) { -+ dev_err(inst->dev, "sgl submit failed"); -+ count = 0; -+ goto out; -+ } -+ count_left -= chunk_size; -+ chunk_no++; -+ } -+ dma_async_issue_pending(inst->dma_chan); -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ init_trans_func(inst, count); -+ else if (inst->settings.data_width == SMI_WIDTH_16BIT) -+ init_trans_func(inst, count / 2); -+out: -+ spin_unlock(&inst->transaction_lock); -+ return count; -+} -+EXPORT_SYMBOL(bcm2835_smi_user_dma); -+ -+ -+/**************************************************************************** -+* -+* High level buffer transfer functions - for use by other drivers -+* -+***************************************************************************/ -+ -+/* Buffer must be physically contiguous - i.e. kmalloc, not vmalloc! */ -+void bcm2835_smi_write_buf( -+ struct bcm2835_smi_instance *inst, -+ const void *buf, size_t n_bytes) -+{ -+ int odd_bytes = n_bytes & 0x3; -+ -+ n_bytes -= odd_bytes; -+ -+ spin_lock(&inst->transaction_lock); -+ -+ if (n_bytes > DMA_THRESHOLD_BYTES) { -+ dma_addr_t phy_addr = dma_map_single( -+ inst->dev, -+ (void *)buf, -+ n_bytes, -+ DMA_MEM_TO_DEV); -+ struct scatterlist *sgl = -+ smi_scatterlist_from_buffer(inst, phy_addr, n_bytes, -+ &inst->buffer_sgl); -+ -+ if (!sgl) { -+ smi_dump_context_labelled(inst, -+ "Error: could not create scatterlist for write!"); -+ goto out; -+ } -+ smi_dma_write_sgl(inst, sgl, 1, n_bytes); -+ -+ dma_unmap_single -+ (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); -+ } else if (n_bytes) { -+ smi_write_fifo(inst, (uint32_t *) buf, n_bytes); -+ } -+ buf += n_bytes; -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) { -+ while (odd_bytes--) -+ smi_write_single_word(inst, *(uint8_t *) (buf++)); -+ } else { -+ while (odd_bytes >= 2) { -+ smi_write_single_word(inst, *(uint16_t *)buf); -+ buf += 2; -+ odd_bytes -= 2; -+ } -+ if (odd_bytes) { -+ /* Reading an odd number of bytes on a 16 bit bus is -+ a user bug. It's kinder to fail early and tell them -+ than to e.g. transparently give them the bottom byte -+ of a 16 bit transfer. */ -+ dev_err(inst->dev, -+ "WARNING: odd number of bytes specified for wide transfer."); -+ dev_err(inst->dev, -+ "At least one byte dropped as a result."); -+ dump_stack(); -+ } -+ } -+out: -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_write_buf); -+ -+void bcm2835_smi_read_buf(struct bcm2835_smi_instance *inst, -+ void *buf, size_t n_bytes) -+{ -+ -+ /* SMI is inherently 32-bit, which causes surprising amounts of mess -+ for bytes % 4 != 0. Easiest to avoid this mess altogether -+ by handling remainder separately. */ -+ int odd_bytes = n_bytes & 0x3; -+ -+ spin_lock(&inst->transaction_lock); -+ n_bytes -= odd_bytes; -+ if (n_bytes > DMA_THRESHOLD_BYTES) { -+ dma_addr_t phy_addr = dma_map_single(inst->dev, -+ buf, n_bytes, -+ DMA_DEV_TO_MEM); -+ struct scatterlist *sgl = smi_scatterlist_from_buffer( -+ inst, phy_addr, n_bytes, -+ &inst->buffer_sgl); -+ if (!sgl) { -+ smi_dump_context_labelled(inst, -+ "Error: could not create scatterlist for read!"); -+ goto out; -+ } -+ smi_dma_read_sgl(inst, sgl, 1, n_bytes); -+ dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); -+ } else if (n_bytes) { -+ smi_read_fifo(inst, (uint32_t *)buf, n_bytes); -+ } -+ buf += n_bytes; -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) { -+ while (odd_bytes--) -+ *((uint8_t *) (buf++)) = smi_read_single_word(inst); -+ } else { -+ while (odd_bytes >= 2) { -+ *(uint16_t *) buf = smi_read_single_word(inst); -+ buf += 2; -+ odd_bytes -= 2; -+ } -+ if (odd_bytes) { -+ dev_err(inst->dev, -+ "WARNING: odd number of bytes specified for wide transfer."); -+ dev_err(inst->dev, -+ "At least one byte dropped as a result."); -+ dump_stack(); -+ } -+ } -+out: -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_read_buf); -+ -+void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, -+ unsigned int address) -+{ -+ spin_lock(&inst->transaction_lock); -+ smi_set_address(inst, address); -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_set_address); -+ -+struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node) -+{ -+ struct platform_device *pdev; -+ -+ if (!node) -+ return NULL; -+ -+ pdev = of_find_device_by_node(node); -+ if (!pdev) -+ return NULL; -+ -+ return platform_get_drvdata(pdev); -+} -+EXPORT_SYMBOL(bcm2835_smi_get); -+ -+/**************************************************************************** -+* -+* bcm2835_smi_probe - called when the driver is loaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_dma_setup(struct bcm2835_smi_instance *inst) -+{ -+ int i, rv = 0; -+ -+ inst->dma_chan = dma_request_slave_channel(inst->dev, "rx-tx"); -+ -+ inst->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ inst->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ inst->dma_config.src_addr = inst->smi_regs_busaddr + SMID; -+ inst->dma_config.dst_addr = inst->dma_config.src_addr; -+ /* Direction unimportant - always overridden by prep_slave_sg */ -+ inst->dma_config.direction = DMA_DEV_TO_MEM; -+ dmaengine_slave_config(inst->dma_chan, &inst->dma_config); -+ /* Alloc and map bounce buffers */ -+ for (i = 0; i < DMA_BOUNCE_BUFFER_COUNT; ++i) { -+ inst->bounce.buffer[i] = -+ dmam_alloc_coherent(inst->dev, DMA_BOUNCE_BUFFER_SIZE, -+ &inst->bounce.phys[i], -+ GFP_KERNEL); -+ if (!inst->bounce.buffer[i]) { -+ dev_err(inst->dev, "Could not allocate buffer!"); -+ rv = -ENOMEM; -+ break; -+ } -+ smi_scatterlist_from_buffer( -+ inst, -+ inst->bounce.phys[i], -+ DMA_BOUNCE_BUFFER_SIZE, -+ &inst->bounce.sgl[i] -+ ); -+ } -+ -+ return rv; -+} -+ -+static int bcm2835_smi_probe(struct platform_device *pdev) -+{ -+ int err; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct resource *ioresource; -+ struct bcm2835_smi_instance *inst; -+ -+ /* Allocate buffers and instance data */ -+ -+ inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance), -+ GFP_KERNEL); -+ -+ if (!inst) -+ return -ENOMEM; -+ -+ inst->dev = dev; -+ spin_lock_init(&inst->transaction_lock); -+ -+ /* We require device tree support */ -+ if (!node) -+ return -EINVAL; -+ -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource); -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource); -+ inst->smi_regs_busaddr = be32_to_cpu( -+ *of_get_address(node, 0, NULL, NULL)); -+ of_property_read_u32(node, -+ "brcm,smi-clock-source", -+ &inst->clock_source); -+ of_property_read_u32(node, -+ "brcm,smi-clock-divisor", -+ &inst->clock_divisor); -+ -+ err = bcm2835_smi_dma_setup(inst); -+ if (err) -+ return err; -+ -+ /* Finally, do peripheral setup */ -+ -+ smi_setup_clock(inst); -+ smi_setup_regs(inst); -+ -+ platform_set_drvdata(pdev, inst); -+ -+ dev_info(inst->dev, "initialised"); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* bcm2835_smi_remove - called when the driver is unloaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev); -+ struct device *dev = inst->dev; -+ -+ dev_info(dev, "SMI device removed - OK"); -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_smi_of_match[] = { -+ {.compatible = "brcm,bcm2835-smi",}, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_smi_of_match); -+ -+static struct platform_driver bcm2835_smi_driver = { -+ .probe = bcm2835_smi_probe, -+ .remove = bcm2835_smi_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_smi_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_smi_driver); -+ -+MODULE_ALIAS("platform:smi-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Device driver for BCM2835's secondary memory interface"); -+MODULE_AUTHOR("Luke Wren "); -diff --git a/include/linux/broadcom/bcm2835_smi.h b/include/linux/broadcom/bcm2835_smi.h -new file mode 100644 -index 0000000..ee3a75e ---- /dev/null -+++ b/include/linux/broadcom/bcm2835_smi.h -@@ -0,0 +1,391 @@ -+/** -+ * Declarations and definitions for Broadcom's Secondary Memory Interface -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * Copyright (c) 2010-2012 Broadcom. All rights reserved. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+ -+#ifndef BCM2835_SMI_H -+#define BCM2835_SMI_H -+ -+#include -+ -+#ifndef __KERNEL__ -+#include -+#include +diff --git a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c +index 4b32941..0eb0f35 100644 +--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c +@@ -1187,7 +1187,9 @@ static void free_wrapper(struct gadget_wrapper *d) + /* should have been done already by driver model core */ + DWC_WARN("driver '%s' is still registered\n", + d->driver->driver.name); ++#ifdef CONFIG_USB_GADGET + usb_gadget_unregister_driver(d->driver); +#endif -+ -+#define BCM2835_SMI_IOC_MAGIC 0x1 -+#define BCM2835_SMI_INVALID_HANDLE (~0) -+ -+/* IOCTLs 0x100...0x1ff are not device-specific - we can use them */ -+#define BCM2835_SMI_IOC_GET_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 0) -+#define BCM2835_SMI_IOC_WRITE_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 1) -+#define BCM2835_SMI_IOC_ADDRESS _IO(BCM2835_SMI_IOC_MAGIC, 2) -+#define BCM2835_SMI_IOC_MAX 2 -+ -+#define SMI_WIDTH_8BIT 0 -+#define SMI_WIDTH_16BIT 1 -+#define SMI_WIDTH_9BIT 2 -+#define SMI_WIDTH_18BIT 3 -+ -+/* max number of bytes where DMA will not be used */ -+#define DMA_THRESHOLD_BYTES 128 -+#define DMA_BOUNCE_BUFFER_SIZE (1024 * 1024 / 2) -+#define DMA_BOUNCE_BUFFER_COUNT 3 -+ -+ -+struct smi_settings { -+ int data_width; -+ /* Whether or not to pack multiple SMI transfers into a -+ single 32 bit FIFO word */ -+ bool pack_data; -+ -+ /* Timing for reads (writes the same but for WE) -+ * -+ * OE ----------+ +-------------------- -+ * | | -+ * +----------+ -+ * SD -<==============================>----------- -+ * SA -<=========================================>- -+ * <-setup-> <-strobe -> <-hold -> <- pace -> -+ */ -+ -+ int read_setup_time; -+ int read_hold_time; -+ int read_pace_time; -+ int read_strobe_time; -+ -+ int write_setup_time; -+ int write_hold_time; -+ int write_pace_time; -+ int write_strobe_time; -+ -+ bool dma_enable; /* DREQs */ -+ bool dma_passthrough_enable; /* External DREQs */ -+ int dma_read_thresh; -+ int dma_write_thresh; -+ int dma_panic_read_thresh; -+ int dma_panic_write_thresh; -+}; -+ -+/**************************************************************************** -+* -+* Declare exported SMI functions -+* -+***************************************************************************/ -+ -+#ifdef __KERNEL__ -+ -+#include /* for enum dma_transfer_direction */ -+#include -+#include -+ -+struct bcm2835_smi_instance; -+ -+struct bcm2835_smi_bounce_info { -+ struct semaphore callback_sem; -+ void *buffer[DMA_BOUNCE_BUFFER_COUNT]; -+ dma_addr_t phys[DMA_BOUNCE_BUFFER_COUNT]; -+ struct scatterlist sgl[DMA_BOUNCE_BUFFER_COUNT]; -+}; -+ -+ -+void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *); -+ -+struct smi_settings *bcm2835_smi_get_settings_from_regs( -+ struct bcm2835_smi_instance *inst); -+ -+void bcm2835_smi_write_buf( -+ struct bcm2835_smi_instance *inst, -+ const void *buf, -+ size_t n_bytes); -+ -+void bcm2835_smi_read_buf( -+ struct bcm2835_smi_instance *inst, -+ void *buf, -+ size_t n_bytes); -+ -+void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, -+ unsigned int address); -+ -+ssize_t bcm2835_smi_user_dma( -+ struct bcm2835_smi_instance *inst, -+ enum dma_transfer_direction dma_dir, -+ char __user *user_ptr, -+ size_t count, -+ struct bcm2835_smi_bounce_info **bounce); -+ -+struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node); -+ -+#endif /* __KERNEL__ */ -+ -+/**************************************************************** -+* -+* Implementation-only declarations -+* -+****************************************************************/ -+ -+#ifdef BCM2835_SMI_IMPLEMENTATION -+ -+/* Clock manager registers for SMI clock: */ -+#define CM_SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x1010b0) -+/* Clock manager "password" to protect registers from spurious writes */ -+#define CM_PWD (0x5a << 24) -+ -+#define CM_SMI_CTL 0x00 -+#define CM_SMI_DIV 0x04 -+ -+#define CM_SMI_CTL_FLIP (1 << 8) -+#define CM_SMI_CTL_BUSY (1 << 7) -+#define CM_SMI_CTL_KILL (1 << 5) -+#define CM_SMI_CTL_ENAB (1 << 4) -+#define CM_SMI_CTL_SRC_MASK (0xf) -+#define CM_SMI_CTL_SRC_OFFS (0) -+ -+#define CM_SMI_DIV_DIVI_MASK (0xf << 12) -+#define CM_SMI_DIV_DIVI_OFFS (12) -+#define CM_SMI_DIV_DIVF_MASK (0xff << 4) -+#define CM_SMI_DIV_DIVF_OFFS (4) -+ -+/* SMI register mapping:*/ -+#define SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x600000) -+ -+#define SMICS 0x00 /* control + status register */ -+#define SMIL 0x04 /* length/count (n external txfers) */ -+#define SMIA 0x08 /* address register */ -+#define SMID 0x0c /* data register */ -+#define SMIDSR0 0x10 /* device 0 read settings */ -+#define SMIDSW0 0x14 /* device 0 write settings */ -+#define SMIDSR1 0x18 /* device 1 read settings */ -+#define SMIDSW1 0x1c /* device 1 write settings */ -+#define SMIDSR2 0x20 /* device 2 read settings */ -+#define SMIDSW2 0x24 /* device 2 write settings */ -+#define SMIDSR3 0x28 /* device 3 read settings */ -+#define SMIDSW3 0x2c /* device 3 write settings */ -+#define SMIDC 0x30 /* DMA control registers */ -+#define SMIDCS 0x34 /* direct control/status register */ -+#define SMIDA 0x38 /* direct address register */ -+#define SMIDD 0x3c /* direct data registers */ -+#define SMIFD 0x40 /* FIFO debug register */ -+ -+ -+ -+/* Control and Status register bits: -+ * SMICS_RXF : RX fifo full: 1 when RX fifo is full -+ * SMICS_TXE : TX fifo empty: 1 when empty. -+ * SMICS_RXD : RX fifo contains data: 1 when there is data. -+ * SMICS_TXD : TX fifo can accept data: 1 when true. -+ * SMICS_RXR : RX fifo needs reading: 1 when fifo more than 3/4 full, or -+ * when "DONE" and fifo not emptied. -+ * SMICS_TXW : TX fifo needs writing: 1 when less than 1/4 full. -+ * SMICS_AFERR : AXI FIFO error: 1 when fifo read when empty or written -+ * when full. Write 1 to clear. -+ * SMICS_EDREQ : 1 when external DREQ received. -+ * SMICS_PXLDAT : Pixel data: write 1 to enable pixel transfer modes. -+ * SMICS_SETERR : 1 if there was an error writing to setup regs (e.g. -+ * tx was in progress). Write 1 to clear. -+ * SMICS_PVMODE : Set to 1 to enable pixel valve mode. -+ * SMICS_INTR : Set to 1 to enable interrupt on RX. -+ * SMICS_INTT : Set to 1 to enable interrupt on TX. -+ * SMICS_INTD : Set to 1 to enable interrupt on DONE condition. -+ * SMICS_TEEN : Tear effect mode enabled: Programmed transfers will wait -+ * for a TE trigger before writing. -+ * SMICS_PAD1 : Padding settings for external transfers. For writes: the -+ * number of bytes initially written to the TX fifo that -+ * SMICS_PAD0 : should be ignored. For reads: the number of bytes that will -+ * be read before the data, and should be dropped. -+ * SMICS_WRITE : Transfer direction: 1 = write to external device, 0 = read -+ * SMICS_CLEAR : Write 1 to clear the FIFOs. -+ * SMICS_START : Write 1 to start the programmed transfer. -+ * SMICS_ACTIVE : Reads as 1 when a programmed transfer is underway. -+ * SMICS_DONE : Reads as 1 when transfer finished. For RX, not set until -+ * FIFO emptied. -+ * SMICS_ENABLE : Set to 1 to enable the SMI peripheral, 0 to disable. -+ */ -+ -+#define SMICS_RXF (1 << 31) -+#define SMICS_TXE (1 << 30) -+#define SMICS_RXD (1 << 29) -+#define SMICS_TXD (1 << 28) -+#define SMICS_RXR (1 << 27) -+#define SMICS_TXW (1 << 26) -+#define SMICS_AFERR (1 << 25) -+#define SMICS_EDREQ (1 << 15) -+#define SMICS_PXLDAT (1 << 14) -+#define SMICS_SETERR (1 << 13) -+#define SMICS_PVMODE (1 << 12) -+#define SMICS_INTR (1 << 11) -+#define SMICS_INTT (1 << 10) -+#define SMICS_INTD (1 << 9) -+#define SMICS_TEEN (1 << 8) -+#define SMICS_PAD1 (1 << 7) -+#define SMICS_PAD0 (1 << 6) -+#define SMICS_WRITE (1 << 5) -+#define SMICS_CLEAR (1 << 4) -+#define SMICS_START (1 << 3) -+#define SMICS_ACTIVE (1 << 2) -+#define SMICS_DONE (1 << 1) -+#define SMICS_ENABLE (1 << 0) -+ -+/* Address register bits: */ -+ -+#define SMIA_DEVICE_MASK ((1 << 9) | (1 << 8)) -+#define SMIA_DEVICE_OFFS (8) -+#define SMIA_ADDR_MASK (0x3f) /* bits 5 -> 0 */ -+#define SMIA_ADDR_OFFS (0) -+ -+/* DMA control register bits: -+ * SMIDC_DMAEN : DMA enable: set 1: DMA requests will be issued. -+ * SMIDC_DMAP : DMA passthrough: when set to 0, top two data pins are used by -+ * SMI as usual. When set to 1, the top two pins are used for -+ * external DREQs: pin 16 read request, 17 write. -+ * SMIDC_PANIC* : Threshold at which DMA will panic during read/write. -+ * SMIDC_REQ* : Threshold at which DMA will generate a DREQ. -+ */ -+ -+#define SMIDC_DMAEN (1 << 28) -+#define SMIDC_DMAP (1 << 24) -+#define SMIDC_PANICR_MASK (0x3f << 18) -+#define SMIDC_PANICR_OFFS (18) -+#define SMIDC_PANICW_MASK (0x3f << 12) -+#define SMIDC_PANICW_OFFS (12) -+#define SMIDC_REQR_MASK (0x3f << 6) -+#define SMIDC_REQR_OFFS (6) -+#define SMIDC_REQW_MASK (0x3f) -+#define SMIDC_REQW_OFFS (0) -+ -+/* Device settings register bits: same for all 4 (or 3?) device register sets. -+ * Device read settings: -+ * SMIDSR_RWIDTH : Read transfer width. 00 = 8bit, 01 = 16bit, -+ * 10 = 18bit, 11 = 9bit. -+ * SMIDSR_RSETUP : Read setup time: number of core cycles between chip -+ * select/address and read strobe. Min 1, max 64. -+ * SMIDSR_MODE68 : 1 for System 68 mode (i.e. enable + direction pins, -+ * rather than OE + WE pin) -+ * SMIDSR_FSETUP : If set to 1, setup time only applies to first -+ * transfer after address change. -+ * SMIDSR_RHOLD : Number of core cycles between read strobe going -+ * inactive and CS/address going inactive. Min 1, max 64 -+ * SMIDSR_RPACEALL : When set to 1, this device's RPACE value will always -+ * be used for the next transaction, even if it is not -+ * to this device. -+ * SMIDSR_RPACE : Number of core cycles spent waiting between CS -+ * deassert and start of next transfer. Min 1, max 128 -+ * SMIDSR_RDREQ : 1 = use external DMA request on SD16 to pace reads -+ * from device. Must also set DMAP in SMICS. -+ * SMIDSR_RSTROBE : Number of cycles to assert the read strobe. -+ * min 1, max 128. -+ */ -+#define SMIDSR_RWIDTH_MASK ((1<<31)|(1<<30)) -+#define SMIDSR_RWIDTH_OFFS (30) -+#define SMIDSR_RSETUP_MASK (0x3f << 24) -+#define SMIDSR_RSETUP_OFFS (24) -+#define SMIDSR_MODE68 (1 << 23) -+#define SMIDSR_FSETUP (1 << 22) -+#define SMIDSR_RHOLD_MASK (0x3f << 16) -+#define SMIDSR_RHOLD_OFFS (16) -+#define SMIDSR_RPACEALL (1 << 15) -+#define SMIDSR_RPACE_MASK (0x7f << 8) -+#define SMIDSR_RPACE_OFFS (8) -+#define SMIDSR_RDREQ (1 << 7) -+#define SMIDSR_RSTROBE_MASK (0x7f) -+#define SMIDSR_RSTROBE_OFFS (0) -+ -+/* Device write settings: -+ * SMIDSW_WWIDTH : Write transfer width. 00 = 8bit, 01 = 16bit, -+ * 10= 18bit, 11 = 9bit. -+ * SMIDSW_WSETUP : Number of cycles between CS assert and write strobe. -+ * Min 1, max 64. -+ * SMIDSW_WFORMAT : Pixel format of input. 0 = 16bit RGB 565, -+ * 1 = 32bit RGBA 8888 -+ * SMIDSW_WSWAP : 1 = swap pixel data bits. (Use with SMICS_PXLDAT) -+ * SMIDSW_WHOLD : Time between WE deassert and CS deassert. 1 to 64 -+ * SMIDSW_WPACEALL : 1: this device's WPACE will be used for the next -+ * transfer, regardless of that transfer's device. -+ * SMIDSW_WPACE : Cycles between CS deassert and next CS assert. -+ * Min 1, max 128 -+ * SMIDSW_WDREQ : Use external DREQ on pin 17 to pace writes. DMAP must -+ * be set in SMICS. -+ * SMIDSW_WSTROBE : Number of cycles to assert the write strobe. -+ * Min 1, max 128 -+ */ -+#define SMIDSW_WWIDTH_MASK ((1<<31)|(1<<30)) -+#define SMIDSW_WWIDTH_OFFS (30) -+#define SMIDSW_WSETUP_MASK (0x3f << 24) -+#define SMIDSW_WSETUP_OFFS (24) -+#define SMIDSW_WFORMAT (1 << 23) -+#define SMIDSW_WSWAP (1 << 22) -+#define SMIDSW_WHOLD_MASK (0x3f << 16) -+#define SMIDSW_WHOLD_OFFS (16) -+#define SMIDSW_WPACEALL (1 << 15) -+#define SMIDSW_WPACE_MASK (0x7f << 8) -+#define SMIDSW_WPACE_OFFS (8) -+#define SMIDSW_WDREQ (1 << 7) -+#define SMIDSW_WSTROBE_MASK (0x7f) -+#define SMIDSW_WSTROBE_OFFS (0) -+ -+/* Direct transfer control + status register -+ * SMIDCS_WRITE : Direction of transfer: 1 -> write, 0 -> read -+ * SMIDCS_DONE : 1 when a transfer has finished. Write 1 to clear. -+ * SMIDCS_START : Write 1 to start a transfer, if one is not already underway. -+ * SMIDCE_ENABLE: Write 1 to enable SMI in direct mode. -+ */ -+ -+#define SMIDCS_WRITE (1 << 3) -+#define SMIDCS_DONE (1 << 2) -+#define SMIDCS_START (1 << 1) -+#define SMIDCS_ENABLE (1 << 0) -+ -+/* Direct transfer address register -+ * SMIDA_DEVICE : Indicates which of the device settings banks should be used. -+ * SMIDA_ADDR : The value to be asserted on the address pins. -+ */ -+ -+#define SMIDA_DEVICE_MASK ((1<<9)|(1<<8)) -+#define SMIDA_DEVICE_OFFS (8) -+#define SMIDA_ADDR_MASK (0x3f) -+#define SMIDA_ADDR_OFFS (0) -+ -+/* FIFO debug register -+ * SMIFD_FLVL : The high-tide mark of FIFO count during the most recent txfer -+ * SMIFD_FCNT : The current FIFO count. -+ */ -+#define SMIFD_FLVL_MASK (0x3f << 8) -+#define SMIFD_FLVL_OFFS (8) -+#define SMIFD_FCNT_MASK (0x3f) -+#define SMIFD_FCNT_OFFS (0) -+ -+#endif /* BCM2835_SMI_IMPLEMENTATION */ -+ -+#endif /* BCM2835_SMI_H */ - -From f657d984e244c7348152e2edc09cd5decb2f5b55 Mon Sep 17 00:00:00 2001 -From: Luke Wren -Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 183/204] Add SMI NAND driver - -Signed-off-by: Luke Wren ---- - .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++ - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 ++++++ - arch/arm/configs/bcm2709_defconfig | 7 + - arch/arm/configs/bcmrpi_defconfig | 7 + - drivers/mtd/nand/Kconfig | 7 + - drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++ - 8 files changed, 402 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt - create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts - create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c - -diff --git a/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt -new file mode 100644 -index 0000000..159544d ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt -@@ -0,0 +1,42 @@ -+* BCM2835 SMI NAND flash -+ -+This driver is a shim between the BCM2835 SMI driver (SMI is a peripheral for -+talking to parallel register interfaces) and Linux's MTD layer. -+ -+Required properties: -+- compatible: "brcm,bcm2835-smi-nand" -+- status: "okay" -+ -+Optional properties: -+- partition@n, where n is an integer from a consecutive sequence starting at 0 -+ - Difficult to store partition table on NAND device - normally put it -+ in the source code, kernel bootparams, or device tree (the best way!) -+ - Sub-properties: -+ - label: the partition name, as shown by mtdinfo /dev/mtd* -+ - reg: the size and offset of this partition. -+ - (optional) read-only: an empty property flagging as read only -+ -+Example: -+ -+nand: flash@0 { -+ compatible = "brcm,bcm2835-smi-nand"; -+ status = "okay"; -+ -+ partition@0 { -+ label = "stage2"; -+ // 128k -+ reg = <0 0x20000>; -+ read-only; -+ }; -+ partition@1 { -+ label = "firmware"; -+ // 16M -+ reg = <0x20000 0x1000000>; -+ read-only; -+ }; -+ partition@2 { -+ label = "root"; -+ // 2G -+ reg = <0x1020000 0x80000000>; -+ }; -+}; -\ No newline at end of file -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index f8f2c034..dfd23a1 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -15,6 +15,7 @@ endif - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/smi-nand-overlay.dts b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts -new file mode 100644 -index 0000000..13ce0b7 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts -@@ -0,0 +1,69 @@ -+// Description: Overlay to enable NAND flash through -+// the secondary memory interface -+// Author: Luke Wren -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&smi>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&smi_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ nand: flash@0 { -+ compatible = "brcm,bcm2835-smi-nand"; -+ smi_handle = <&smi>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ status = "okay"; -+ -+ partition@0 { -+ label = "stage2"; -+ // 128k -+ reg = <0 0x20000>; -+ read-only; -+ }; -+ partition@1 { -+ label = "firmware"; -+ // 16M -+ reg = <0x20000 0x1000000>; -+ read-only; -+ }; -+ partition@2 { -+ label = "root"; -+ // 2G (will need to use 64 bit for >=4G) -+ reg = <0x1020000 0x80000000>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ smi_pins: smi_pins { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15>; -+ /* Alt 1: SMI */ -+ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 -+ 5 5 5 5 5>; -+ /* /CS, /WE and /OE are pulled high, as they are -+ generally active low signals */ -+ brcm,pull = <2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 16a8354..c7671bf 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -392,6 +392,10 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_UBI=m - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1142,6 +1146,9 @@ CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m - CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 7dd4fd4..75fa1d0 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -385,6 +385,10 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_UBI=m - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1135,6 +1139,9 @@ CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m - CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y -diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 5897d8d..82c4b4b 100644 ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -41,6 +41,13 @@ config MTD_SM_COMMON - tristate - default n - -+config MTD_NAND_BCM2835_SMI -+ tristate "Use Broadcom's Secondary Memory Interface as a NAND controller (BCM283x)" -+ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI && MTD_NAND -+ default m -+ help -+ Uses the BCM2835's SMI peripheral as a NAND controller. -+ - config MTD_NAND_DENALI - tristate "Support Denali NAND controller" - depends on HAS_DMA -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 582bbd05..f1393b0 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o - obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o - obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o - obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o -+obj-$(CONFIG_MTD_NAND_BCM2835_SMI) += bcm2835_smi_nand.o - obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o - obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o - obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o -diff --git a/drivers/mtd/nand/bcm2835_smi_nand.c b/drivers/mtd/nand/bcm2835_smi_nand.c -new file mode 100644 -index 0000000..b747326 ---- /dev/null -+++ b/drivers/mtd/nand/bcm2835_smi_nand.c -@@ -0,0 +1,268 @@ -+/** -+ * NAND flash driver for Broadcom Secondary Memory Interface -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DEVICE_NAME "bcm2835-smi-nand" -+#define DRIVER_NAME "smi-nand-bcm2835" -+ -+struct bcm2835_smi_nand_host { -+ struct bcm2835_smi_instance *smi_inst; -+ struct nand_chip nand_chip; -+ struct mtd_info mtd; -+ struct device *dev; -+}; -+ -+/**************************************************************************** -+* -+* NAND functionality implementation -+* -+****************************************************************************/ -+ -+#define SMI_NAND_CLE_PIN 0x01 -+#define SMI_NAND_ALE_PIN 0x02 -+ -+static inline void bcm2835_smi_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ uint32_t cmd32 = cmd; -+ uint32_t addr = ~(SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ if (ctrl & NAND_CLE) -+ addr |= SMI_NAND_CLE_PIN; -+ if (ctrl & NAND_ALE) -+ addr |= SMI_NAND_ALE_PIN; -+ /* Lower ALL the CS pins! */ -+ if (ctrl & NAND_NCE) -+ addr &= (SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); -+ -+ bcm2835_smi_set_address(inst, addr); -+ -+ if (cmd != NAND_CMD_NONE) -+ bcm2835_smi_write_buf(inst, &cmd32, 1); -+} -+ -+static inline uint8_t bcm2835_smi_nand_read_byte(struct mtd_info *mtd) -+{ -+ uint8_t byte; -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_read_buf(inst, &byte, 1); -+ return byte; -+} -+ -+static inline void bcm2835_smi_nand_write_byte(struct mtd_info *mtd, -+ uint8_t byte) -+{ -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_write_buf(inst, &byte, 1); -+} -+ -+static inline void bcm2835_smi_nand_write_buf(struct mtd_info *mtd, -+ const uint8_t *buf, int len) -+{ -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_write_buf(inst, buf, len); -+} -+ -+static inline void bcm2835_smi_nand_read_buf(struct mtd_info *mtd, -+ uint8_t *buf, int len) -+{ -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_read_buf(inst, buf, len); -+} -+ -+/**************************************************************************** -+* -+* Probe and remove functions -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_nand_probe(struct platform_device *pdev) -+{ -+ struct bcm2835_smi_nand_host *host; -+ struct nand_chip *this; -+ struct mtd_info *mtd; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node, *smi_node; -+ struct mtd_part_parser_data ppdata; -+ struct smi_settings *smi_settings; -+ struct bcm2835_smi_instance *smi_inst; -+ int ret = -ENXIO; -+ -+ if (!node) { -+ dev_err(dev, "No device tree node supplied!"); -+ return -EINVAL; -+ } -+ -+ smi_node = of_parse_phandle(node, "smi_handle", 0); -+ -+ /* Request use of SMI peripheral: */ -+ smi_inst = bcm2835_smi_get(smi_node); -+ -+ if (!smi_inst) { -+ dev_err(dev, "Could not register with SMI."); -+ return -EPROBE_DEFER; -+ } -+ -+ /* Set SMI timing and bus width */ -+ -+ smi_settings = bcm2835_smi_get_settings_from_regs(smi_inst); -+ -+ smi_settings->data_width = SMI_WIDTH_8BIT; -+ smi_settings->read_setup_time = 2; -+ smi_settings->read_hold_time = 1; -+ smi_settings->read_pace_time = 1; -+ smi_settings->read_strobe_time = 3; -+ -+ smi_settings->write_setup_time = 2; -+ smi_settings->write_hold_time = 1; -+ smi_settings->write_pace_time = 1; -+ smi_settings->write_strobe_time = 3; -+ -+ bcm2835_smi_set_regs_from_settings(smi_inst); -+ -+ host = devm_kzalloc(dev, sizeof(struct bcm2835_smi_nand_host), -+ GFP_KERNEL); -+ if (!host) -+ return -ENOMEM; -+ -+ host->dev = dev; -+ host->smi_inst = smi_inst; -+ -+ platform_set_drvdata(pdev, host); -+ -+ /* Link the structures together */ -+ -+ this = &host->nand_chip; -+ mtd = &host->mtd; -+ mtd->priv = this; -+ mtd->owner = THIS_MODULE; -+ mtd->dev.parent = dev; -+ mtd->name = DRIVER_NAME; -+ ppdata.of_node = node; -+ -+ /* 20 us command delay time... */ -+ this->chip_delay = 20; -+ -+ this->priv = host; -+ this->cmd_ctrl = bcm2835_smi_nand_cmd_ctrl; -+ this->read_byte = bcm2835_smi_nand_read_byte; -+ this->write_byte = bcm2835_smi_nand_write_byte; -+ this->write_buf = bcm2835_smi_nand_write_buf; -+ this->read_buf = bcm2835_smi_nand_read_buf; -+ -+ this->ecc.mode = NAND_ECC_SOFT; -+ -+ /* Should never be accessed directly: */ -+ -+ this->IO_ADDR_R = (void *)0xdeadbeef; -+ this->IO_ADDR_W = (void *)0xdeadbeef; -+ -+ /* First scan to find the device and get the page size */ -+ -+ if (nand_scan_ident(mtd, 1, NULL)) -+ return -ENXIO; -+ -+ /* Second phase scan */ -+ -+ if (nand_scan_tail(mtd)) -+ return -ENXIO; -+ -+ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); -+ if (!ret) -+ return 0; -+ -+ nand_release(mtd); -+ return -EINVAL; -+} -+ -+static int bcm2835_smi_nand_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_smi_nand_host *host = platform_get_drvdata(pdev); -+ -+ nand_release(&host->mtd); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_smi_nand_of_match[] = { -+ {.compatible = "brcm,bcm2835-smi-nand",}, -+ { /* sentinel */ } -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_smi_nand_of_match); -+ -+static struct platform_driver bcm2835_smi_nand_driver = { -+ .probe = bcm2835_smi_nand_probe, -+ .remove = bcm2835_smi_nand_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_smi_nand_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_smi_nand_driver); -+ -+MODULE_ALIAS("platform:smi-nand-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION -+ ("Driver for NAND chips using Broadcom Secondary Memory Interface"); -+MODULE_AUTHOR("Luke Wren "); - -From a3bf36473505511198d71fdf19e6b28b4ee55195 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 16 Sep 2015 17:28:41 +0100 -Subject: [PATCH 184/204] BCM270X_DT: Document SMI overlay - ---- - arch/arm/boot/dts/overlays/Makefile | 6 +++--- - arch/arm/boot/dts/overlays/README | 18 ++++++++++++++++++ - 2 files changed, 21 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index dfd23a1..192bda7 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,9 +13,6 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -@@ -48,6 +45,9 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0aa5aa1..4ab4c695 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -530,6 +530,24 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - debug Enable debug output (default off) - - -+Name: smi -+Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! -+Load: dtoverlay=smi -+Params: -+ -+ -+Name: smi-dev -+Info: Enables the userspace interface for the SMI driver -+Load: dtoverlay=smi-dev -+Params: -+ -+ -+Name: smi-nand -+Info: Enables access to NAND flash via the SMI interface -+Load: dtoverlay=smi-nand -+Params: -+ -+ - Name: spi-bcm2708 - Info: Selects the bcm2708-spi SPI driver - Load: dtoverlay=spi-bcm2708 - -From 24a9683edd38171e27a170b95a42133c2bd3890f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Sep 2015 17:13:42 +0100 -Subject: [PATCH 185/204] dwc_otg: Force host mode to fix incorrect compute - module boards - ---- - drivers/usb/host/dwc_otg/dwc_otg_cil.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c -index e40060f..beaa8b3 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_cil.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c -@@ -192,7 +192,7 @@ dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr) - core_if->hptxfsiz.d32 = - DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); - gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); -- gusbcfg.b.force_host_mode = 0; -+ gusbcfg.b.force_host_mode = 1; - DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); - dwc_mdelay(100); } + + device_unregister(&d->gadget.dev); +@@ -1275,86 +1277,4 @@ void pcd_remove(dwc_bus_dev_t *_dev) + otg_dev->pcd = 0; + } + +-/** +- * This function registers a gadget driver with the PCD. +- * +- * When a driver is successfully registered, it will receive control +- * requests including set_configuration(), which enables non-control +- * requests. then usb traffic follows until a disconnect is reported. +- * then a host may connect again, or the driver might get unbound. +- * +- * @param driver The driver being registered +- * @param bind The bind function of gadget driver +- */ +- +-int usb_gadget_probe_driver(struct usb_gadget_driver *driver) +-{ +- int retval; +- +- DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", +- driver->driver.name); +- +- if (!driver || driver->max_speed == USB_SPEED_UNKNOWN || +- !driver->bind || +- !driver->unbind || !driver->disconnect || !driver->setup) { +- DWC_DEBUGPL(DBG_PCDV, "EINVAL\n"); +- return -EINVAL; +- } +- if (gadget_wrapper == 0) { +- DWC_DEBUGPL(DBG_PCDV, "ENODEV\n"); +- return -ENODEV; +- } +- if (gadget_wrapper->driver != 0) { +- DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver); +- return -EBUSY; +- } +- +- /* hook up the driver */ +- gadget_wrapper->driver = driver; +- gadget_wrapper->gadget.dev.driver = &driver->driver; +- +- DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name); +- retval = driver->bind(&gadget_wrapper->gadget, gadget_wrapper->driver); +- if (retval) { +- DWC_ERROR("bind to driver %s --> error %d\n", +- driver->driver.name, retval); +- gadget_wrapper->driver = 0; +- gadget_wrapper->gadget.dev.driver = 0; +- return retval; +- } +- DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n", +- driver->driver.name); +- return 0; +-} +-EXPORT_SYMBOL(usb_gadget_probe_driver); +- +-/** +- * This function unregisters a gadget driver +- * +- * @param driver The driver being unregistered +- */ +-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +-{ +- //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); +- +- if (gadget_wrapper == 0) { +- DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__, +- -ENODEV); +- return -ENODEV; +- } +- if (driver == 0 || driver != gadget_wrapper->driver) { +- DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__, +- -EINVAL); +- return -EINVAL; +- } +- +- driver->unbind(&gadget_wrapper->gadget); +- gadget_wrapper->driver = 0; +- +- DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name); +- return 0; +-} +- +-EXPORT_SYMBOL(usb_gadget_unregister_driver); +- + #endif /* DWC_HOST_ONLY */ -From 4f8563760264a9aedad6fec09e8adb8c3929c1a3 Mon Sep 17 00:00:00 2001 +From 0ae54a1f7e53f7f8b7e491ca96295c7d14e6d89c Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Tue, 15 Sep 2015 15:16:24 +0100 -Subject: [PATCH 186/204] config: Add CIFS_DFS_UPCALL, CIFS_ACL, CIFS_SMB2, - CIFS_FSCACHE +Date: Wed, 21 Oct 2015 23:36:07 +0100 +Subject: [PATCH 101/113] config: remove CONFIG_CPU_SW_DOMAIN_PAN it causes + panics --- - arch/arm/configs/bcm2709_defconfig | 4 ++++ - arch/arm/configs/bcmrpi_defconfig | 4 ++++ - 2 files changed, 8 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index c7671bf..60f8357 100644 +index 66a1c1399..b87e731 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -1167,6 +1167,10 @@ CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_SMB2=y -+CONFIG_CIFS_FSCACHE=y - CONFIG_9P_FS=m - CONFIG_9P_FS_POSIX_ACL=y - CONFIG_NLS_DEFAULT="utf8" +@@ -47,6 +47,7 @@ CONFIG_VMSPLIT_2G=y + CONFIG_PREEMPT=y + CONFIG_AEABI=y + CONFIG_OABI_COMPAT=y ++# CONFIG_CPU_SW_DOMAIN_PAN is not set + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y + CONFIG_CMA=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 75fa1d0..8ebc8d5 100644 +index 3e1ac5a..64a169d 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1160,6 +1160,10 @@ CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_SMB2=y -+CONFIG_CIFS_FSCACHE=y - CONFIG_9P_FS=m - CONFIG_9P_FS_POSIX_ACL=y - CONFIG_NLS_DEFAULT="utf8" +@@ -42,6 +42,7 @@ CONFIG_BCM2708_DT=y + CONFIG_PREEMPT=y + CONFIG_AEABI=y + CONFIG_OABI_COMPAT=y ++# CONFIG_CPU_SW_DOMAIN_PAN is not set + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y + CONFIG_CMA=y -From dee40d2ad759e6f0d9737f15c9c00a9149d55b73 Mon Sep 17 00:00:00 2001 -From: David Lechner -Date: Mon, 14 Sep 2015 19:08:36 -0500 -Subject: [PATCH 187/204] Use dts-dirs feature for overlays. - -The kernel makefiles have a dts-dirs target that is for vendor subdirectories. - -Using this fixes the install_dtbs target, which previously did not install the overlays. ---- - arch/arm/boot/dts/Makefile | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 12de305..faf293f 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -15,6 +15,9 @@ endif - ifeq ($(CONFIG_ARCH_BCM2835),y) - RPI_DT_OVERLAYS=y - endif -+ifeq ($(RPI_DT_OVERLAYS),y) -+ dts-dirs += overlays -+endif - - dtb-$(CONFIG_ARCH_ALPINE) += \ - alpine-db.dtb -@@ -683,11 +686,10 @@ targets += $(dtb-y) - endif - - always := $(dtb-y) -+subdir-y := $(dts-dirs) - clean-files := *.dtb - - # Enable fixups to support overlays on BCM2708 platforms - ifeq ($(RPI_DT_OVERLAYS),y) - DTC_FLAGS ?= -@ - endif -- --subdir-y += overlays - -From 51ccad4fd102f2eb4d2a8115ff2a06ec01676acd Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 10 Sep 2015 09:32:14 +0000 -Subject: [PATCH 192/204] backport: spi: bcm2835: BUG: fix wrong use of - PAGE_MASK - -There is a bug in the alignment checking of transfers, -that results in DMA not being used for un-aligned -transfers that do not cross page-boundries, which is valid. - -This is due to a missconception of the meaning PAGE_MASK -when implementing that check originally - (PAGE_SIZE - 1) -should have been used instead. - -Also fixes a copy/paste error. - -Reported-by: -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -Cc: stable@vger.kernel.org ---- - drivers/spi/spi-bcm2835.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index b68991c..3835332 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, - /* otherwise we only allow transfers within the same page - * to avoid wasting time on dma_mapping when it is not practical - */ -- if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { -+ if (((size_t)tfr->tx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); - return false; - } -- if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { -+ if (((size_t)tfr->rx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, -- "Unaligned spi tx-transfer bridging page\n"); -+ "Unaligned spi rx-transfer bridging page\n"); - return false; - } - - -From 16e92c1ffaf2b25fc3b410ba8e1dc6a457b645f7 Mon Sep 17 00:00:00 2001 -From: Stuart MacLean -Date: Fri, 2 Oct 2015 15:12:59 +0100 -Subject: [PATCH 193/204] Add support for the HiFiBerry DAC+ Pro. - -The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. - -An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. ---- - .../dts/overlays/hifiberry-dacplus-overlay.dts | 15 +- - drivers/clk/Makefile | 1 + - drivers/clk/clk-hifiberry-dacpro.c | 160 ++++++++++++++ - sound/soc/bcm/hifiberry_dacplus.c | 244 +++++++++++++++++++-- - sound/soc/codecs/pcm512x.c | 3 +- - 5 files changed, 396 insertions(+), 27 deletions(-) - create mode 100644 drivers/clk/clk-hifiberry-dacpro.c - -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -index deb9c625..f923a48 100644 ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -6,6 +6,16 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -+ target-path = "/clocks"; -+ __overlay__ { -+ dacpro_osc: dacpro_osc { -+ compatible = "hifiberry,dacpro-clk"; -+ #clock-cells = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { - target = <&sound>; - __overlay__ { - compatible = "hifiberry,hifiberry-dacplus"; -@@ -14,14 +24,14 @@ - }; - }; - -- fragment@1 { -+ fragment@2 { - target = <&i2s>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -32,6 +42,7 @@ - #sound-dai-cells = <0>; - compatible = "ti,pcm5122"; - reg = <0x4d>; -+ clocks = <&dacpro_osc>; - status = "okay"; - }; - }; -diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index 3d00c25..f949266 100644 ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o - obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o - obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o - obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o - obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o - obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o - obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o -diff --git a/drivers/clk/clk-hifiberry-dacpro.c b/drivers/clk/clk-hifiberry-dacpro.c -new file mode 100644 -index 0000000..3e35d45 ---- /dev/null -+++ b/drivers/clk/clk-hifiberry-dacpro.c -@@ -0,0 +1,160 @@ -+/* -+ * Clock Driver for HiFiBerry DAC Pro -+ * -+ * Author: Stuart MacLean -+ * Copyright 2015 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+/** -+ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro -+ * @hw: clk_hw for the common clk framework -+ * @mode: 0 => CLK44EN, 1 => CLK48EN -+ */ -+struct clk_hifiberry_hw { -+ struct clk_hw hw; -+ uint8_t mode; -+}; -+ -+#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) -+ -+static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { -+ { .compatible = "hifiberry,dacpro-clk",}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); -+ -+static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : -+ CLK_48EN_RATE; -+} -+ -+static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long *parent_rate) -+{ -+ long actual_rate; -+ -+ if (rate <= CLK_44EN_RATE) { -+ actual_rate = (long)CLK_44EN_RATE; -+ } else if (rate >= CLK_48EN_RATE) { -+ actual_rate = (long)CLK_48EN_RATE; -+ } else { -+ long diff44Rate = (long)(rate - CLK_44EN_RATE); -+ long diff48Rate = (long)(CLK_48EN_RATE - rate); -+ -+ if (diff44Rate < diff48Rate) -+ actual_rate = (long)CLK_44EN_RATE; -+ else -+ actual_rate = (long)CLK_48EN_RATE; -+ } -+ return actual_rate; -+} -+ -+ -+static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ unsigned long actual_rate; -+ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); -+ -+ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, -+ &parent_rate); -+ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; -+ return 0; -+} -+ -+ -+const struct clk_ops clk_hifiberry_dacpro_rate_ops = { -+ .recalc_rate = clk_hifiberry_dacpro_recalc_rate, -+ .round_rate = clk_hifiberry_dacpro_round_rate, -+ .set_rate = clk_hifiberry_dacpro_set_rate, -+}; -+ -+static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct clk_hifiberry_hw *proclk; -+ struct clk *clk; -+ struct device *dev; -+ struct clk_init_data init; -+ -+ dev = &pdev->dev; -+ -+ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); -+ if (!proclk) -+ return -ENOMEM; -+ -+ init.name = "clk-hifiberry-dacpro"; -+ init.ops = &clk_hifiberry_dacpro_rate_ops; -+ init.flags = CLK_IS_ROOT | CLK_IS_BASIC; -+ init.parent_names = NULL; -+ init.num_parents = 0; -+ -+ proclk->mode = 0; -+ proclk->hw.init = &init; -+ -+ clk = devm_clk_register(dev, &proclk->hw); -+ if (!IS_ERR(clk)) { -+ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, -+ clk); -+ } else { -+ dev_err(dev, "Fail to register clock driver\n"); -+ kfree(proclk); -+ ret = PTR_ERR(clk); -+ } -+ return ret; -+} -+ -+static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) -+{ -+ of_clk_del_provider(pdev->dev.of_node); -+ return 0; -+} -+ -+static struct platform_driver clk_hifiberry_dacpro_driver = { -+ .probe = clk_hifiberry_dacpro_probe, -+ .remove = clk_hifiberry_dacpro_remove, -+ .driver = { -+ .name = "clk-hifiberry-dacpro", -+ .of_match_table = clk_hifiberry_dacpro_dt_ids, -+ }, -+}; -+ -+static int __init clk_hifiberry_dacpro_init(void) -+{ -+ return platform_driver_register(&clk_hifiberry_dacpro_driver); -+} -+core_initcall(clk_hifiberry_dacpro_init); -+ -+static void __exit clk_hifiberry_dacpro_exit(void) -+{ -+ platform_driver_unregister(&clk_hifiberry_dacpro_driver); -+} -+module_exit(clk_hifiberry_dacpro_exit); -+ -+MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:clk-hifiberry-dacpro"); -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index 11e4f39..a6b651c 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -1,8 +1,8 @@ - /* -- * ASoC Driver for HiFiBerry DAC+ -+ * ASoC Driver for HiFiBerry DAC+ / DAC Pro - * -- * Author: Daniel Matuschek -- * Copyright 2014 -+ * Author: Daniel Matuschek, Stuart MacLean -+ * Copyright 2014-2015 - * based on code by Florian Meier - * - * This program is free software; you can redistribute it and/or -@@ -17,6 +17,13 @@ - - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - #include - #include -@@ -26,34 +33,222 @@ - - #include "../codecs/pcm512x.h" - -+#define HIFIBERRY_DACPRO_NOCLOCK 0 -+#define HIFIBERRY_DACPRO_CLK44EN 1 -+#define HIFIBERRY_DACPRO_CLK48EN 2 -+ -+struct pcm512x_priv { -+ struct regmap *regmap; -+ struct clk *sclk; -+}; -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+static bool snd_rpi_hifiberry_is_dacpro; -+ -+static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, -+ int clk_id) -+{ -+ switch (clk_id) { -+ case HIFIBERRY_DACPRO_NOCLOCK: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); -+ break; -+ case HIFIBERRY_DACPRO_CLK44EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); -+ break; -+ case HIFIBERRY_DACPRO_CLK48EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); -+ break; -+ } -+} -+ -+static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec) -+{ -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec) -+{ -+ int sck; -+ -+ sck = snd_soc_read(codec, PCM512x_RATE_DET_4); -+ return (!(sck & 0x40)); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( -+ struct snd_soc_codec *codec) -+{ -+ msleep(2); -+ return snd_rpi_hifiberry_dacplus_is_sclk(codec); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec) -+{ -+ bool isClk44EN, isClk48En, isNoClk; -+ -+ snd_rpi_hifiberry_dacplus_clk_gpio(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN); -+ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK); -+ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN); -+ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ return (isClk44EN && isClk48En && !isNoClk); -+} -+ -+static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate) -+{ -+ int type; -+ -+ switch (sample_rate) { -+ case 11025: -+ case 22050: -+ case 44100: -+ case 88200: -+ case 176400: -+ type = HIFIBERRY_DACPRO_CLK44EN; -+ break; -+ default: -+ type = HIFIBERRY_DACPRO_CLK48EN; -+ break; -+ } -+ return type; -+} -+ -+static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec, -+ int sample_rate) -+{ -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ -+ if (!IS_ERR(pcm512x->sclk)) { -+ int ctype; -+ -+ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate); -+ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) -+ ? CLK_44EN_RATE : CLK_48EN_RATE); -+ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype); -+ } -+} -+ - static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) - { - struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *priv; -+ -+ snd_rpi_hifiberry_is_dacpro -+ = snd_rpi_hifiberry_dacplus_is_pro_card(codec); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_dai_link *dai = rtd->dai_link; -+ -+ dai->name = "HiFiBerry DAC+ Pro"; -+ dai->stream_name = "HiFiBerry DAC+ Pro HiFi"; -+ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBM_CFM; -+ -+ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); -+ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03); -+ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); -+ } else { -+ priv = snd_soc_codec_get_drvdata(codec); -+ priv->sclk = ERR_PTR(-ENOENT); -+ } -+ - snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -- snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_update_rate_den( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ struct snd_ratnum *rats_no_pll; -+ unsigned int num = 0, den = 0; -+ int err; -+ -+ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); -+ if (!rats_no_pll) -+ return -ENOMEM; -+ -+ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; -+ rats_no_pll->den_min = 1; -+ rats_no_pll->den_max = 128; -+ rats_no_pll->den_step = 1; -+ -+ err = snd_interval_ratnum(hw_param_interval(params, -+ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); -+ if (err >= 0 && den) { -+ params->rate_num = num; -+ params->rate_den = den; -+ } -+ -+ devm_kfree(rtd->dev, rats_no_pll); - return 0; - } - --static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params) -+static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro( -+ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params) - { -+ int bratio = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio); -+} -+ -+static int snd_rpi_hifiberry_dacplus_hw_params( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -- return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ snd_rpi_hifiberry_dacplus_set_sclk(codec, -+ params_rate(params)); -+ -+ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai, -+ params); -+ if (!ret) -+ ret = snd_rpi_hifiberry_dacplus_update_rate_den( -+ substream, params); -+ } else { -+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ } -+ return ret; - } - --static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+static int snd_rpi_hifiberry_dacplus_startup( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); - return 0; - } - --static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { -+static void snd_rpi_hifiberry_dacplus_shutdown( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); - } - - /* machine stream operations */ -@@ -90,19 +285,20 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -- - if (pdev->dev.of_node) { -- struct device_node *i2s_node; -- struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -- i2s_node = of_parse_phandle(pdev->dev.of_node, -- "i2s-controller", 0); -- -- if (i2s_node) { -- dai->cpu_dai_name = NULL; -- dai->cpu_of_node = i2s_node; -- dai->platform_name = NULL; -- dai->platform_of_node = i2s_node; -- } -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai; -+ -+ dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } - } - - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); -diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c -index e12764d..8d16b2f 100644 ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -856,7 +856,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, - int fssp; - int gpio; - -- lrclk_div = snd_soc_params_to_frame_size(params); -+ lrclk_div = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); - if (lrclk_div == 0) { - dev_err(dev, "No LRCLK?\n"); - return -EINVAL; - -From f1c2c5ab06e1597d0aa0593c5dec52cf580332e3 Mon Sep 17 00:00:00 2001 +From a32ae7cd9db25a303aad442c459a69841add7220 Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 194/204] rpi_display: add backlight driver and overlay +Subject: [PATCH 102/113] rpi_display: add backlight driver and overlay Add a mailbox-driven backlight controller for the Raspberry Pi DSI touchscreen display. Requires updated GPU firmware to recognise the @@ -150272,7 +140623,7 @@ Signed-off-by: Gordon Hollingworth create mode 100644 drivers/video/backlight/rpi_backlight.c diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 192bda7..2e82be5 100644 +index 9411ec8..2236c85 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -38,6 +38,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb @@ -150284,7 +140635,7 @@ index 192bda7..2e82be5 100644 dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4ab4c695..b57bd11 100644 +index 6a9b270..dd1dad2 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -463,6 +463,12 @@ Load: dtoverlay=raspidac3 @@ -150328,10 +140679,10 @@ index 0000000..c021d02 + }; +}; diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 60f8357..6f4021b 100644 +index b87e731..39769f2 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -802,6 +802,7 @@ CONFIG_FB_BCM2708=y +@@ -803,6 +803,7 @@ CONFIG_FB_BCM2708=y CONFIG_FB_SSD1307=m CONFIG_FB_RPISENSE=m # CONFIG_BACKLIGHT_GENERIC is not set @@ -150340,10 +140691,10 @@ index 60f8357..6f4021b 100644 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 8ebc8d5..015540b 100644 +index 64a169d..abbe478 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -795,6 +795,7 @@ CONFIG_FB_BCM2708=y +@@ -796,6 +796,7 @@ CONFIG_FB_BCM2708=y CONFIG_FB_SSD1307=m CONFIG_FB_RPISENSE=m # CONFIG_BACKLIGHT_GENERIC is not set @@ -150352,10 +140703,10 @@ index 8ebc8d5..015540b 100644 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig -index 2d9923a..78d02bd 100644 +index 5ffa4b4..c3023ab 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig -@@ -263,6 +263,12 @@ config BACKLIGHT_PWM +@@ -265,6 +265,12 @@ config BACKLIGHT_PWM If you have a LCD backlight adjustable by PWM, say Y to enable this driver. @@ -150369,12 +140720,12 @@ index 2d9923a..78d02bd 100644 tristate "Backlight Driver for DA9030/DA9034 using WLED" depends on PMIC_DA903X diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile -index d67073f..e36907a 100644 +index 16ec534..00eff87 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile -@@ -49,6 +49,7 @@ obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o - obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o +@@ -50,6 +50,7 @@ obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o + obj-$(CONFIG_BACKLIGHT_PM8941_WLED) += pm8941-wled.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o +obj-$(CONFIG_BACKLIGHT_RPI) += rpi_backlight.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o @@ -150517,674 +140868,498 @@ index d3933af..ffb0f82 100644 RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, +From 7a91c278bb2ef86a66020fa12edcbbb5d1948bc1 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 12 Oct 2015 12:18:14 +0200 +Subject: [PATCH 104/113] BCM270X_DT: configure I2S DMA channels - -From ed66fe22cf07f1240e693bf6e7628ac9c42d36d4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 6 Oct 2015 10:16:58 +0100 -Subject: [PATCH 196/204] bcm2835-gpiomem: Fix for ARCH_BCM2835 builds - -Build on ARCH_BCM2835, and fail to probe if no IO resource. - -See: https://github.com/raspberrypi/linux/issues/1154 +Signed-off-by: Matthias Reichl --- - drivers/char/broadcom/bcm2835-gpiomem.c | 25 ++++++++++--------------- - 1 file changed, 10 insertions(+), 15 deletions(-) + arch/arm/boot/dts/bcm2708_common.dtsi | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) -diff --git a/drivers/char/broadcom/bcm2835-gpiomem.c b/drivers/char/broadcom/bcm2835-gpiomem.c -index 0085e13..911f5b7 100644 ---- a/drivers/char/broadcom/bcm2835-gpiomem.c -+++ b/drivers/char/broadcom/bcm2835-gpiomem.c -@@ -143,7 +143,6 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) - int err; - void *ptr_err; - struct device *dev = &pdev->dev; -- struct device_node *node = dev->of_node; - struct resource *ioresource; +diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi +index 5d9081a..73f2db1e 100644 +--- a/arch/arm/boot/dts/bcm2708_common.dtsi ++++ b/arch/arm/boot/dts/bcm2708_common.dtsi +@@ -119,8 +119,7 @@ + reg = <0x7e203000 0x24>, + <0x7e101098 0x08>; - /* Allocate buffers and instance data */ -@@ -157,6 +156,15 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) +- //dmas = <&dma 2>, +- // <&dma 3>; ++ dmas = <&dma 2>, <&dma 3>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + +From f4db2c33a3793419315f95b4ecfa9eb526c1a1fa Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 16:44:05 +0200 +Subject: [PATCH 105/113] bcm2835-i2s: get base address for DMA from devicetree + +Code copied from spi-bcm2835. Get physical address from devicetree +instead of using hardcoded constant. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 5a75f4b..11c209d 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include - inst->dev = dev; + #include + #include +@@ -158,10 +159,6 @@ static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { + #define BCM2835_I2S_INT_RXR BIT(1) + #define BCM2835_I2S_INT_TXW BIT(0) -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (ioresource) { -+ inst->gpio_regs_phys = ioresource->start; -+ } else { -+ dev_err(inst->dev, "failed to get IO resource"); -+ err = -ENOENT; -+ goto failed_get_resource; +-/* I2S DMA interface */ +-/* FIXME: Needs IOMMU support */ +-#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000) +- + /* General device struct */ + struct bcm2835_i2s_dev { + struct device *dev; +@@ -791,6 +788,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + int ret; + struct regmap *regmap[2]; + struct resource *mem[2]; ++ const __be32 *addr; ++ dma_addr_t dma_reg_base; ++ ++ addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); ++ if (!addr) { ++ dev_err(&pdev->dev, "could not get DMA-register address\n"); ++ return -ENODEV; + } -+ - /* Create character device entries */ ++ dma_reg_base = be32_to_cpup(addr); - err = alloc_chrdev_region(&bcm2835_gpiomem_devid, -@@ -187,20 +195,6 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) - if (IS_ERR(ptr_err)) - goto failed_device_create; + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { +@@ -817,12 +823,10 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) -- /* Get address from device tree if available (*_resource() correctly -- converts the bus address in device tree to a physical address), -- or use hardcoded offset + BCM2708_PERI_BASE if not. -- (In spite of its name 2708 actually seems to have the correct -- mach-dependent value on 2709 etc, as it is defined in -- mach-bcm270x/platform.h) */ -- -- if (node) { -- ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- inst->gpio_regs_phys = ioresource->start; -- } else { -- inst->gpio_regs_phys = GPIO_BASE; -- } -- - dev_info(inst->dev, "Initialised: Registers at 0x%08lx", - inst->gpio_regs_phys); + /* Set the DMA address */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = +- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG +- + BCM2835_VCMMU_SHIFT; ++ dma_reg_base + BCM2835_I2S_FIFO_A_REG; -@@ -214,6 +208,7 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) - failed_cdev_add: - unregister_chrdev_region(bcm2835_gpiomem_devid, 1); - failed_alloc_chrdev: -+failed_get_resource: - kfree(inst); - failed_inst_alloc: - dev_err(inst->dev, "could not load bcm2835_gpiomem"); - -From 9223ca1be3362490e689e00156fa792e04910284 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 5 Oct 2015 10:47:45 +0100 -Subject: [PATCH 197/204] BCM270X_DT: Add at86rf233 overlay - -Add an overlay to support the Atmel AT86RF233 WPAN transceiver on spi0.0. - -See: https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 21 +++++++-- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 54 ++++++++++++++++++++++++ - 3 files changed, 72 insertions(+), 4 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 2e82be5..b370eb0 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = +- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG +- + BCM2835_VCMMU_SHIFT; ++ dma_reg_base + BCM2835_I2S_FIFO_A_REG; - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index b57bd11..014675a 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -69,13 +69,14 @@ DT parameters: - - Parameters always have default values, although in some cases (e.g. "w1-gpio") - it is necessary to provided multiple overlays in order to get the desired --behaviour. See the list of overlays below for a description of the parameters and their defaults. -+behaviour. See the list of overlays below for a description of the parameters -+and their defaults. - - The Overlay and Parameter Reference - =================================== - --N.B. When editing this file, please preserve the indentation levels to make it simple to parse --programmatically. NO HARD TABS. -+N.B. When editing this file, please preserve the indentation levels to make it -+simple to parse programmatically. NO HARD TABS. - - - Name: -@@ -149,7 +150,7 @@ Name: ads7846 - Info: ADS7846 Touch controller - Load: dtoverlay=ads7846,= - Params: cs SPI bus Chip Select (default 1) -- speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) - penirq GPIO used for PENIRQ. REQUIRED - penirq_pull Set GPIO pull (default 0=none, 2=pullup) - swapxy Swap x and y axis -@@ -170,6 +171,18 @@ Params: cs SPI bus Chip Select (default 1) - www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt - - -+Name: at86rf233 -+Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, -+ connected to spi0.0 -+Load: dtoverlay=at86rf233,= -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 750000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) -+ -+ - Name: bmp085_i2c-sensor - Info: Configures the BMP085/BMP180 digital barometric pressure and temperature - sensors from Bosch Sensortec -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -new file mode 100644 -index 0000000..70f50ea ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -0,0 +1,54 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ lowpan0: at86rf233@0 { -+ compatible = "atmel,at86rf233"; -+ reg = <0>; -+ interrupt-parent = <&gpio>; -+ interrupts = <23 4>; /* active high */ -+ reset-gpio = <&gpio 24 1>; -+ sleep-gpio = <&gpio 25 1>; -+ spi-max-frequency = <7500000>; -+ xtal-trim = /bits/ 8 <0xf>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lowpan0_pins: lowpan0_pins { -+ brcm,pins = <23 24 25>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ interrupt = <&lowpan0>, "interrupts:0", -+ <&lowpan0_pins>, "brcm,pins:0"; -+ reset = <&lowpan0>, "reset-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:4"; -+ sleep = <&lowpan0>, "sleep-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:8"; -+ speed = <&lowpan0>, "spi-max-frequency:0"; -+ trim = <&lowpan0>, "xtal-trim.0"; -+ }; -+}; + /* Set the bus width */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = -From c089bd70a6d37cb4a05626d48eaebcdfcef0bf41 Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Sun, 18 Oct 2015 17:07:24 -0700 -Subject: [PATCH 198/204] New overlay for PiScreen2r +From bbdb22a1df4ba9153fca8c50fb3d9ee464936044 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:13:35 +0200 +Subject: [PATCH 106/113] configs: enable SND_BCM2835_SOC_I2S ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 +++ - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 100 ++++++++++++++++++++++ - 3 files changed, 115 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index b370eb0..f4b2817 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -34,6 +34,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 014675a..3276312 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -411,6 +411,20 @@ Params: speed Display SPI bus speed - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: piscreen2r -+Info: PiScreen 2 with resistive TP display by OzzMaker.com -+Load: dtoverlay=piscreen,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= -diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -new file mode 100644 -index 0000000..7c018e0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -0,0 +1,100 @@ -+ /* -+ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen2_pins: piscreen2_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen2: piscreen2@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen2_pins>; -+ bgr; -+ spi-max-frequency = <64000000>; -+ rotate = <90>; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ txbuflen = <32768>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c0 0x11 0x09 -+ 0x10000c1 0x41 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000b6 0x00 0x02 -+ 0x10000f7 0xa9 0x51 0x2c 0x2 -+ 0x10000be 0x00 0x04 -+ 0x10000e9 0x00 -+ 0x1000011 -+ 0x1000029>; -+ -+ }; -+ -+ piscreen2_ts: piscreen2-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,swap-xy; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen2>,"spi-max-frequency:0"; -+ rotate = <&piscreen2>,"rotate:0"; -+ fps = <&piscreen2>,"fps:0"; -+ debug = <&piscreen2>,"debug:0"; -+ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -+ - -From 30a73891df28c2922fcad40317f474914ccf4434 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 9 Oct 2015 10:49:00 +0100 -Subject: [PATCH 199/204] BCM270X_DT: Make mmc overlay compatible with current - firmware - -The original DT overlay logic followed a merge-then-patch procedure, -i.e. parameters are applied to the loaded overlay before the overlay -is merged into the base DTB. This sequence has been changed to -patch-then-merge, in order to support parameterised node names, and -to protect against bad overlays. As a result, overrides (parameters) -must only target labels in the overlay, but the overlay can obviously target nodes in the base DTB. - -mmc-overlay.dts (that switches back to the original mmc sdcard -driver) is the only overlay violating that rule, and this patch -fixes it. ---- - arch/arm/boot/dts/overlays/mmc-overlay.dts | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts -index 0a37cf4..4579ff2 100644 ---- a/arch/arm/boot/dts/overlays/mmc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -7,13 +7,13 @@ - fragment@0 { - target = <&mmc>; - -- __overlay__ { -+ frag0: __overlay__ { - brcm,overclock-50 = <0>; - }; - }; - - __overrides__ { -- overclock_50 = <&mmc>,"brcm,overclock-50:0"; -- force_pio = <&mmc>,"brcm,force-pio?"; -+ overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; - }; - }; - -From 25dc64a6491a98e8df7b387e54dfe1d2be1ea5e8 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 12 Oct 2015 08:52:00 +0100 -Subject: [PATCH 200/204] BCM270X_DT: Reduce default at86rf233 SPI frequency - -The AT86RF233 has been found to be unreliable on a 7.5MHz SPI bus, -so reduce the default frequency to 6MHz. - -See: https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/README | 2 +- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 3276312..42a5876 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -178,7 +178,7 @@ Load: dtoverlay=at86rf233,= - Params: interrupt GPIO used for INT (default 23) - reset GPIO used for Reset (default 24) - sleep GPIO used for Sleep (default 25) -- speed SPI bus speed in Hz (default 750000) -+ speed SPI bus speed in Hz (default 6000000) - trim Fine tuning of the internal capacitance - arrays (0=+0pF, 15=+4.5pF, default 15) - -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -index 70f50ea..0460269 100644 ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -25,7 +25,7 @@ - interrupts = <23 4>; /* active high */ - reset-gpio = <&gpio 24 1>; - sleep-gpio = <&gpio 25 1>; -- spi-max-frequency = <7500000>; -+ spi-max-frequency = <6000000>; - xtal-trim = /bits/ 8 <0xf>; - }; - }; - -From 625d90e2f7b2de52e0ba82e66e076915402e9c8b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 1 Oct 2015 11:49:11 +0100 -Subject: [PATCH 201/204] config: Add CONFIG_UHID +Allow bcm2835-i2s compilation on BCM270x and enable in bcm2709_defconfig +and bcmrpi_defconfig +Signed-off-by: Matthias Reichl --- arch/arm/configs/bcm2709_defconfig | 1 + arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) + sound/soc/bcm/Kconfig | 2 +- + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6f4021b..6a914fb 100644 +index 39769f2..e4df400 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -843,6 +843,7 @@ CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y -+CONFIG_UHID=m - CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m +@@ -830,6 +830,7 @@ CONFIG_SND_USB_CAIAQ=m + CONFIG_SND_USB_CAIAQ_INPUT=y + CONFIG_SND_USB_6FIRE=m + CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 015540b..7a477e3 100644 +index abbe478..84aeada 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -836,6 +836,7 @@ CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y -+CONFIG_UHID=m - CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m +@@ -823,6 +823,7 @@ CONFIG_SND_USB_CAIAQ=m + CONFIG_SND_USB_CAIAQ_INPUT=y + CONFIG_SND_USB_6FIRE=m + CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index f465dd2..fd3aaa4 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -1,6 +1,6 @@ + config SND_BCM2835_SOC_I2S + tristate "SoC Audio support for the Broadcom BCM2835 I2S module" +- depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on ARCH_BCM2835 || MACH_BCM2708 || MACH_BCM2709 || COMPILE_TEST + select SND_SOC_GENERIC_DMAENGINE_PCM + select REGMAP_MMIO + help -From 7a8dc0c298b4619fe8658481d0b3ae0ac1231a5e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 4 Oct 2015 12:30:01 +0100 -Subject: [PATCH 202/204] config: Add CONFIG_CRYPTO_USER_API_SKCIPHER +From 48ce0895d05eefded0897a67ec03aeefacaf42f1 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:21:16 +0200 +Subject: [PATCH 107/113] bcm2835-i2s: add 24bit support, update bclk_ratio to + more correct values +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit 62c05a0b5328d9376d39c9e74da10b8a2465c234 ("ASoC: BCM2708: +Add 24 bit support") + +This adds 24 bit support to the I2S driver of the BCM2708. +Besides enabling the 24 bit flags, it includes two bug fixes: + +MMAP is not supported. Claiming this leads to strange issues +when the format of driver and file do not match. + +The datasheet states that the width extension bit should be set +for widths greater than 24, but greater or equal would be correct. +This follows from the definition of the width field. + +Signed-off-by: Florian Meier + +RPi commit 3e8c672bc4e92d457aa4654bbb4cfd79a18a2327 ("bcm2708-i2s: +Update bclk_ratio to more correct values") + +Discussion about blck_ratio affecting sound quality: +https://github.com/raspberrypi/linux/issues/681 + +Signed-off-by: Matthias Reichl --- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) + sound/soc/bcm/bcm2835-i2s.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6a914fb..05383c0 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1239,6 +1239,7 @@ CONFIG_CRYPTO_WP512=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_USER_API_SKCIPHER=m - # CONFIG_CRYPTO_HW is not set - CONFIG_ARM_CRYPTO=y - CONFIG_CRYPTO_SHA1_ARM_NEON=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 7a477e3..0f315d8 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1235,6 +1235,7 @@ CONFIG_CRYPTO_WP512=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_USER_API_SKCIPHER=m - # CONFIG_CRYPTO_HW is not set - CONFIG_ARM_CRYPTO=y - CONFIG_CRYPTO_SHA1_ARM=m - -From c7158fd021cf31f5fb67768796aecabde5ff6727 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 4 Oct 2015 12:36:44 +0100 -Subject: [PATCH 203/204] config: Add options for supporting openlabs 802.15.4 - radio - ---- - arch/arm/configs/bcm2709_defconfig | 6 ++++++ - arch/arm/configs/bcmrpi_defconfig | 6 ++++++ - 2 files changed, 12 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 05383c0..fb402e8 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -283,6 +283,9 @@ CONFIG_VLAN_8021Q=m - CONFIG_VLAN_8021Q_GVRP=y - CONFIG_ATALK=m - CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_CBQ=m - CONFIG_NET_SCH_HTB=m -@@ -529,6 +532,9 @@ CONFIG_ZD1211RW=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m - CONFIG_INPUT_POLLDEV=m - # CONFIG_INPUT_MOUSEDEV_PSAUX is not set - CONFIG_INPUT_JOYDEV=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0f315d8..eb81555e 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -276,6 +276,9 @@ CONFIG_VLAN_8021Q=m - CONFIG_VLAN_8021Q_GVRP=y - CONFIG_ATALK=m - CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_CBQ=m - CONFIG_NET_SCH_HTB=m -@@ -522,6 +525,9 @@ CONFIG_ZD1211RW=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m - CONFIG_INPUT_POLLDEV=m - # CONFIG_INPUT_MOUSEDEV_PSAUX is not set - CONFIG_INPUT_JOYDEV=m - -From 6c1d6379ed6d95956ba255936da39f06543ddb7f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 8 Oct 2015 13:33:28 +0100 -Subject: [PATCH 204/204] scripts/mkknlimg: Improve ARCH_BCM2835 detection - -The board support code contains sufficient strings to be able to -distinguish 2708 vs. 2835 builds, so remove the check for -bcm2835-pm-wdt which could exist in either. - -Also, since the canned configuration is no longer built in (it's -a module), remove the config string checking. - -See: https://github.com/raspberrypi/linux/issues/1157 ---- - scripts/mkknlimg | 41 +++++------------------------------------ - 1 file changed, 5 insertions(+), 36 deletions(-) - -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -index 3dff948..3998d43 100755 ---- a/scripts/mkknlimg -+++ b/scripts/mkknlimg -@@ -50,12 +50,6 @@ if (! -r $kernel_file) - usage(); - } +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 11c209d..1c44a34 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -340,11 +340,15 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + data_length = 16; +- bclk_ratio = 40; ++ bclk_ratio = 50; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ data_length = 24; ++ bclk_ratio = 50; + break; + case SNDRV_PCM_FORMAT_S32_LE: + data_length = 32; +- bclk_ratio = 80; ++ bclk_ratio = 100; + break; + default: + return -EINVAL; +@@ -420,7 +424,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + /* Setup the frame format */ + format = BCM2835_I2S_CHEN; --my @wanted_config_lines = --( -- 'CONFIG_BCM2708_DT', -- 'CONFIG_ARCH_BCM2835' --); +- if (data_length > 24) ++ if (data_length >= 24) + format |= BCM2835_I2S_CHWEX; + + format |= BCM2835_I2S_CHWID((data_length-8)&0xf); +@@ -711,6 +715,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE + | SNDRV_PCM_FMTBIT_S32_LE + }, + .capture = { +@@ -718,6 +723,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE + | SNDRV_PCM_FMTBIT_S32_LE + }, + .ops = &bcm2835_i2s_dai_ops, + +From baab4d800282582ca2c1b17a469fcebbd951f07a Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:25:51 +0200 +Subject: [PATCH 108/113] bcm2835-i2s: setup clock only if CPU is clock master + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit c14827ecdaa36607f6110f9ce8df96e698672191 ("bcm2708: Allow +option card devices to be configured via DT") + +Original work by Zoltan Szenczi, committed to RPi tree by +Phil Elwell. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 1c44a34..2a5d9d6 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -411,15 +411,25 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + divf = dividend & BCM2835_CLK_DIVF_MASK; + } + +- /* Set clock divider */ +- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD +- | BCM2835_CLK_DIVI(divi) +- | BCM2835_CLK_DIVF(divf)); - - my @wanted_strings = - ( - 'bcm2708_fb', -@@ -63,7 +57,8 @@ my @wanted_strings = - 'brcm,bcm2835-sdhost', - 'brcm,bcm2708-pinctrl', - 'brcm,bcm2835-gpio', -- 'brcm,bcm2835-pm-wdt' -+ 'brcm,bcm2835', -+ 'brcm,bcm2836' - ); +- /* Setup clock, but don't start it yet */ +- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD +- | BCM2835_CLK_MASH(mash) +- | BCM2835_CLK_SRC(clk_src)); ++ /* Clock should only be set up here if CPU is clock master */ ++ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ case SND_SOC_DAIFMT_CBS_CFM: ++ /* Set clock divider */ ++ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, ++ BCM2835_CLK_PASSWD ++ | BCM2835_CLK_DIVI(divi) ++ | BCM2835_CLK_DIVF(divf)); ++ ++ /* Setup clock, but don't start it yet */ ++ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, ++ BCM2835_CLK_PASSWD ++ | BCM2835_CLK_MASH(mash) ++ | BCM2835_CLK_SRC(clk_src)); ++ break; ++ default: ++ break; ++ } - my $res = try_extract($kernel_file, $tmpfile1); -@@ -98,12 +93,11 @@ if ($res) - config_bool($res, 'brcm,bcm2835-mmc') || - config_bool($res, 'brcm,bcm2835-sdhost')) + /* Setup the frame format */ + format = BCM2835_I2S_CHEN; + +From 2d1ce550ee0c8fc1dd65d9ccc8091b85d9f3da62 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:49:51 +0200 +Subject: [PATCH 109/113] bcm2835-i2s: Eliminate debugfs directory error + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit fd7d7a3dbe9262d16971ef81c234ed28c6499dd7 ("bcm2708: +Eliminate i2s debugfs directory error") + +Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') +to avoid the name clash when registering debugfs entries. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 2a5d9d6..8db6d90 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -782,6 +782,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { + .precious_reg = bcm2835_i2s_precious_reg, + .volatile_reg = bcm2835_i2s_volatile_reg, + .cache_type = REGCACHE_RBTREE, ++ .name = "i2s", + }, { -- $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); -- $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); - $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); - $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); -- $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); -- $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt'); -+ $is_283x ||= config_bool($res, 'brcm,bcm2835'); -+ $is_283x ||= config_bool($res, 'brcm,bcm2836'); -+ $dtok ||= $is_283x; - $append_trailer = 1; - } - else -@@ -205,31 +199,6 @@ sub try_extract - $res->{$match} = 1; + .reg_bits = 32, +@@ -790,6 +791,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { + .max_register = BCM2835_CLK_PCMDIV_REG, + .volatile_reg = bcm2835_clk_volatile_reg, + .cache_type = REGCACHE_RBTREE, ++ .name = "clk", + }, + }; + + +From 905fbd8a8a81de4cec733e92e3bf99f9c7ccad2e Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:35:20 +0200 +Subject: [PATCH 110/113] bcm2835-i2s: Register PCM device + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit ba46b4935a23aa2caac1855ead52a035d4776680 ("ASoC: Add +support for BCM2708") + +This driver adds support for digital audio (I2S) +for the BCM2708 SoC that is used by the +Raspberry Pi. External audio codecs can be +connected to the Raspberry Pi via P5 header. + +It relies on cyclic DMA engine support for BCM2708. + +Signed-off-by: Florian Meier + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 8db6d90..6ce6c3f 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -799,6 +799,25 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { + .name = "bcm2835-i2s-comp", + }; + ++static const struct snd_pcm_hardware bcm2835_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_JOINT_DUPLEX, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE, ++ .period_bytes_min = 32, ++ .period_bytes_max = 64 * PAGE_SIZE, ++ .periods_min = 2, ++ .periods_max = 255, ++ .buffer_bytes_max = 128 * PAGE_SIZE, ++}; ++ ++static const struct snd_dmaengine_pcm_config bcm2835_dmaengine_pcm_config = { ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++ .pcm_hardware = &bcm2835_pcm_hardware, ++ .prealloc_buffer_size = 256 * PAGE_SIZE, ++}; ++ + static int bcm2835_i2s_probe(struct platform_device *pdev) + { + struct bcm2835_i2s_dev *dev; +@@ -870,7 +889,9 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + return ret; } -- my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$'; -- my $cf1 = 'IKCFG_ST\037\213\010'; -- my $cf2 = '0123456789'; -- -- my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`; -- if ($pos) -- { -- $pos =~ s/:.*[\r\n]*$//s; -- $pos += 8; -- my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8); -- if (($err == 0) || ($err == 2)) -- { -- if (open(my $fh, '<', $tmp)) -- { -- while (my $line = <$fh>) -- { -- chomp($line); -- $res->{$1} = $2 if ($line =~ /$config_pattern/); -- } -- -- close($fh); -- } -- } -- } -- - return $res; - } +- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); ++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, ++ &bcm2835_dmaengine_pcm_config, ++ SND_DMAENGINE_PCM_FLAG_COMPAT); + if (ret) { + dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); + return ret; + +From 7cf1bac3f8f5fc8d41f4598a4245f1d0e9974742 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:55:21 +0200 +Subject: [PATCH 111/113] bcm2835-i2s: Enable MMAP support via a DT property + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit 7ee829fd77a30127db5d0b3c7d79b8718166e568 ("bcm2708-i2s: +Enable MMAP support via a DT property and overlay") + +The i2s driver used to claim to support MMAP, but that feature was disabled +when some problems were found. Add the ability to enable this feature +through Device Tree, using the i2s-mmap overlay. + +See: #1004 + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 6ce6c3f..2a6334b 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -799,7 +799,7 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { + .name = "bcm2835-i2s-comp", + }; +-static const struct snd_pcm_hardware bcm2835_pcm_hardware = { ++static struct snd_pcm_hardware bcm2835_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_JOINT_DUPLEX, + .formats = SNDRV_PCM_FMTBIT_S16_LE | +@@ -835,6 +835,11 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + } + dma_reg_base = be32_to_cpup(addr); + ++ if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) ++ bcm2835_pcm_hardware.info |= ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID; ++ + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { + void __iomem *base; + +From 5178cffda1705dcc2735c4d59b8b9165d97e1aa6 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 12 Oct 2015 12:19:16 +0200 +Subject: [PATCH 112/113] BCM270X_DT: switch to bcm2835-i2s + +I2S soundcard drivers with proper devicetree support (i.e. not linking +to the cpu_dai/platform via name but to cpu/platform via of_node) +will work out of the box without any modifications. + +When the kernel is compiled without devicetree support the platform +code will instantiate the bcm2708-i2s driver and I2S soundcard drivers +will link to it via name, as before. + +Signed-off-by: Matthias Reichl +--- + arch/arm/boot/dts/bcm2708_common.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi +index 73f2db1e..c658c7b 100644 +--- a/arch/arm/boot/dts/bcm2708_common.dtsi ++++ b/arch/arm/boot/dts/bcm2708_common.dtsi +@@ -115,7 +115,7 @@ + }; + + i2s: i2s@7e203000 { +- compatible = "brcm,bcm2708-i2s"; ++ compatible = "brcm,bcm2835-i2s"; + reg = <0x7e203000 0x24>, + <0x7e101098 0x08>; + + +From 59d68c0263ecaa076d524c8a5667da285e318434 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Wed, 14 Oct 2015 13:14:02 +0200 +Subject: [PATCH 113/113] config: fix RaspiDAC Rev.3x dependencies + +Change depends to SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +like the other I2S soundcard drivers. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index fd3aaa4..794ff7a 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -70,7 +70,7 @@ config SND_BCM2708_SOC_IQAUDIO_DAC + + config SND_BCM2708_SOC_RASPIDAC3 + tristate "Support for RaspiDAC Rev.3x" +- depends on SND_BCM2708_SOC_I2S ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_PCM512x_I2C + select SND_SOC_TPA6130A2 + help diff --git a/projects/RPi2/linux/linux.arm.conf b/projects/RPi2/linux/linux.arm.conf index d3d17ea315..5332420757 100644 --- a/projects/RPi2/linux/linux.arm.conf +++ b/projects/RPi2/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.1.8 Kernel Configuration +# Linux/arm 4.3.0 Kernel Configuration # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -9,6 +9,7 @@ CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_NEED_DMA_MAP_STATE=y @@ -94,17 +95,11 @@ CONFIG_TICK_CPU_ACCOUNTING=y # RCU Subsystem # CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y # CONFIG_TASKS_RCU is not set CONFIG_RCU_STALL_COMMON=y -# CONFIG_RCU_USER_QS is not set -CONFIG_RCU_FANOUT=32 -CONFIG_RCU_FANOUT_LEAF=16 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set # CONFIG_TREE_RCU_TRACE is not set -CONFIG_RCU_KTHREAD_PRIO=0 -# CONFIG_RCU_NOCB_CPU is not set # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m @@ -115,6 +110,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set # CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_PIDS is not set # CONFIG_CGROUP_DEVICE is not set # CONFIG_CPUSETS is not set # CONFIG_CGROUP_CPUACCT is not set @@ -162,6 +158,8 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y # CONFIG_AIO is not set CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_MEMBARRIER=y CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y @@ -177,11 +175,12 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_SLUB_CPU_PARTIAL=y -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_DATA_VERIFICATION is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set # CONFIG_UPROBES is not set # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -210,6 +209,7 @@ CONFIG_CC_STACKPROTECTOR_NONE=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_MODULES_USE_ELF_REL=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_CLONE_BACKWARDS=y @@ -365,7 +365,6 @@ CONFIG_MIGHT_HAVE_CACHE_L2X0=y CONFIG_ARM_L1_CACHE_SHIFT_6=y CONFIG_ARM_L1_CACHE_SHIFT=6 CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARCH_HAS_BARRIERS=y # CONFIG_ARM_KERNMEM_PERMS is not set # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set @@ -429,7 +428,9 @@ CONFIG_AEABI=y # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set CONFIG_HAVE_ARCH_PFN_VALID=y # CONFIG_HIGHMEM is not set +# CONFIG_CPU_SW_DOMAIN_PAN is not set CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_MEMBLOCK=y @@ -454,6 +455,8 @@ CONFIG_CMA_AREAS=7 # CONFIG_ZPOOL is not set # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_ALIGNMENT_TRAP=y CONFIG_UACCESS_WITH_MEMCPY=y @@ -504,6 +507,7 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y # CPU frequency scaling drivers # # CONFIG_CPUFREQ_DT is not set +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set CONFIG_ARM_BCM2835_CPUFREQ=y # CONFIG_QORIQ_CPUFREQ is not set @@ -581,7 +585,6 @@ CONFIG_IP_MROUTE=y # CONFIG_NET_UDP_TUNNEL is not set # CONFIG_NET_FOU is not set # CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_GENEVE is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set @@ -603,6 +606,7 @@ CONFIG_IPV6=y # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set # CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set @@ -627,6 +631,7 @@ CONFIG_NETFILTER_ADVANCED=y # # Core Netfilter Configuration # +# CONFIG_NETFILTER_INGRESS is not set CONFIG_NETFILTER_NETLINK=m # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set @@ -743,6 +748,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m # CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_DUP_IPV4 is not set # CONFIG_NF_LOG_ARP is not set # CONFIG_NF_LOG_IPV4 is not set CONFIG_NF_REJECT_IPV4=m @@ -770,6 +776,7 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m # CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_NF_DUP_IPV6 is not set CONFIG_NF_REJECT_IPV6=m # CONFIG_NF_LOG_IPV6 is not set CONFIG_NF_NAT_IPV6=m @@ -850,6 +857,7 @@ CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y # CONFIG_BT_BNEP is not set CONFIG_BT_HIDP=m +CONFIG_BT_HS=y CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set # CONFIG_BT_DEBUGFS is not set @@ -859,8 +867,10 @@ CONFIG_BT_LE=y # CONFIG_BT_INTEL=m CONFIG_BT_BCM=m +CONFIG_BT_RTL=m CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set CONFIG_BT_HCIBCM203X=m @@ -897,12 +907,14 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set CONFIG_HAVE_BPF_JIT=y # @@ -956,10 +968,6 @@ CONFIG_CMA_ALIGNMENT=8 # CONFIG_MTD is not set CONFIG_DTC=y CONFIG_OF=y - -# -# Device Tree and Open Firmware support -# # CONFIG_OF_UNITTEST is not set CONFIG_OF_FLATTREE=y CONFIG_OF_EARLY_FLATTREE=y @@ -982,7 +990,6 @@ CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MG_DISK is not set @@ -1041,6 +1048,10 @@ CONFIG_BCM2708_VCHIQ=y # Intel MIC Bus Driver # +# +# SCIF Bus Driver +# + # # Intel MIC Host Driver # @@ -1048,8 +1059,14 @@ CONFIG_BCM2708_VCHIQ=y # # Intel MIC Card Driver # + +# +# SCIF Driver +# # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set # # SCSI device support @@ -1109,6 +1126,7 @@ CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y CONFIG_TUN=y +# CONFIG_TUN_VNET_CROSS_LE is not set # CONFIG_VETH is not set # CONFIG_NLMON is not set @@ -1127,6 +1145,7 @@ CONFIG_PHYLIB=y # # MII PHY device drivers # +# CONFIG_AQUANTIA_PHY is not set # CONFIG_AT803X_PHY is not set # CONFIG_AMD_PHY is not set # CONFIG_MARVELL_PHY is not set @@ -1135,6 +1154,7 @@ CONFIG_PHYLIB=y # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_BCM7XXX_PHY is not set @@ -1145,6 +1165,9 @@ CONFIG_PHYLIB=y # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set # CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set # CONFIG_MDIO_BUS_MUX_GPIO is not set @@ -1168,6 +1191,7 @@ CONFIG_USB_NET_DRIVERS=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set CONFIG_USB_RTL8152=m +# CONFIG_USB_LAN78XX is not set CONFIG_USB_USBNET=y CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_AX88179_178A=m @@ -1195,6 +1219,7 @@ CONFIG_USB_NET_RNDIS_HOST=m # CONFIG_USB_IPHETH is not set # CONFIG_USB_SIERRA_NET is not set # CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set CONFIG_WLAN=y # CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_AT76C50X_USB is not set @@ -1298,6 +1323,7 @@ CONFIG_ZD1211RW=m # Input device support # CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_SPARSEKMAP is not set @@ -1347,7 +1373,7 @@ CONFIG_JOYSTICK_XPAD_LEDS=y # CONFIG_JOYSTICK_RPISENSE is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_OF_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_TOUCHSCREEN_ADS7846=m # CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879 is not set @@ -1375,6 +1401,7 @@ CONFIG_TOUCHSCREEN_EGALAX=m # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set @@ -1383,6 +1410,7 @@ CONFIG_TOUCHSCREEN_RPI_FT5406=m # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set # CONFIG_TOUCHSCREEN_WM97XX is not set CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_TOUCHSCREEN_USB_EGALAX=y @@ -1435,6 +1463,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set # @@ -1446,6 +1475,13 @@ CONFIG_INPUT_UINPUT=y # # Character devices # +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM_VC_CMA=y +CONFIG_BCM2708_VCMEM=y +CONFIG_BCM_VCIO=y +CONFIG_BCM_VC_SM=y +CONFIG_BCM2835_DEVGPIOMEM=m +CONFIG_BCM2835_SMI_DEV=m CONFIG_TTY=y CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y @@ -1476,6 +1512,7 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_SCCNXP is not set @@ -1489,6 +1526,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_FSL_LPUART is not set # CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set # CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_STM32 is not set # CONFIG_TTY_PRINTK is not set # CONFIG_HVC_DCC is not set # CONFIG_IPMI_HANDLER is not set @@ -1499,13 +1537,6 @@ CONFIG_HW_RANDOM_BCM2708=m # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BCM_VC_CMA=y -CONFIG_BCM2708_VCMEM=y -CONFIG_BCM_VCIO=y -CONFIG_BCM_VC_SM=y -CONFIG_BCM2835_DEVGPIOMEM=m -CONFIG_BCM2835_SMI_DEV=m # CONFIG_XILLYBUS is not set # @@ -1525,6 +1556,7 @@ CONFIG_I2C_MUX=m # CONFIG_I2C_MUX_PCA9541 is not set # CONFIG_I2C_MUX_PCA954x is not set # CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=y @@ -1540,6 +1572,7 @@ CONFIG_I2C_BCM2708_BAUDRATE=100000 # CONFIG_I2C_BCM2835 is not set # CONFIG_I2C_CBUS_GPIO is not set # CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_EMEV2 is not set CONFIG_I2C_GPIO=y # CONFIG_I2C_NOMADIK is not set # CONFIG_I2C_OCORES is not set @@ -1587,6 +1620,7 @@ CONFIG_SPI_BCM2708=m # CONFIG_SPI_SC18IS602 is not set # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set # CONFIG_SPI_DESIGNWARE is not set # @@ -1669,6 +1703,7 @@ CONFIG_GPIO_ARIZONA=m # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_ZX is not set # # USB GPIO expanders @@ -1715,9 +1750,12 @@ CONFIG_POWER_SUPPLY=y # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_BQ2415X is not set # CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set # CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set # CONFIG_POWER_RESET is not set # CONFIG_POWER_AVS is not set CONFIG_HWMON=y @@ -1824,6 +1862,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set # CONFIG_SENSORS_TMP103 is not set @@ -1842,20 +1881,19 @@ CONFIG_HWMON=y CONFIG_THERMAL=y CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_GOV_FAIR_SHARE is not set CONFIG_THERMAL_GOV_STEP_WISE=y # CONFIG_THERMAL_GOV_BANG_BANG is not set # CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set # CONFIG_CPU_THERMAL is not set # CONFIG_THERMAL_EMULATION is not set CONFIG_THERMAL_BCM2835=y - -# -# Texas Instruments thermal drivers -# CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -1920,6 +1958,7 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_DA9052_I2C is not set # CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set @@ -1994,6 +2033,7 @@ CONFIG_MFD_ARIZONA_SPI=m CONFIG_MFD_WM5102=y # CONFIG_MFD_WM5110 is not set # CONFIG_MFD_WM8997 is not set +# CONFIG_MFD_WM8998 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X_I2C is not set # CONFIG_MFD_WM831X_SPI is not set @@ -2159,6 +2199,7 @@ CONFIG_VIDEO_EM28XX_RC=m # CONFIG_V4L_PLATFORM_DRIVERS is not set # CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set # # Supported MMC/SDIO adapters @@ -2268,7 +2309,6 @@ CONFIG_MEDIA_TUNER_R820T=m # # Multistandard (satellite) frontends # -CONFIG_DVB_CX24120=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m @@ -2299,6 +2339,7 @@ CONFIG_DVB_TUNER_ITD1000=m CONFIG_DVB_TUNER_CX24113=m CONFIG_DVB_TDA826X=m CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m CONFIG_DVB_DS3000=m @@ -2386,10 +2427,6 @@ CONFIG_DVB_AF9033=m # # Graphics support # - -# -# Direct Rendering Manager -# # CONFIG_DRM is not set # @@ -2459,6 +2496,7 @@ CONFIG_SND_HRTIMER=m CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_MAX_CARDS=32 # CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -2474,6 +2512,7 @@ CONFIG_SND_AC97_CODEC=m # # HD-Audio # +CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_ARM=y # CONFIG_SND_ARMAACI is not set CONFIG_SND_BCM2835=m @@ -2494,6 +2533,7 @@ CONFIG_SND_USB_VARIAX=m CONFIG_SND_SOC=m CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m @@ -2518,13 +2558,13 @@ CONFIG_SND_BCM2708_SOC_RASPIDAC3=m # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set -# CONFIG_SND_SOC_QCOM is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # +# CONFIG_SND_SOC_AC97_CODEC is not set # CONFIG_SND_SOC_ADAU1701 is not set # CONFIG_SND_SOC_AK4104 is not set # CONFIG_SND_SOC_AK4554 is not set @@ -2541,8 +2581,10 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_CS4271_I2C is not set # CONFIG_SND_SOC_CS4271_SPI is not set # CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_HDMI_CODEC is not set # CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_GTM601 is not set # CONFIG_SND_SOC_PCM1681 is not set # CONFIG_SND_SOC_PCM1792A is not set CONFIG_SND_SOC_PCM512x=m @@ -2560,8 +2602,10 @@ CONFIG_SND_SOC_PCM5102A=m # CONFIG_SND_SOC_SSM4567 is not set CONFIG_SND_SOC_STA32X=m # CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set # CONFIG_SND_SOC_TAS2552 is not set # CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set # CONFIG_SND_SOC_TFA9879 is not set CONFIG_SND_SOC_TAS5713=m # CONFIG_SND_SOC_TLV320AIC23_I2C is not set @@ -2622,6 +2666,7 @@ CONFIG_DRAGONRISE_FF=y # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_GEMBIRD is not set # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set @@ -2705,6 +2750,7 @@ CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set CONFIG_USB_MON=m # CONFIG_USB_WUSB_CBAF is not set @@ -2890,6 +2936,7 @@ CONFIG_MMC_BCM2835_SDHOST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set # CONFIG_MMC_SDHCI_F_SDH30 is not set # CONFIG_MMC_SPI is not set # CONFIG_MMC_DW is not set @@ -2897,6 +2944,7 @@ CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set CONFIG_MMC_REALTEK_USB=m +# CONFIG_MMC_MTK is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -2905,6 +2953,9 @@ CONFIG_LEDS_CLASS_FLASH=y # # LED drivers # +# CONFIG_LEDS_AAT1290 is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set # CONFIG_LEDS_LM3530 is not set # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_PCA9532 is not set @@ -2921,13 +2972,14 @@ CONFIG_LEDS_GPIO=y # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set # CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set # CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_KTD2692 is not set # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set -# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -2948,12 +3000,14 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_LEDS_TRIGGER_CAMERA is not set CONFIG_LEDS_TRIGGER_INPUT=y # CONFIG_ACCESSIBILITY is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y # CONFIG_EDAC is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set CONFIG_RTC_SYSTOHC=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" # CONFIG_RTC_DEBUG is not set # @@ -3030,6 +3084,7 @@ CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set # # on-CPU RTC drivers @@ -3037,7 +3092,6 @@ CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_PL030 is not set # CONFIG_RTC_DRV_PL031 is not set # CONFIG_RTC_DRV_SNVS is not set -# CONFIG_RTC_DRV_XGENE is not set # # HID Sensor RTC drivers @@ -3049,16 +3103,17 @@ CONFIG_DMADEVICES=y # # DMA Devices # -# CONFIG_AMBA_PL08X is not set -# CONFIG_DW_DMAC is not set -# CONFIG_PL330_DMA is not set -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2708_LEGACY=y -# CONFIG_FSL_EDMA is not set -# CONFIG_NBPFAXI_DMA is not set CONFIG_DMA_ENGINE=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +# CONFIG_PL330_DMA is not set +CONFIG_DMA_BCM2708=y +CONFIG_DMA_BCM2708_LEGACY=y +# CONFIG_DW_DMAC is not set # # DMA Clients @@ -3106,7 +3161,7 @@ CONFIG_LIRC_XBOX=m # # Android # -# CONFIG_USB_WPAN_HCD is not set +# CONFIG_STAGING_BOARD is not set # CONFIG_WIMAX_GDM72XX is not set # CONFIG_LTE_GDM724X is not set # CONFIG_LUSTRE_FS is not set @@ -3114,6 +3169,7 @@ CONFIG_LIRC_XBOX=m # CONFIG_GS_FPGABOOT is not set # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set # CONFIG_FB_TFT is not set +# CONFIG_MOST is not set # CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y @@ -3124,6 +3180,7 @@ CONFIG_COMMON_CLK=y # # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_CLK_QORIQ is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set @@ -3138,6 +3195,7 @@ CONFIG_COMMON_CLK=y CONFIG_CLKSRC_OF=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_TIMER_SP804 is not set # CONFIG_ATMEL_PIT is not set # CONFIG_SH_TIMER_CMT is not set # CONFIG_SH_TIMER_MTU2 is not set @@ -3162,6 +3220,7 @@ CONFIG_BCM2835_MBOX=y # # SOC (System On Chip) specific Drivers # +# CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set CONFIG_EXTCON=m @@ -3186,14 +3245,22 @@ CONFIG_IRQCHIP=y # PHY Subsystem # # CONFIG_GENERIC_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_POWERCAP is not set # CONFIG_MCB is not set +# +# Performance monitor support +# +# CONFIG_RAS is not set + # # Android # # CONFIG_ANDROID is not set +# CONFIG_NVMEM is not set # # Firmware Drivers @@ -3208,7 +3275,7 @@ CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set # CONFIG_EXT4_ENCRYPTION is not set @@ -3287,6 +3354,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -3481,6 +3549,7 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHED_INFO is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set @@ -3516,8 +3585,8 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 -# CONFIG_RCU_CPU_STALL_INFO is not set # CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set @@ -3551,6 +3620,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set # CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -3595,13 +3665,17 @@ CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +# CONFIG_CRYPTO_RSA is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_NULL2=y # CONFIG_CRYPTO_PCRYPT is not set CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set @@ -3614,7 +3688,9 @@ CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m # # Block modes @@ -3642,6 +3718,7 @@ CONFIG_CRYPTO_CRC32C=y # CONFIG_CRYPTO_CRC32 is not set # CONFIG_CRYPTO_CRCT10DIF is not set CONFIG_CRYPTO_GHASH=m +# CONFIG_CRYPTO_POLY1305 is not set CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -3669,6 +3746,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_TEA is not set @@ -3680,6 +3758,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set @@ -3687,15 +3766,27 @@ CONFIG_CRYPTO_LZO=m # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_DRBG_MENU is not set +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m # CONFIG_CRYPTO_USER_API_HASH is not set # CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set # CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set CONFIG_ARM_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM=m CONFIG_CRYPTO_SHA256_ARM=m +# CONFIG_CRYPTO_SHA512_ARM is not set CONFIG_CRYPTO_AES_ARM=m # CONFIG_BINARY_PRINTF is not set @@ -3750,7 +3841,6 @@ CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_AVERAGE=y # CONFIG_CORDIC is not set # CONFIG_DDR is not set CONFIG_LIBFDT=y @@ -3759,5 +3849,6 @@ CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set # CONFIG_ARCH_HAS_SG_CHAIN is not set # CONFIG_VIRTUALIZATION is not set diff --git a/projects/RPi2/patches/linux/linux-01-RPi_support.patch b/projects/RPi2/patches/linux/linux-01-RPi_support.patch index 32cf12da6a..af2d4b60b2 100644 --- a/projects/RPi2/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi2/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,724 @@ -From 5e9c268f96c85ea7722958b1f6f73c8d13a822dc Mon Sep 17 00:00:00 2001 +From 1ac297ca77f1fbe846e51e484f1c3ba490154fe4 Mon Sep 17 00:00:00 2001 +From: Steve Glendinning +Date: Thu, 19 Feb 2015 18:47:12 +0000 +Subject: [PATCH 001/113] smsx95xx: fix crimes against truesize + +smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. + +This patch stops smsc95xx from changing truesize. + +Signed-off-by: Steve Glendinning +--- + drivers/net/usb/smsc95xx.c | 2 -- + 1 file changed, 2 deletions(-) + mode change 100644 => 100755 drivers/net/usb/smsc95xx.c + +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +old mode 100644 +new mode 100755 +index 26423ad..fbc72ec6 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -1785,7 +1785,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + if (dev->net->features & NETIF_F_RXCSUM) + smsc95xx_rx_csum_offload(skb); + skb_trim(skb, skb->len - 4); /* remove fcs */ +- skb->truesize = size + sizeof(struct sk_buff); + + return 1; + } +@@ -1803,7 +1802,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + if (dev->net->features & NETIF_F_RXCSUM) + smsc95xx_rx_csum_offload(ax_skb); + skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ +- ax_skb->truesize = size + sizeof(struct sk_buff); + + usbnet_skb_return(dev, ax_skb); + } + +From 977a6619f5303a58bd4e2b34229638d530ff1d39 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 Apr 2015 16:58:45 +0100 +Subject: [PATCH 002/113] smsc95xx: Disable turbo mode by default + +--- + drivers/net/usb/smsc95xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index fbc72ec6..477b9c7 100755 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -70,7 +70,7 @@ struct smsc95xx_priv { + u8 suspend_flags; + }; + +-static bool turbo_mode = true; ++static bool turbo_mode = false; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + + +From 0d5dbc68901771e0bdd60bb79c8a6c0a101abb95 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 18 Jun 2014 13:42:01 +0100 +Subject: [PATCH 003/113] vmstat: Workaround for issue where dirty page count + goes negative + +See: +https://github.com/raspberrypi/linux/issues/617 +http://www.spinics.net/lists/linux-mm/msg72236.html +--- + include/linux/vmstat.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h +index 82e7db7..f87d16d 100644 +--- a/include/linux/vmstat.h ++++ b/include/linux/vmstat.h +@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + { + atomic_long_dec(&zone->vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) ++ atomic_long_set(&zone->vm_stat[item], 0); + atomic_long_dec(&vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) ++ atomic_long_set(&vm_stat[item], 0); + } + + static inline void __inc_zone_page_state(struct page *page, + +From 15c41e58ff73c75b44d6f916e87f5586a5ab4f19 Mon Sep 17 00:00:00 2001 +From: Robert Tiemann +Date: Mon, 20 Jul 2015 11:01:25 +0200 +Subject: [PATCH 004/113] BCM2835_DT: Fix I2S register map + +--- + Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- + Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 4 ++-- + arch/arm/boot/dts/bcm2835.dtsi | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt +index 1396078..2db8294 100644 +--- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt ++++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt +@@ -48,8 +48,8 @@ Example: + + bcm2835_i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; +- reg = < 0x7e203000 0x20>, +- < 0x7e101098 0x02>; ++ reg = < 0x7e203000 0x24>, ++ < 0x7e101098 0x08>; + + dmas = <&dma 2>, + <&dma 3>; +diff --git a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt +index 65783de..a89fe42 100644 +--- a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt ++++ b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt +@@ -16,8 +16,8 @@ Example: + + bcm2835_i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x20>, +- <0x7e101098 0x02>; ++ reg = <0x7e203000 0x24>, ++ <0x7e101098 0x08>; + + dmas = <&dma 2>, + <&dma 3>; +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index 301c73f..440717c 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -102,8 +102,8 @@ + + i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x20>, +- <0x7e101098 0x02>; ++ reg = <0x7e203000 0x24>, ++ <0x7e101098 0x08>; + + dmas = <&dma 2>, + <&dma 3>; + +From 1123fea13563a412b29a0e71e173130307c84b16 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 4 Jun 2015 13:11:46 -0700 +Subject: [PATCH 005/113] ARM: bcm2835: Add the Raspberry Pi firmware driver + +This gives us a function for making mailbox property channel requests +of the firmware, which is most notable in that it will let us get and +set clock rates. + +Signed-off-by: Eric Anholt +--- + drivers/firmware/Kconfig | 7 + + drivers/firmware/Makefile | 1 + + drivers/firmware/raspberrypi.c | 260 +++++++++++++++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 115 +++++++++++++ + 4 files changed, 383 insertions(+) + create mode 100644 drivers/firmware/raspberrypi.c + create mode 100644 include/soc/bcm2835/raspberrypi-firmware.h + +diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig +index 665efca..7181126 100644 +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -147,6 +147,13 @@ config QCOM_SCM_64 + def_bool y + depends on QCOM_SCM && ARM64 + ++config RASPBERRYPI_FIRMWARE ++ tristate "Raspberry Pi Firmware Driver" ++ depends on BCM2835_MBOX ++ help ++ This option enables support for communicating with the firmware on the ++ Raspberry Pi. ++ + source "drivers/firmware/broadcom/Kconfig" + source "drivers/firmware/google/Kconfig" + source "drivers/firmware/efi/Kconfig" +diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile +index 2ee8347..8f9049d 100644 +--- a/drivers/firmware/Makefile ++++ b/drivers/firmware/Makefile +@@ -16,6 +16,7 @@ obj-$(CONFIG_QCOM_SCM) += qcom_scm.o + obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o + obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o + CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) ++obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o + + obj-y += broadcom/ + obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ +diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c +new file mode 100644 +index 0000000..dd506cd3 +--- /dev/null ++++ b/drivers/firmware/raspberrypi.c +@@ -0,0 +1,260 @@ ++/* ++ * Defines interfaces for interacting wtih the Raspberry Pi firmware's ++ * property channel. ++ * ++ * Copyright © 2015 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) ++#define MBOX_CHAN(msg) ((msg) & 0xf) ++#define MBOX_DATA28(msg) ((msg) & ~0xf) ++#define MBOX_CHAN_PROPERTY 8 ++ ++struct rpi_firmware { ++ struct mbox_client cl; ++ struct mbox_chan *chan; /* The property channel. */ ++ struct completion c; ++ u32 enabled; ++}; ++ ++static DEFINE_MUTEX(transaction_lock); ++ ++static void response_callback(struct mbox_client *cl, void *msg) ++{ ++ struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); ++ complete(&fw->c); ++} ++ ++/* ++ * Sends a request to the firmware through the BCM2835 mailbox driver, ++ * and synchronously waits for the reply. ++ */ ++static int ++rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) ++{ ++ u32 message = MBOX_MSG(chan, data); ++ int ret; ++ ++ WARN_ON(data & 0xf); ++ ++ mutex_lock(&transaction_lock); ++ reinit_completion(&fw->c); ++ ret = mbox_send_message(fw->chan, &message); ++ if (ret >= 0) { ++ wait_for_completion(&fw->c); ++ ret = 0; ++ } else { ++ dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); ++ } ++ mutex_unlock(&transaction_lock); ++ ++ return ret; ++} ++ ++/** ++ * rpi_firmware_property_list - Submit firmware property list ++ * @fw: Pointer to firmware structure from rpi_firmware_get(). ++ * @data: Buffer holding tags. ++ * @tag_size: Size of tags buffer. ++ * ++ * Submits a set of concatenated tags to the VPU firmware through the ++ * mailbox property interface. ++ * ++ * The buffer header and the ending tag are added by this function and ++ * don't need to be supplied, just the actual tags for your operation. ++ * See struct rpi_firmware_property_tag_header for the per-tag ++ * structure. ++ */ ++int rpi_firmware_property_list(struct rpi_firmware *fw, ++ void *data, size_t tag_size) ++{ ++ size_t size = tag_size + 12; ++ u32 *buf; ++ dma_addr_t bus_addr; ++ int ret; ++ ++ /* Packets are processed a dword at a time. */ ++ if (size & 3) ++ return -EINVAL; ++ ++ buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, ++ GFP_ATOMIC); ++ if (!buf) ++ return -ENOMEM; ++ ++ /* The firmware will error out without parsing in this case. */ ++ WARN_ON(size >= 1024 * 1024); ++ ++ buf[0] = size; ++ buf[1] = RPI_FIRMWARE_STATUS_REQUEST; ++ memcpy(&buf[2], data, tag_size); ++ buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END; ++ wmb(); ++ ++ ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr); ++ ++ rmb(); ++ memcpy(data, &buf[2], tag_size); ++ if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) { ++ /* ++ * The tag name here might not be the one causing the ++ * error, if there were multiple tags in the request. ++ * But single-tag is the most common, so go with it. ++ */ ++ dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", ++ buf[2], buf[1]); ++ ret = -EINVAL; ++ } ++ ++ dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(rpi_firmware_property_list); ++ ++/** ++ * rpi_firmware_property - Submit single firmware property ++ * @fw: Pointer to firmware structure from rpi_firmware_get(). ++ * @tag: One of enum_mbox_property_tag. ++ * @tag_data: Tag data buffer. ++ * @buf_size: Buffer size. ++ * ++ * Submits a single tag to the VPU firmware through the mailbox ++ * property interface. ++ * ++ * This is a convenience wrapper around ++ * rpi_firmware_property_list() to avoid some of the ++ * boilerplate in property calls. ++ */ ++int rpi_firmware_property(struct rpi_firmware *fw, ++ u32 tag, void *tag_data, size_t buf_size) ++{ ++ /* Single tags are very small (generally 8 bytes), so the ++ * stack should be safe. ++ */ ++ u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)]; ++ struct rpi_firmware_property_tag_header *header = ++ (struct rpi_firmware_property_tag_header *)data; ++ int ret; ++ ++ header->tag = tag; ++ header->buf_size = buf_size; ++ header->req_resp_size = 0; ++ memcpy(data + sizeof(struct rpi_firmware_property_tag_header), ++ tag_data, buf_size); ++ ++ ret = rpi_firmware_property_list(fw, &data, sizeof(data)); ++ memcpy(tag_data, ++ data + sizeof(struct rpi_firmware_property_tag_header), ++ buf_size); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(rpi_firmware_property); ++ ++static void ++rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) ++{ ++ u32 packet; ++ int ret = rpi_firmware_property(fw, ++ RPI_FIRMWARE_GET_FIRMWARE_REVISION, ++ &packet, sizeof(packet)); ++ ++ if (ret == 0) { ++ struct tm tm; ++ ++ time_to_tm(packet, 0, &tm); ++ ++ dev_info(fw->cl.dev, ++ "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min); ++ } ++} ++ ++static int rpi_firmware_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rpi_firmware *fw; ++ ++ fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); ++ if (!fw) ++ return -ENOMEM; ++ ++ fw->cl.dev = dev; ++ fw->cl.rx_callback = response_callback; ++ fw->cl.tx_block = true; ++ ++ fw->chan = mbox_request_channel(&fw->cl, 0); ++ if (IS_ERR(fw->chan)) { ++ int ret = PTR_ERR(fw->chan); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get mbox channel: %d\n", ret); ++ return ret; ++ } ++ ++ init_completion(&fw->c); ++ ++ platform_set_drvdata(pdev, fw); ++ ++ rpi_firmware_print_firmware_revision(fw); ++ ++ return 0; ++} ++ ++static int rpi_firmware_remove(struct platform_device *pdev) ++{ ++ struct rpi_firmware *fw = platform_get_drvdata(pdev); ++ ++ mbox_free_channel(fw->chan); ++ ++ return 0; ++} ++ ++/** ++ * rpi_firmware_get - Get pointer to rpi_firmware structure. ++ * @firmware_node: Pointer to the firmware Device Tree node. ++ * ++ * Returns NULL is the firmware device is not ready. ++ */ ++struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) ++{ ++ struct platform_device *pdev = of_find_device_by_node(firmware_node); ++ ++ if (!pdev) ++ return NULL; ++ ++ return platform_get_drvdata(pdev); ++} ++EXPORT_SYMBOL_GPL(rpi_firmware_get); ++ ++static const struct of_device_id rpi_firmware_of_match[] = { ++ { .compatible = "raspberrypi,bcm2835-firmware", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rpi_firmware_of_match); ++ ++static struct platform_driver rpi_firmware_driver = { ++ .driver = { ++ .name = "raspberrypi-firmware", ++ .of_match_table = rpi_firmware_of_match, ++ }, ++ .probe = rpi_firmware_probe, ++ .remove = rpi_firmware_remove, ++}; ++module_platform_driver(rpi_firmware_driver); ++ ++MODULE_AUTHOR("Eric Anholt "); ++MODULE_DESCRIPTION("Raspberry Pi firmware driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +new file mode 100644 +index 0000000..9d9efb7 +--- /dev/null ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -0,0 +1,115 @@ ++/* ++ * Copyright © 2015 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++struct rpi_firmware; ++ ++enum rpi_firmware_property_status { ++ RPI_FIRMWARE_STATUS_REQUEST = 0, ++ RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000, ++ RPI_FIRMWARE_STATUS_ERROR = 0x80000001, ++}; ++ ++/** ++ * struct rpi_firmware_property_tag_header - Firmware property tag header ++ * @tag: One of enum_mbox_property_tag. ++ * @buf_size: The number of bytes in the value buffer following this ++ * struct. ++ * @req_resp_size: On submit, the length of the request (though it doesn't ++ * appear to be currently used by the firmware). On return, ++ * the length of the response (always 4 byte aligned), with ++ * the low bit set. ++ */ ++struct rpi_firmware_property_tag_header { ++ u32 tag; ++ u32 buf_size; ++ u32 req_resp_size; ++}; ++ ++enum rpi_firmware_property_tag { ++ RPI_FIRMWARE_PROPERTY_END = 0, ++ RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, ++ ++ RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, ++ RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, ++ ++ RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, ++ RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, ++ RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, ++ RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, ++ RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, ++ RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, ++ RPI_FIRMWARE_GET_CLOCKS = 0x00010007, ++ RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, ++ RPI_FIRMWARE_GET_TIMING = 0x00020002, ++ RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, ++ RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, ++ RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, ++ RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, ++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, ++ RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, ++ RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, ++ RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, ++ RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, ++ RPI_FIRMWARE_GET_TURBO = 0x00030009, ++ RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, ++ RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, ++ RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, ++ RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, ++ RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, ++ RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, ++ RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, ++ RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, ++ RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, ++ RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, ++ RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, ++ RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, ++ RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, ++ RPI_FIRMWARE_SET_TURBO = 0x00038009, ++ ++ /* Dispmanx TAGS */ ++ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, ++ RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, ++ RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, ++ ++ RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, ++ RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, ++}; ++ ++int rpi_firmware_property(struct rpi_firmware *fw, ++ u32 tag, void *data, size_t len); ++int rpi_firmware_property_list(struct rpi_firmware *fw, ++ void *data, size_t tag_size); ++struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); + +From c03abc094d43ff82ec7e9516858003c2544b5b5a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 12 Jun 2015 19:01:05 +0200 +Subject: [PATCH 006/113] irqchip: bcm2835: Add FIQ support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a duplicate irq range with an offset on the hwirq's so the +driver can detect that enable_fiq() is used. +Tested with downstream dwc_otg USB controller driver. + +Signed-off-by: Noralf Trønnes +Reviewed-by: Eric Anholt +Acked-by: Stephen Warren +--- + arch/arm/mach-bcm/Kconfig | 1 + + drivers/irqchip/irq-bcm2835.c | 51 ++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 47 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig +index 1319c3c..edbe6fe 100644 +--- a/arch/arm/mach-bcm/Kconfig ++++ b/arch/arm/mach-bcm/Kconfig +@@ -114,6 +114,7 @@ config ARCH_BCM2835 + select ARM_ERRATA_411920 + select ARM_TIMER_SP804 + select CLKSRC_OF ++ select FIQ + select PINCTRL + select PINCTRL_BCM2835 + help +diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c +index bf9cc5f..3f601f9 100644 +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -55,7 +55,7 @@ + #include + + /* Put the bank and irq (32 bits) into the hwirq */ +-#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) ++#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) + #define HWIRQ_BANK(i) (i >> 5) + #define HWIRQ_BIT(i) BIT(i & 0x1f) + +@@ -71,9 +71,13 @@ + | SHORTCUT1_MASK | SHORTCUT2_MASK) + + #define REG_FIQ_CONTROL 0x0c ++#define REG_FIQ_ENABLE 0x80 ++#define REG_FIQ_DISABLE 0 + + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 ++#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) ++#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) + + static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; + static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; +@@ -98,14 +102,38 @@ static void __exception_irq_entry bcm2835_handle_irq( + struct pt_regs *regs); + static void bcm2836_chained_handle_irq(struct irq_desc *desc); + ++static inline unsigned int hwirq_to_fiq(unsigned long hwirq) ++{ ++ hwirq -= NUMBER_IRQS; ++ /* ++ * The hwirq numbering used in this driver is: ++ * BASE (0-7) GPU1 (32-63) GPU2 (64-95). ++ * This differ from the one used in the FIQ register: ++ * GPU1 (0-31) GPU2 (32-63) BASE (64-71) ++ */ ++ if (hwirq >= 32) ++ return hwirq - 32; ++ ++ return hwirq + 64; ++} ++ + static void armctrl_mask_irq(struct irq_data *d) + { +- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); ++ if (d->hwirq >= NUMBER_IRQS) ++ writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); ++ else ++ writel_relaxed(HWIRQ_BIT(d->hwirq), ++ intc.disable[HWIRQ_BANK(d->hwirq)]); + } + + static void armctrl_unmask_irq(struct irq_data *d) + { +- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); ++ if (d->hwirq >= NUMBER_IRQS) ++ writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), ++ intc.base + REG_FIQ_CONTROL); ++ else ++ writel_relaxed(HWIRQ_BIT(d->hwirq), ++ intc.enable[HWIRQ_BANK(d->hwirq)]); + } + + static struct irq_chip armctrl_chip = { +@@ -151,8 +179,9 @@ static int __init armctrl_of_init(struct device_node *node, + panic("%s: unable to map IC registers\n", + node->full_name); + +- intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), +- &armctrl_ops, NULL); ++ intc.base = base; ++ intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2, ++ &armctrl_ops, NULL); + if (!intc.domain) + panic("%s: unable to create IRQ domain\n", node->full_name); + +@@ -182,6 +211,18 @@ static int __init armctrl_of_init(struct device_node *node, + set_handle_irq(bcm2835_handle_irq); + } + ++ /* Make a duplicate irq range which is used to enable FIQ */ ++ for (b = 0; b < NR_BANKS; b++) { ++ for (i = 0; i < bank_irqs[b]; i++) { ++ irq = irq_create_mapping(intc.domain, ++ MAKE_HWIRQ(b, i) + NUMBER_IRQS); ++ BUG_ON(irq <= 0); ++ irq_set_chip(irq, &armctrl_chip); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ } ++ } ++ init_FIQ(FIQ_START); ++ + return 0; + } + + +From e88007fc84bba1fdc4e11139bcdbd33f0543fa02 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 001/204] Main bcm2708/bcm2709 linux port +Subject: [PATCH 007/113] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -19,7 +736,7 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2708/Makefile.boot | 3 + arch/arm/mach-bcm2708/armctrl.c | 304 +++++++++ arch/arm/mach-bcm2708/armctrl.h | 27 + - arch/arm/mach-bcm2708/bcm2708.c | 622 ++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 607 +++++++++++++++++ arch/arm/mach-bcm2708/bcm2708.h | 49 ++ arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++ arch/arm/mach-bcm2708/include/mach/clkdev.h | 7 + @@ -71,7 +788,7 @@ Signed-off-by: Noralf Trønnes drivers/clocksource/arm_arch_timer.c | 36 + drivers/tty/serial/amba-pl011.c | 2 +- include/linux/mmc/host.h | 1 + - 62 files changed, 6436 insertions(+), 5 deletions(-) + 62 files changed, 6421 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile create mode 100644 arch/arm/mach-bcm2708/Makefile.boot @@ -124,10 +841,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 arch/arm/mach-bcm2709/vc_support.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 19f4cc6..3ec1319 100644 +index 72ad724..afbcf9d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -314,6 +314,42 @@ choice +@@ -315,6 +315,42 @@ choice default ARCH_VERSATILE if !MMU default ARCH_MULTIPLATFORM if MMU @@ -170,7 +887,7 @@ index 19f4cc6..3ec1319 100644 config ARCH_MULTIPLATFORM bool "Allow multiple platforms to be selected" depends on MMU -@@ -824,6 +860,9 @@ config ARCH_VIRT +@@ -827,6 +863,9 @@ config ARCH_VIRT # Kconfigs may be included either alphabetically (according to the # plat- suffix) or along side the corresponding mach-* source. # @@ -181,10 +898,10 @@ index 19f4cc6..3ec1319 100644 source "arch/arm/mach-alpine/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index 0c12ffb..18db6c4 100644 +index 0cfd7f9..87c5451 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug -@@ -1197,6 +1197,14 @@ choice +@@ -1247,6 +1247,14 @@ choice options; the platform specific options are deprecated and will be soon removed. @@ -200,10 +917,10 @@ index 0c12ffb..18db6c4 100644 config DEBUG_AT91_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 47f10e7..afd559d 100644 +index 2c2b28e..a2e7cf7 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -150,6 +150,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +@@ -154,6 +154,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -213,10 +930,10 @@ index 47f10e7..afd559d 100644 machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AXXIA) += axxia diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S -index 3637973..380430a 100644 +index 04286fd..ed82628 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S -@@ -680,6 +680,14 @@ ARM_BE8(rev16 ip, ip) +@@ -700,6 +700,14 @@ ARM_BE8(rev16 ip, ip) ldrcc r7, [r4], #4 @ use branch for delay slot bcc 1b ret lr @@ -232,12 +949,12 @@ index 3637973..380430a 100644 ENDPROC(__fixup_a_pv_table) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index f192a2a..f638dae 100644 +index 7a7c4ce..7dd2e4c 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c -@@ -98,6 +98,16 @@ void arch_cpu_idle_dead(void) +@@ -91,6 +91,16 @@ void arch_cpu_idle_exit(void) + ledtrig_cpu(CPU_LED_IDLE_END); } - #endif +char bcm2708_reboot_mode = 'h'; + @@ -310,7 +1027,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c new file mode 100644 -index 0000000..4868cd37 +index 0000000..95f272b --- /dev/null +++ b/arch/arm/mach-bcm2708/armctrl.c @@ -0,0 +1,304 @@ @@ -611,7 +1328,7 @@ index 0000000..4868cd37 + irq_set_chip(irq, &armctrl_chip); + irq_set_chip_data(irq, (void *)data); + irq_set_handler(irq, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); + } + + armctrl_pm_register(base, irq_start, resume_sources); @@ -653,10 +1370,10 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c new file mode 100644 -index 0000000..a209c58 +index 0000000..d67ee24 --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -0,0 +1,622 @@ +@@ -0,0 +1,607 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708.c + * @@ -1106,24 +1823,9 @@ index 0000000..a209c58 + system_serial_low = serial; +} + -+static void timer_set_mode(enum clock_event_mode mode, -+ struct clock_event_device *clk) ++static int timer_set_oneshot(struct clock_event_device *unused) +{ -+ switch (mode) { -+ case CLOCK_EVT_MODE_ONESHOT: /* Leave the timer disabled, .set_next_event will enable it */ -+ case CLOCK_EVT_MODE_SHUTDOWN: -+ break; -+ case CLOCK_EVT_MODE_PERIODIC: -+ -+ case CLOCK_EVT_MODE_UNUSED: -+ case CLOCK_EVT_MODE_RESUME: -+ -+ default: -+ printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n", -+ (int)mode); -+ break; -+ } -+ ++ return 0; +} + +static int timer_set_next_event(unsigned long cycles, @@ -1144,7 +1846,7 @@ index 0000000..a209c58 + .name = "timer0", + .shift = 32, + .features = CLOCK_EVT_FEAT_ONESHOT, -+ .set_mode = timer_set_mode, ++ .set_state_oneshot = timer_set_oneshot, + .set_next_event = timer_set_next_event, +}; + @@ -2745,7 +3447,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c new file mode 100644 -index 0000000..2fcfab9 +index 0000000..813008a --- /dev/null +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -0,0 +1,361 @@ @@ -3097,10 +3799,10 @@ index 0000000..2fcfab9 + if (irq >= IRQ_ARM_LOCAL_CNTPSIRQ && irq <= IRQ_ARM_LOCAL_TIMER) { + irq_set_percpu_devid(irq); + irq_set_chip_and_handler(irq, &armctrl_chip, handle_percpu_devid_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); ++ irq_set_status_flags(irq, IRQ_NOAUTOEN); + } else { + irq_set_chip_and_handler(irq, &armctrl_chip, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); + } + irq_set_chip_data(irq, (void *)data); + } @@ -3577,7 +4279,7 @@ index 0000000..e33265d +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c new file mode 100644 -index 0000000..d135620 +index 0000000..8c3f518 --- /dev/null +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -0,0 +1,801 @@ @@ -4295,7 +4997,7 @@ index 0000000..d135620 +/* + * for linux/arch/arm/kernel/smp.c:secondary_start_kernel(void) + */ -+void __cpuinit bcm2709_secondary_init(unsigned int cpu) ++void __init bcm2709_secondary_init(unsigned int cpu) +{ + printk("[%s] enter cpu:%d\n", __FUNCTION__, cpu); + //gic_secondary_init(0); @@ -4304,7 +5006,7 @@ index 0000000..d135620 +/* + * for linux/arch/arm/kernel/smp.c:__cpu_up(..) + */ -+int __cpuinit bcm2709_boot_secondary(unsigned int cpu, struct task_struct *idle) ++int __init bcm2709_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + void secondary_startup(void); + void *mbox_set = __io_address(ARM_LOCAL_MAILBOX3_SET0 + 0x10 * MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0)); @@ -6868,7 +7570,7 @@ index 0000000..c4dc7d6 + } +} diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index b4f92b9..bb263d8 100644 +index df7537f..29352cc 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -358,7 +358,7 @@ config CPU_PJ4B @@ -6908,10 +7610,10 @@ index 06d890a..30d96e8 100644 ENTRY(cpu_v6_dcache_clean_area) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S -index 7911f14..dc287c0 100644 +index de2b246..3a3aec8 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S -@@ -460,6 +460,7 @@ __v7_setup_cont: +@@ -480,6 +480,7 @@ __errata_finish: orr r0, r0, r6 @ set them THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions ret lr @ return to head.S:__ret @@ -6933,10 +7635,10 @@ index 2ed1b8a..b52d949 100644 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index 0aa135d..89dbcb9 100644 +index d6e3e49..7482c15 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c -@@ -882,3 +882,39 @@ void __init acpi_generic_timer_init(void) +@@ -874,3 +874,39 @@ void __init acpi_generic_timer_init(void) acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init); } #endif @@ -6977,10 +7679,10 @@ index 0aa135d..89dbcb9 100644 + return 0; +} diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 0cc622a..2585cd8 100644 +index fd27e98..3c37758 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c -@@ -85,7 +85,7 @@ struct vendor_data { +@@ -87,7 +87,7 @@ struct vendor_data { static unsigned int get_fifosize_arm(struct amba_device *dev) { @@ -6990,22 +7692,505 @@ index 0cc622a..2585cd8 100644 static struct vendor_data vendor_arm = { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index b5bedae..b0258e8 100644 +index 83b81fd..17bec60 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h -@@ -285,6 +285,7 @@ struct mmc_host { - MMC_CAP2_HS400_1_2V) +@@ -289,6 +289,7 @@ struct mmc_host { #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) + #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ +#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ mmc_pm_flag_t pm_caps; /* supported pm features */ -From 7408b83b52329a004068c5749e1733d8cb9028cb Mon Sep 17 00:00:00 2001 +From a86c3cf38e4069cfa9c59a09b1b08c6bed22717f Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 19 Aug 2015 08:49:11 +0100 +Subject: [PATCH 008/113] BCM2708: Use upstream interrupt driver on all Pi1's + +Although the aim is to delete the old armctrl driver, that can't happen +while non-DT configurations are still supported. This commit enables +use of the new FIQ-enabled upstream irqchip driver when DT is enabled +on all BCM2835-based RPi platforms (Models A, B, A+, B+ & CM). + +BCM2836-based platforms (Pi 2) will get the same treatment at a later +date, unless non-DT support has already been withdrawn. +--- + arch/arm/Kconfig | 1 + + arch/arm/mach-bcm2708/armctrl.c | 68 +++++++++++++++++++++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 6 +++- + drivers/irqchip/Makefile | 1 + + 4 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index afbcf9d..354789d 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -327,6 +327,7 @@ config ARCH_BCM2708 + select GENERIC_CLOCKEVENTS + select ARM_ERRATA_411920 + select MACH_BCM2708 ++ select MULTI_IRQ_HANDLER + select VC4 + select FIQ + help +diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c +index 95f272b..85ec395 100644 +--- a/arch/arm/mach-bcm2708/armctrl.c ++++ b/arch/arm/mach-bcm2708/armctrl.c +@@ -26,10 +26,22 @@ + #include + #include + ++#include + #include + #include + #include "armctrl.h" + ++/* Mask out shortcut interrupts where they also appear in the regular bank */ ++#define BANK0_HWIRQ 0x001ffcff ++#define BANK1_HWIRQ BIT(8) ++#define BANK2_HWIRQ BIT(9) ++#define BANK0_VALID_MASK \ ++ (BANK0_HWIRQ + BANK1_HWIRQ + BANK2_HWIRQ) ++#define BANK1_VALID_MASK \ ++ (~(BIT(7) | BIT(9) | BIT(10) | BIT(18) | BIT(19))) ++#define BANK2_VALID_MASK \ ++ (~(BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25) | BIT(30))) ++ + /* For support of kernels >= 3.0 assume only one VIC for now*/ + static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { + INTERRUPT_VC_JPEG, +@@ -275,6 +287,59 @@ static struct irq_chip armctrl_chip = { + .irq_set_wake = armctrl_set_wake, + }; + ++#ifdef CONFIG_MULTI_IRQ_HANDLER ++ ++static void __exception_irq_entry armctrl_handle_irq( ++ struct pt_regs *regs) ++{ ++ u32 stat; ++ ++ while ((stat = readl_relaxed(__io_address(ARM_IRQ_PEND0)) & ++ BANK0_VALID_MASK)) { ++ u32 stat2; ++ u32 irq; ++ ++ if (stat & BANK0_HWIRQ) { ++ irq = ARM_IRQ0_BASE + ffs(stat & BANK0_HWIRQ) - 1; ++ } else if (stat & BANK1_HWIRQ) { ++ stat2 = readl_relaxed(__io_address(ARM_IRQ_PEND1)) & ++ BANK1_VALID_MASK; ++ if (stat2) ++ irq = ARM_IRQ1_BASE + ++ ffs(stat2 & BANK1_VALID_MASK) - 1; ++ else ++ continue; ++ } else if (stat & BANK2_HWIRQ) { ++ stat2 = readl_relaxed(__io_address(ARM_IRQ_PEND2)) & ++ BANK2_VALID_MASK; ++ if (stat2) ++ irq = ARM_IRQ2_BASE + ++ ffs(stat2 & BANK2_VALID_MASK) - 1; ++ else ++ continue; ++ } else { ++ BUG(); ++ } ++ ++ handle_IRQ(irq, regs); ++ } ++} ++ ++/* This function forces the interrupt numbers to be allocated sequentially, ++ * instead of with gaps due to the sparse BANK0, to make the offset from ++ * IRQs and FIQs constant (and equal to FIQ_START). ++ */ ++unsigned int arch_dynirq_lower_bound(unsigned int from) ++{ ++ if (from < 24) ++ return from + 24; ++ else if (from >= 104) ++ return from - 24; ++ return from; ++} ++ ++#endif ++ + /** + * armctrl_init - initialise a vectored interrupt controller + * @base: iomem base address +@@ -298,6 +363,9 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + irq_set_probe(irq); + } + ++#ifdef CONFIG_MULTI_IRQ_HANDLER ++ set_handle_irq(armctrl_handle_irq); ++#endif + armctrl_pm_register(base, irq_start, resume_sources); + armctrl_dt_init(); + return 0; +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index d67ee24..54af8e8 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -89,7 +90,10 @@ static void __init bcm2708_init_led(void); + + void __init bcm2708_init_irq(void) + { +- armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0); ++ if (of_have_populated_dt()) ++ irqchip_init(); ++ else ++ armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0); + } + + static struct map_desc bcm2708_io_desc[] __initdata = { +diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile +index bb3048f..e360137 100644 +--- a/drivers/irqchip/Makefile ++++ b/drivers/irqchip/Makefile +@@ -2,6 +2,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o + + obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o + obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o ++obj-$(CONFIG_ARCH_BCM2708) += irq-bcm2835.o + obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o + obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o + obj-$(CONFIG_ARCH_MMP) += irq-mmp.o + +From 09ff19e8d75f7fdaf7d2b3788070bb8a9f2134cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:37:19 +0200 +Subject: [PATCH 009/113] BCM270x: Switch to firmware driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +defconfig: enable BCM2835_MBOX, RASPBERRYPI_FIRMWARE and BCM_VCIO. +Add firmware node and change mailbox node in Device Tree. +Add/update platform file for firmware and mailbox. +Strip bcm2708-vcio of everything except the legacy API and hook it +up with the firmware driver. + +Signed-off-by: Noralf Trønnes +--- + arch/arm/mach-bcm2708/bcm2708.c | 27 ++++++--------------------- + arch/arm/mach-bcm2709/bcm2709.c | 27 ++++++--------------------- + 2 files changed, 12 insertions(+), 42 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 54af8e8..769e6a4 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -277,29 +277,14 @@ static struct platform_device bcm2708_usb_device = { + }, + }; + +-static struct resource bcm2708_vcio_resources[] = { +- { +- .start = ARMCTRL_0_MAIL0_BASE, +- .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ARM_MAILBOX, +- .end = IRQ_ARM_MAILBOX, +- .flags = IORESOURCE_IRQ, +- }, +-}; +- +-static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +-static struct platform_device bcm2708_vcio_device = { +- .name = "bcm2708_vcio", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vcio_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++static struct platform_device bcm2708_rpifw_device = { ++ .name = "raspberrypi-firmware", + .dev = { +- .dma_mask = &vcio_dmamask, ++ .dma_mask = &rpifw_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ }, + }; + + int __init bcm_register_device(struct platform_device *pdev) +@@ -431,7 +416,7 @@ void __init bcm2708_init(void) + bcm2708_init_clocks(); + bcm2708_dt_init(); + +- bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_rpifw_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 8c3f518..e7e553e 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -304,29 +304,14 @@ static struct platform_device bcm2708_usb_device = { + }, + }; + +-static struct resource bcm2708_vcio_resources[] = { +- { +- .start = ARMCTRL_0_MAIL0_BASE, +- .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ARM_MAILBOX, +- .end = IRQ_ARM_MAILBOX, +- .flags = IORESOURCE_IRQ, +- }, +-}; +- +-static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +-static struct platform_device bcm2708_vcio_device = { +- .name = "bcm2708_vcio", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vcio_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++static struct platform_device bcm2708_rpifw_device = { ++ .name = "raspberrypi-firmware", + .dev = { +- .dma_mask = &vcio_dmamask, ++ .dma_mask = &rpifw_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ }, + }; + + int __init bcm_register_device(struct platform_device *pdev) +@@ -458,7 +443,7 @@ void __init bcm2709_init(void) + bcm2709_init_clocks(); + bcm2709_dt_init(); + +- bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_rpifw_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif + +From d65f19aaa17d12336e2414c1cfb095b250ea3ca1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Thu, 13 Aug 2015 19:17:47 +0200 +Subject: [PATCH 010/113] BCM2708: Use brcm,bcm2835-system-timer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When booting with Device Tree use drivers/clocksource/bcm2835_timer.c + +Signed-off-by: Noralf Trønnes +--- + arch/arm/Kconfig | 2 ++ + arch/arm/mach-bcm2708/bcm2708.c | 7 ++++++- + arch/arm/mach-bcm2708/include/mach/platform.h | 1 - + drivers/clocksource/Makefile | 2 +- + 4 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 354789d..f40e621 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -319,6 +319,8 @@ config ARCH_BCM2708 + bool "Broadcom BCM2708 family" + select CPU_V6 + select ARM_AMBA ++ select CLKSRC_MMIO ++ select CLKSRC_OF if OF + select HAVE_SCHED_CLOCK + select NEED_MACH_GPIO_H + select NEED_MACH_MEMORY_H +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 769e6a4..be963e4 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -390,7 +390,6 @@ static void __init bcm2708_dt_init(void) + { + int ret; + +- of_clk_init(NULL); + ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (ret) { + pr_err("of_platform_populate failed: %d\n", ret); +@@ -494,6 +493,12 @@ static struct delay_timer bcm2708_delay_timer = { + + static void __init bcm2708_timer_init(void) + { ++ if (of_have_populated_dt()) { ++ of_clk_init(NULL); ++ clocksource_of_init(); ++ return; ++ } ++ + /* init high res timer */ + bcm2708_clocksource_init(); + +diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h +index 2e7e1bb..a132502 100644 +--- a/arch/arm/mach-bcm2708/include/mach/platform.h ++++ b/arch/arm/mach-bcm2708/include/mach/platform.h +@@ -181,7 +181,6 @@ + #define MAXIRQNUM (32 + 32 + 20) + #define MAXFIQNUM (32 + 32 + 20) + +-#define MAX_TIMER 2 + #define MAX_PERIOD 699050 + #define TICKS_PER_uSEC 1 + +diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile +index 5c00863..2efed52 100644 +--- a/drivers/clocksource/Makefile ++++ b/drivers/clocksource/Makefile +@@ -19,7 +19,7 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o + obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o + obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o + obj-$(CONFIG_ORION_TIMER) += time-orion.o +-obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o ++obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708) += bcm2835_timer.o + obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o + obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o + obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o + +From f98a40301ec3de0e9308b1edea7014c9e3e5fb47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:19:30 +0200 +Subject: [PATCH 011/113] mailbox: bcm2835: Support ARCH_BCM270x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Make it possible to use bcm2835-mailbox without Device Tree. +Load driver early because of lacking support for deferred probing +in many drivers. + +Signed-off-by: Noralf Trønnes +--- + drivers/mailbox/Kconfig | 2 +- + drivers/mailbox/bcm2835-mailbox.c | 18 ++++++++++++++++-- + drivers/mailbox/mailbox.c | 13 ++++++++++++- + 3 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig +index bbec500..737db54 100644 +--- a/drivers/mailbox/Kconfig ++++ b/drivers/mailbox/Kconfig +@@ -65,7 +65,7 @@ config ALTERA_MBOX + + config BCM2835_MBOX + tristate "BCM2835 Mailbox" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + help + An implementation of the BCM2385 Mailbox. It is used to invoke + the services of the Videocore. Say Y here if you want to use the +diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c +index cfb4b44..d9c6c21 100644 +--- a/drivers/mailbox/bcm2835-mailbox.c ++++ b/drivers/mailbox/bcm2835-mailbox.c +@@ -51,12 +51,15 @@ + #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) + #define MAIL1_STA (ARM_0_MAIL1 + 0x18) + ++/* On ARCH_BCM270x these come through (arm_control.h ) */ ++#ifndef ARM_MS_FULL + /* Status register: FIFO state. */ + #define ARM_MS_FULL BIT(31) + #define ARM_MS_EMPTY BIT(30) + + /* Configuration register: Enable interrupts. */ + #define ARM_MC_IHAVEDATAIRQEN BIT(0) ++#endif + + struct bcm2835_mbox { + void __iomem *regs; +@@ -151,7 +154,7 @@ static int bcm2835_mbox_probe(struct platform_device *pdev) + return -ENOMEM; + spin_lock_init(&mbox->lock); + +- ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), ++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), + bcm2835_mbox_irq, 0, dev_name(dev), mbox); + if (ret) { + dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", +@@ -209,7 +212,18 @@ static struct platform_driver bcm2835_mbox_driver = { + .probe = bcm2835_mbox_probe, + .remove = bcm2835_mbox_remove, + }; +-module_platform_driver(bcm2835_mbox_driver); ++ ++static int __init bcm2835_mbox_init(void) ++{ ++ return platform_driver_register(&bcm2835_mbox_driver); ++} ++arch_initcall(bcm2835_mbox_init); ++ ++static void __init bcm2835_mbox_exit(void) ++{ ++ platform_driver_unregister(&bcm2835_mbox_driver); ++} ++module_exit(bcm2835_mbox_exit); + + MODULE_AUTHOR("Lubomir Rintel "); + MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index 6a4811f..3bb7e87 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -307,13 +307,23 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) + unsigned long flags; + int ret; + +- if (!dev || !dev->of_node) { ++ if (!dev) { + pr_debug("%s: No owner device node\n", __func__); + return ERR_PTR(-ENODEV); + } + + mutex_lock(&con_mutex); + ++ if (!dev->of_node) { ++ chan = ERR_PTR(-EPROBE_DEFER); ++ /* pick the first controller in the list */ ++ list_for_each_entry(mbox, &mbox_cons, node) { ++ chan = &mbox->chans[0]; ++ break; ++ } ++ goto skip_dt; ++ } ++ + if (of_parse_phandle_with_args(dev->of_node, "mboxes", + "#mbox-cells", index, &spec)) { + dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__); +@@ -330,6 +340,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) + + of_node_put(spec.np); + ++skip_dt: + if (IS_ERR(chan)) { + mutex_unlock(&con_mutex); + return chan; + +From d3a7bb9cb866466f6c6c8c01c77b7e52747294bb Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 Oct 2014 18:50:05 +0100 -Subject: [PATCH 002/204] Add bcm2708_gpio driver +Subject: [PATCH 012/113] Add bcm2708_gpio driver Signed-off-by: popcornmix @@ -7041,11 +8226,12 @@ Issue: linux #760 arch/arm/mach-bcm2708/Kconfig | 8 + arch/arm/mach-bcm2708/Makefile | 1 + arch/arm/mach-bcm2708/bcm2708.c | 25 ++ - arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708_gpio.c | 425 ++++++++++++++++++++++++++++++ arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++ + arch/arm/mach-bcm2709/bcm2708_gpio.c | 1 - arch/arm/mach-bcm2709/bcm2709.c | 25 ++ include/linux/platform_data/bcm2708.h | 23 ++ - 7 files changed, 525 insertions(+) + 8 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h create mode 100644 include/linux/platform_data/bcm2708.h @@ -7079,11 +8265,11 @@ index e7d5a29..5120994 100644 obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o +obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a209c58..6c1c616 100644 +index be963e4..3654967 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -298,6 +298,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -287,6 +287,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +#ifdef CONFIG_BCM2708_GPIO @@ -7116,10 +8302,10 @@ index a209c58..6c1c616 100644 int ret; diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c new file mode 100644 -index 0000000..e33265d +index 0000000..ef817fe --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -0,0 +1,426 @@ +@@ -0,0 +1,425 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708_gpio.c + * @@ -7442,7 +8628,6 @@ index 0000000..e33265d + irq_set_chip_data(irq, ucb); + irq_set_chip_and_handler(irq, &bcm2708_irqchip, + handle_simple_irq); -+ set_irq_flags(irq, IRQF_VALID); + } + + bcm2708_gpio_irq.dev_id = ucb; @@ -7569,12 +8754,24 @@ index 0000000..7965a97 +#define irq_to_gpio(x) ((x) - GPIO_IRQ_START) + +#endif +diff --git a/arch/arm/mach-bcm2709/bcm2708_gpio.c b/arch/arm/mach-bcm2709/bcm2708_gpio.c +index e33265d..ef817fe 100644 +--- a/arch/arm/mach-bcm2709/bcm2708_gpio.c ++++ b/arch/arm/mach-bcm2709/bcm2708_gpio.c +@@ -320,7 +320,6 @@ static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb) + irq_set_chip_data(irq, ucb); + irq_set_chip_and_handler(irq, &bcm2708_irqchip, + handle_simple_irq); +- set_irq_flags(irq, IRQF_VALID); + } + + bcm2708_gpio_irq.dev_id = ucb; diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index d135620..b173422 100644 +index e7e553e..5fcd153 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -329,6 +329,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -314,6 +314,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +#ifdef CONFIG_BCM2708_GPIO @@ -7635,644 +8832,10 @@ index 0000000..fb69624 + +#endif -From d86df54c296ad49447cb90e8c9ea1d2c8bd2b82b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 19:11:03 +0200 -Subject: [PATCH 003/204] mailbox: bcm2708: Add bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: popcornmix - -Copy the arch vcio.c driver to drivers/mailbox. -This is done to make it available on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes - -mailbox: bcm2708-vcio: Allocation does not need to be atomic - -No need to do atomic allocation in a context that can sleep. - -Signed-off-by: Noralf Trønnes - -mailbox: bcm2708-vcio: Check the correct status register before writing - -With the VC reader blocked and the ARM writing, MAIL0_STA reads -empty permanently while MAIL1_STA goes from empty (0x40000000) -to non-empty (0x00000001-0x00000007) to full (0x80000008). - -Suggested-by: Phil Elwell -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 6 + - drivers/mailbox/Makefile | 2 + - drivers/mailbox/bcm2708-vcio.c | 427 ++++++++++++++++++++++++++ - include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++ - 4 files changed, 561 insertions(+) - create mode 100644 drivers/mailbox/bcm2708-vcio.c - create mode 100644 include/linux/platform_data/mailbox-bcm2708.h - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 84b0a2d..7f19cb4 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -7,6 +7,12 @@ menuconfig MAILBOX - - if MAILBOX - -+config BCM2708_MBOX -+ bool "Broadcom BCM2708 Mailbox (vcio)" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ help -+ Broadcom BCM2708 Mailbox (vcio) -+ - config ARM_MHU - tristate "ARM MHU Mailbox" - depends on ARM_AMBA -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index b18201e..cecfad3 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -2,6 +2,8 @@ - - obj-$(CONFIG_MAILBOX) += mailbox.o - -+obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o -+ - obj-$(CONFIG_ARM_MHU) += arm_mhu.o - - obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -new file mode 100644 -index 0000000..d91672b ---- /dev/null -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -0,0 +1,427 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_vcio" -+#define DEVICE_FILE_NAME "vcio" -+ -+/* offsets from a mail box base address */ -+#define MAIL0_RD 0x00 /* read - and next 4 words */ -+#define MAIL0_POL 0x10 /* read without popping the fifo */ -+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL0_STA 0x18 /* status */ -+#define MAIL0_CNF 0x1C /* configuration */ -+#define MAIL1_WRT 0x20 /* write - and next 4 words */ -+#define MAIL1_STA 0x38 /* status */ -+ -+/* On MACH_BCM270x these come through (arm_control.h ) */ -+#ifndef ARM_MS_EMPTY -+#define ARM_MS_EMPTY BIT(30) -+#define ARM_MS_FULL BIT(31) -+ -+#define ARM_MC_IHAVEDATAIRQEN BIT(0) -+#endif -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+#define MAJOR_NUM 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+ -+static struct class *vcio_class; -+ -+struct vc_mailbox { -+ void __iomem *regs; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out) -+{ -+ int i; -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -+ -+ return 0; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ -+ return 0; -+} -+ -+static irqreturn_t mbox_irq_handler(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -+ int status = readl(mbox->regs + MAIL0_STA); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->regs + MAIL0_RD); -+ int chan = MBOX_CHAN(msg); -+ -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ pr_err(DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ pr_err(DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->regs + MAIL0_STA); -+ } -+ return ret; -+} -+ -+/* Mailbox Methods */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_write(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_read(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)src < TASK_SIZE) -+ return copy_from_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)dst < TASK_SIZE) -+ return copy_to_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -+ GFP_KERNEL); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* Platform Device for Mailbox */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static bool device_is_open; -+ -+/* This is called whenever a process attempts to open the device file */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* We don't want to talk to two processes at the same time */ -+ if (device_is_open) -+ return -EBUSY; -+ -+ device_is_open = true; -+ try_module_get(THIS_MODULE); -+ -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* We're now ready for our next caller */ -+ device_is_open = false; -+ -+ module_put(THIS_MODULE); -+ -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ default: -+ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+const struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device *vdev; -+ struct vc_mailbox *mailbox; -+ struct resource *res; -+ int irq, ret; -+ -+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -+ if (!mailbox) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mailbox->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mailbox->regs)) -+ return PTR_ERR(mailbox->regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, irq, mbox_irq_handler, -+ IRQF_IRQPOLL, -+ dev_name(dev), mailbox); -+ if (ret) { -+ dev_err(dev, "Interrupt request failed %d\n", ret); -+ return ret; -+ } -+ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ if (ret < 0) { -+ pr_err("Character device registration failed %d\n", ret); -+ return ret; -+ } -+ -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ pr_err("Class creation failed %d\n", ret); -+ goto err_class; -+ } -+ -+ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); -+ if (IS_ERR(vdev)) { -+ ret = PTR_ERR(vdev); -+ pr_err("Device creation failed %d\n", ret); -+ goto err_dev; -+ } -+ -+ mbox_init(mailbox); -+ platform_set_drvdata(pdev, mailbox); -+ mbox_dev = dev; -+ -+ dev_info(dev, "mailbox at %p\n", mailbox->regs); -+ -+ return 0; -+ -+err_dev: -+ class_destroy(vcio_class); -+err_class: -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ mbox_dev = NULL; -+ platform_set_drvdata(pdev, NULL); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm_vcio_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-vcio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm_vcio_of_match_table, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ return platform_driver_register(&bcm_mbox_driver); -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -new file mode 100644 -index 0000000..cc284ed ---- /dev/null -+++ b/include/linux/platform_data/mailbox-bcm2708.h -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef _PLAT_MAILBOX_BCM2708_H -+#define _PLAT_MAILBOX_BCM2708_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+ -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+ -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+int bcm_mailbox_read(unsigned chan, uint32_t *data28); -+int bcm_mailbox_write(unsigned chan, uint32_t data28); -+int bcm_mailbox_property(void *data, int size); -+ -+#endif - -From a01bebe2f26586b5b8021847cc12f83f9fd0a27f Mon Sep 17 00:00:00 2001 +From 69cf08e3b513c929a540214cd0b7f4a433aa6be6 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 004/204] Add dwc_otg driver +Subject: [PATCH 013/113] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -8712,6 +9275,20 @@ comment pointing to a possible: 'usb storage / SCSI bug'. Signed-off-by: Noralf Trønnes dwc_otg: Fix crash when fiq_enable=0 + +dwc_otg: fiq_fsm: Make high-speed isochronous strided transfers work properly + +Certain low-bandwidth high-speed USB devices (specialist audio devices, +compressed-frame webcams) have packet intervals > 1 microframe. + +Stride these transfers in the FIQ by using the start-of-frame interrupt +to restart the channel at the right time. + +dwc_otg: Force host mode to fix incorrect compute module boards + +dwc_otg: Add ARCH_BCM2835 support + +Signed-off-by: Noralf Trønnes --- arch/arm/include/asm/irqflags.h | 16 +- arch/arm/kernel/fiqasm.S | 4 + @@ -8735,7 +9312,7 @@ dwc_otg: Fix crash when fiq_enable=0 drivers/usb/host/dwc_common_port/dwc_cc.c | 532 ++ drivers/usb/host/dwc_common_port/dwc_cc.h | 224 + drivers/usb/host/dwc_common_port/dwc_common_fbsd.c | 1308 ++++ - .../usb/host/dwc_common_port/dwc_common_linux.c | 1434 ++++ + .../usb/host/dwc_common_port/dwc_common_linux.c | 1433 ++++ drivers/usb/host/dwc_common_port/dwc_common_nbsd.c | 1275 ++++ drivers/usb/host/dwc_common_port/dwc_crypto.c | 308 + drivers/usb/host/dwc_common_port/dwc_crypto.h | 111 + @@ -8764,17 +9341,17 @@ dwc_otg: Fix crash when fiq_enable=0 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 1594 +++++ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 705 ++ drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 117 + - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1756 +++++ + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1757 +++++ drivers/usb/host/dwc_otg/dwc_otg_driver.h | 86 + - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 1346 ++++ - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 367 + + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 1355 ++++ + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 370 + drivers/usb/host/dwc_otg/dwc_otg_fiq_stub.S | 80 + - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4252 ++++++++++++ + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4257 ++++++++++++ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 862 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 1132 ++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 417 ++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2713 ++++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 995 +++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2714 ++++++++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 1004 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 957 +++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 188 + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2712 ++++++++ @@ -8787,7 +9364,7 @@ dwc_otg: Fix crash when fiq_enable=0 drivers/usb/host/dwc_otg/test/dwc_otg_test.pm | 337 + drivers/usb/host/dwc_otg/test/test_mod_param.pl | 133 + drivers/usb/host/dwc_otg/test/test_sysfs.pl | 193 + - 74 files changed, 60032 insertions(+), 96 deletions(-) + 74 files changed, 60059 insertions(+), 96 deletions(-) create mode 100644 drivers/usb/gadget/file_storage.c create mode 100644 drivers/usb/host/dwc_common_port/Makefile create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd @@ -8851,16 +9428,17 @@ dwc_otg: Fix crash when fiq_enable=0 create mode 100644 drivers/usb/host/dwc_otg/test/test_sysfs.pl diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h -index 3b763d6..5770408 100644 +index 4390814..2b5c1b7 100644 --- a/arch/arm/include/asm/irqflags.h +++ b/arch/arm/include/asm/irqflags.h -@@ -145,12 +145,22 @@ static inline unsigned long arch_local_save_flags(void) +@@ -152,13 +152,23 @@ static inline unsigned long arch_local_save_flags(void) } /* - * restore saved IRQ & FIQ state + * restore saved IRQ state */ + #define arch_local_irq_restore arch_local_irq_restore static inline void arch_local_irq_restore(unsigned long flags) { - asm volatile( @@ -8893,10 +9471,10 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index 4868cd37..0429225 100644 +index 85ec395..f9c59d8 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -54,8 +54,12 @@ static void armctrl_mask_irq(struct irq_data *d) +@@ -66,8 +66,12 @@ static void armctrl_mask_irq(struct irq_data *d) 0 }; @@ -8911,7 +9489,7 @@ index 4868cd37..0429225 100644 } static void armctrl_unmask_irq(struct irq_data *d) -@@ -67,8 +71,14 @@ static void armctrl_unmask_irq(struct irq_data *d) +@@ -79,8 +83,14 @@ static void armctrl_unmask_irq(struct irq_data *d) 0 }; @@ -8928,19 +9506,19 @@ index 4868cd37..0429225 100644 } #ifdef CONFIG_OF -@@ -299,6 +309,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, - } - +@@ -367,6 +377,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + set_handle_irq(armctrl_handle_irq); + #endif armctrl_pm_register(base, irq_start, resume_sources); + init_FIQ(FIQ_START); armctrl_dt_init(); return 0; } diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6c1c616..1735b72 100644 +index 3654967..354dbf6 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -254,12 +254,23 @@ static struct resource bcm2708_usb_resources[] = { +@@ -258,12 +258,23 @@ static struct resource bcm2708_usb_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { @@ -9135,7 +9713,7 @@ index 3a88a1a..45152ed 100644 #define SPARE_ALLOC_IRQS 64 #define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c -index 2fcfab9..a366275 100644 +index 813008a..c6f68b4 100644 --- a/arch/arm/mach-bcm2709/armctrl.c +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -91,7 +91,15 @@ static void armctrl_unmask_irq(struct irq_data *d) @@ -9180,10 +9758,10 @@ index 358ca8d..abaac7c 100644 return i; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 1e9a8c9..7e9f79f 100644 +index 431839b..56824cfe 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -4906,7 +4906,7 @@ static void port_event(struct usb_hub *hub, int port1) +@@ -4916,7 +4916,7 @@ static void port_event(struct usb_hub *hub, int port1) if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; @@ -9283,11 +9861,11 @@ index f368d20..2f6e3fe 100644 /* Now that the interfaces are installed, re-enable LPM. */ usb_unlocked_enable_lpm(dev); diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h -index a6315ab..165dd53 100644 +index a95b0c9..17b605f 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h @@ -19,33 +19,82 @@ - static struct usb_device_id whitelist_table [] = { + static struct usb_device_id whitelist_table[] = { /* hubs are optional in OTG, but very handy ... */ +#define CERT_WITHOUT_HUBS @@ -13122,10 +13700,10 @@ index 0000000..a896d73 +} +module_exit(fsg_cleanup); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 197a6a3..5496cd0 100644 +index 079991e..050eb41 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig -@@ -738,6 +738,19 @@ config USB_HWA_HCD +@@ -745,6 +745,19 @@ config USB_HWA_HCD To compile this driver a module, choose M here: the module will be called "hwa-hc". @@ -13146,10 +13724,10 @@ index 197a6a3..5496cd0 100644 tristate "i.MX21 HCD support" depends on ARM && ARCH_MXC diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile -index 65b0b6a..49399f2 100644 +index 754efaa..8bb3310 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile -@@ -68,6 +68,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o +@@ -70,6 +70,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o @@ -13157,7 +13735,7 @@ index 65b0b6a..49399f2 100644 +obj-$(CONFIG_USB_DWCOTG) += dwc_otg/ dwc_common_port/ obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o - obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o + obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile new file mode 100644 index 0000000..f10d466 @@ -15840,10 +16418,10 @@ index 0000000..6dd04b5 +} diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c new file mode 100644 -index 0000000..b802042 +index 0000000..4664684 --- /dev/null +++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c -@@ -0,0 +1,1434 @@ +@@ -0,0 +1,1433 @@ +#include +#include +#include @@ -16617,7 +17195,6 @@ index 0000000..b802042 + } + + t->scheduled = 0; -+ t->t->base = &boot_tvec_bases; + t->t->expires = jiffies; + setup_timer(t->t, timer_callback, (unsigned long)t); + @@ -30133,7 +30710,7 @@ index 0000000..55fd337 +#endif /* (__DWC_OTG_CFI_H__) */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c new file mode 100644 -index 0000000..e40060f +index 0000000..beaa8b3 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c @@ -0,0 +1,7141 @@ @@ -30331,7 +30908,7 @@ index 0000000..e40060f + core_if->hptxfsiz.d32 = + DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); + gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); -+ gusbcfg.b.force_host_mode = 0; ++ gusbcfg.b.force_host_mode = 1; + DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); + dwc_mdelay(100); + } @@ -41184,10 +41761,10 @@ index 0000000..ccc24e0 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c new file mode 100644 -index 0000000..53307f0 +index 0000000..95edadf --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -0,0 +1,1756 @@ +@@ -0,0 +1,1757 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $ + * $Revision: #92 $ @@ -41913,6 +42490,7 @@ index 0000000..53307f0 + + memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); + dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF; ++ dwc_otg_device->os_dep.platformdev = _dev; + + /* + * Map the DWC_otg Core memory into virtual address space. @@ -43038,10 +43616,10 @@ index 0000000..6a8be63 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c new file mode 100644 -index 0000000..7e0c726 +index 0000000..85d82f3 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -0,0 +1,1346 @@ +@@ -0,0 +1,1355 @@ +/* + * dwc_otg_fiq_fsm.c - The finite state machine FIQ + * @@ -43659,8 +44237,11 @@ index 0000000..7e0c726 + break; + + case FIQ_HS_ISOC_SLEEPING: -+ state->channel[n].fsm = FIQ_HS_ISOC_TURBO; -+ fiq_fsm_restart_channel(state, n, 0); ++ /* Is it time to wake this channel yet? */ ++ if (--state->channel[n].uframe_sleeps == 0) { ++ state->channel[n].fsm = FIQ_HS_ISOC_TURBO; ++ fiq_fsm_restart_channel(state, n, 0); ++ } + break; + + case FIQ_PER_SSPLIT_QUEUED: @@ -43668,7 +44249,7 @@ index 0000000..7e0c726 + break; + if(!fiq_fsm_tt_in_use(state, num_channels, n)) { + if (!fiq_fsm_too_late(state, n)) { -+ fiq_print(FIQDBG_INT, st, "SOF GO %01d", n); ++ fiq_print(FIQDBG_INT, state, "SOF GO %01d", n); + fiq_fsm_restart_channel(state, n, 0); + state->channel[n].fsm = FIQ_PER_SSPLIT_STARTED; + } else { @@ -44113,8 +44694,14 @@ index 0000000..7e0c726 + if (fiq_fsm_update_hs_isoc(state, n, hcint)) { + /* more transactions to come */ + handled = 1; -+ restart = 1; + fiq_print(FIQDBG_INT, state, "HSISO M "); ++ /* For strided transfers, put ourselves to sleep */ ++ if (st->hs_isoc_info.stride > 1) { ++ st->uframe_sleeps = st->hs_isoc_info.stride - 1; ++ st->fsm = FIQ_HS_ISOC_SLEEPING; ++ } else { ++ restart = 1; ++ } + } else { + st->fsm = FIQ_HS_ISOC_DONE; + fiq_print(FIQDBG_INT, state, "HSISO F "); @@ -44390,10 +44977,10 @@ index 0000000..7e0c726 +} diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h new file mode 100644 -index 0000000..8455324 +index 0000000..f9fddfb --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -0,0 +1,367 @@ +@@ -0,0 +1,370 @@ +/* + * dwc_otg_fiq_fsm.h - Finite state machine FIQ header definitions + * @@ -44656,12 +45243,13 @@ index 0000000..8455324 + * @iso_frame: Pointer to the array of OTG URB iso_frame_descs. + * @nrframes: Total length of iso_frame_desc array + * @index: Current index (FIQ-maintained) -+ * ++ * @stride: Interval in uframes between HS isoc transactions + */ +struct fiq_hs_isoc_info { + struct dwc_otg_hcd_iso_packet_desc *iso_desc; + unsigned int nrframes; + unsigned int index; ++ unsigned int stride; +}; + +/** @@ -44692,6 +45280,8 @@ index 0000000..8455324 + /* Hardware bug workaround: sometimes channel halt interrupts are + * delayed until the next SOF. Keep track of when we expected to get interrupted. */ + unsigned int expected_uframe; ++ /* number of uframes remaining (for interval > 1 HS isoc transfers) before next transfer */ ++ unsigned int uframe_sleeps; + /* in/out for communicating number of dma buffers used, or number of ISOC to do */ + unsigned int nrpackets; + struct fiq_dma_info dma_info; @@ -44849,10 +45439,10 @@ index 0000000..ffa8d21 +END(_dwc_otg_fiq_stub) diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c new file mode 100644 -index 0000000..4d7c7bb +index 0000000..135b611 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -0,0 +1,4252 @@ +@@ -0,0 +1,4257 @@ + +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $ @@ -46533,6 +47123,9 @@ index 0000000..4d7c7bb + } + } + ++ st->hs_isoc_info.stride = qh->interval; ++ st->uframe_sleeps = 0; ++ + fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d ", hc->hc_num); + fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hcchar_copy.d32); + fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hctsiz_copy.d32); @@ -46547,9 +47140,11 @@ index 0000000..4d7c7bb + DWC_WRITE_REG32(&hc_regs->hcintmsk, st->hcintmsk_copy.d32); + if (hfnum.b.frrem < PERIODIC_FRREM_BACKOFF) { + /* Prevent queueing near EOF1. Bad things happen if a periodic -+ * split transaction is queued very close to EOF. ++ * split transaction is queued very close to EOF. SOF interrupt handler ++ * will wake this channel at the next interrupt. + */ + st->fsm = FIQ_HS_ISOC_SLEEPING; ++ st->uframe_sleeps = 1; + } else { + st->fsm = FIQ_HS_ISOC_TURBO; + st->hcchar_copy.b.chen = 1; @@ -51536,10 +52131,10 @@ index 0000000..fb57db0 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c new file mode 100644 -index 0000000..8a31562 +index 0000000..8db3dfc --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -0,0 +1,2713 @@ +@@ -0,0 +1,2714 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $ + * $Revision: #89 $ @@ -51578,7 +52173,6 @@ index 0000000..8a31562 +#include "dwc_otg_regs.h" + +#include -+#include +#include + + @@ -53840,10 +54434,10 @@ index 0000000..8a31562 + dwc_urb->error_count++; + } + } ++ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval * (nr_frames - 1)); ++ + //printk_ratelimited(KERN_INFO "%s: HS isochronous of %d/%d frames with %d errors complete\n", + // __FUNCTION__, i, dwc_urb->packet_count, dwc_urb->error_count); -+ hcd->fops->complete(hcd, dwc_urb->priv, dwc_urb, 0); -+ release_channel(hcd, qh->channel, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); +} + +/** @@ -54086,6 +54680,8 @@ index 0000000..8a31562 + * fail. + */ + dwc_otg_fiq_unmangle_isoc(hcd, qh, qtd, num); ++ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); ++ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); + break; + + case FIQ_PER_SPLIT_LS_ABORTED: @@ -54255,10 +54851,10 @@ index 0000000..8a31562 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c new file mode 100644 -index 0000000..0f4ebcd +index 0000000..a331720 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -0,0 +1,995 @@ +@@ -0,0 +1,1004 @@ + +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $ @@ -54706,7 +55302,16 @@ index 0000000..0f4ebcd + DWC_WARN("MPHI periph has NOT been enabled"); +#endif + // Enable FIQ interrupt from USB peripheral -+ enable_fiq(INTERRUPT_VC_USB); ++#ifdef CONFIG_ARCH_BCM2835 ++ enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1)); ++#else ++#ifdef CONFIG_MULTI_IRQ_HANDLER ++ if (otg_dev->os_dep.platformdev->dev.of_node) ++ enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1)); ++ else ++#endif ++ enable_fiq(INTERRUPT_VC_USB); ++#endif + local_fiq_enable(); +} + @@ -69546,10 +70151,10 @@ index 0000000..cdc9963 +test_main(); +0; -From a7a65674af3af5dcc29121afaae50c0cf6b2e13b Mon Sep 17 00:00:00 2001 +From 2012bcba9accf8b797c2d418707ddd76c40f9a1c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:54:32 +0100 -Subject: [PATCH 005/204] bcm2708 watchdog driver +Subject: [PATCH 014/113] bcm2708 watchdog driver Signed-off-by: popcornmix --- @@ -69560,10 +70165,10 @@ Signed-off-by: popcornmix create mode 100644 drivers/watchdog/bcm2708_wdog.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index e5e7c55..b9c1ed5 100644 +index 79e1aa1..ee7eebf 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -451,6 +451,12 @@ config RETU_WATCHDOG +@@ -482,6 +482,12 @@ config RETU_WATCHDOG To compile this driver as a module, choose M here: the module will be called retu_wdt. @@ -69576,7 +70181,7 @@ index e5e7c55..b9c1ed5 100644 config MOXART_WDT tristate "MOXART watchdog" depends on ARCH_MOXART -@@ -1216,7 +1222,7 @@ config BCM63XX_WDT +@@ -1282,7 +1288,7 @@ config BCM63XX_WDT config BCM2835_WDT tristate "Broadcom BCM2835 hardware watchdog" @@ -69586,10 +70191,10 @@ index e5e7c55..b9c1ed5 100644 help Watchdog driver for the built in watchdog hardware in Broadcom diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile -index 5c19294..aac60bd 100644 +index 0c616e3..3afbeed 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile -@@ -56,6 +56,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o +@@ -57,6 +57,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o @@ -69986,10 +70591,10 @@ index 0000000..8a27d68 +MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_LICENSE("GPL"); -From d2d531d448b63465a680fb3e15c0e843267ff50f Mon Sep 17 00:00:00 2001 +From 1434672b2776aeb98cb206c6b002fdc138628079 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 006/204] bcm2708 framebuffer driver +Subject: [PATCH 015/113] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -70065,13 +70670,13 @@ Signed-off-by: Noralf Trønnes --- drivers/video/fbdev/Kconfig | 14 + drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/bcm2708_fb.c | 824 ++++++++++ + drivers/video/fbdev/bcm2708_fb.c | 847 ++++++++++ drivers/video/logo/logo_linux_clut224.ppm | 2483 ++++++++++------------------- - 4 files changed, 1720 insertions(+), 1602 deletions(-) + 4 files changed, 1743 insertions(+), 1602 deletions(-) create mode 100644 drivers/video/fbdev/bcm2708_fb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index d1e1e17..15098c5 100644 +index 8b1d371..f1b031e 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -224,6 +224,20 @@ config FB_TILEBLITTING @@ -70080,7 +70685,7 @@ index d1e1e17..15098c5 100644 +config FB_BCM2708 + tristate "BCM2708 framebuffer support" -+ depends on FB && ARM && BCM2708_MBOX ++ depends on FB && RASPBERRYPI_FIRMWARE + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT @@ -70096,7 +70701,7 @@ index d1e1e17..15098c5 100644 tristate "Aeroflex Gaisler framebuffer support" depends on FB && SPARC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 1979aff..57181ad 100644 +index 50ed1b4..9b086ac 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_FB_MACMODES) += macmodes.o @@ -70109,10 +70714,10 @@ index 1979aff..57181ad 100644 obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c new file mode 100644 -index 0000000..f6ac7da +index 0000000..0f62d76 --- /dev/null +++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -0,0 +1,824 @@ +@@ -0,0 +1,847 @@ +/* + * linux/drivers/video/bcm2708_fb.c + * @@ -70140,7 +70745,6 @@ index 0000000..f6ac7da +#include +#include +#include -+#include +#include +#include +#include @@ -70149,6 +70753,7 @@ index 0000000..f6ac7da +#include +#include +#include ++#include + +//#define BCM2708_FB_DEBUG +#define MODULE_NAME "bcm2708_fb" @@ -70173,15 +70778,19 @@ index 0000000..f6ac7da +module_param(dma_busy_wait_threshold, int, 0644); +MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); + -+/* this data structure describes each frame buffer device we find */ -+ -+struct fbinfo_s { -+ u32 xres, yres, xres_virtual, yres_virtual; -+ u32 pitch, bpp; ++struct fb_alloc_tags { ++ struct rpi_firmware_property_tag_header tag1; ++ u32 xres, yres; ++ struct rpi_firmware_property_tag_header tag2; ++ u32 xres_virtual, yres_virtual; ++ struct rpi_firmware_property_tag_header tag3; ++ u32 bpp; ++ struct rpi_firmware_property_tag_header tag4; + u32 xoffset, yoffset; -+ u32 base; -+ u32 screen_size; -+ u16 cmap[256]; ++ struct rpi_firmware_property_tag_header tag5; ++ u32 base, screen_size; ++ struct rpi_firmware_property_tag_header tag6; ++ u32 pitch; +}; + +struct bcm2708_fb_stats { @@ -70193,9 +70802,9 @@ index 0000000..f6ac7da +struct bcm2708_fb { + struct fb_info fb; + struct platform_device *dev; -+ struct fbinfo_s *info; -+ dma_addr_t dma; ++ struct rpi_firmware *fw; + u32 cmap[16]; ++ u32 gpu_cmap[256]; + int dma_chan; + int dma_irq; + void __iomem *dma_chan_base; @@ -70374,80 +70983,76 @@ index 0000000..f6ac7da + if (var->yoffset > var->yres_virtual - var->yres) + var->yoffset = var->yres_virtual - var->yres - 1; + -+ yres = var->yres; -+ if (var->vmode & FB_VMODE_DOUBLE) -+ yres *= 2; -+ else if (var->vmode & FB_VMODE_INTERLACED) -+ yres = (yres + 1) / 2; -+ + return 0; +} + +static int bcm2708_fb_set_par(struct fb_info *info) +{ -+ uint32_t val = 0; + struct bcm2708_fb *fb = to_bcm2708(info); -+ volatile struct fbinfo_s *fbinfo = fb->info; -+ fbinfo->xres = info->var.xres; -+ fbinfo->yres = info->var.yres; -+ fbinfo->xres_virtual = info->var.xres_virtual; -+ fbinfo->yres_virtual = info->var.yres_virtual; -+ fbinfo->bpp = info->var.bits_per_pixel; -+ fbinfo->xoffset = info->var.xoffset; -+ fbinfo->yoffset = info->var.yoffset; -+ fbinfo->base = 0; /* filled in by VC */ -+ fbinfo->pitch = 0; /* filled in by VC */ ++ struct fb_alloc_tags fbinfo = { ++ .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ .xres = info->var.xres, ++ .yres = info->var.yres, ++ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ .xres_virtual = info->var.xres_virtual, ++ .yres_virtual = info->var.yres_virtual, ++ .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, ++ .bpp = info->var.bits_per_pixel, ++ .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, ++ .xoffset = info->var.xoffset, ++ .yoffset = info->var.yoffset, ++ .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, ++ .base = 0, ++ .screen_size = 0, ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, ++ .pitch = 0, ++ }; ++ int ret; + + print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, + info->var.bits_per_pixel); + -+ /* ensure last write to fbinfo is visible to GPU */ -+ wmb(); -+ -+ /* inform vc about new framebuffer */ -+ bcm_mailbox_write(MBOX_CHAN_FB, fb->dma); -+ -+ /* TODO: replace fb driver with vchiq version */ -+ /* wait for response */ -+ bcm_mailbox_read(MBOX_CHAN_FB, &val); -+ -+ /* ensure GPU writes are visible to us */ -+ rmb(); -+ -+ if (val == 0) { -+ fb->fb.fix.line_length = fbinfo->pitch; -+ -+ if (info->var.bits_per_pixel <= 8) -+ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ else -+ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; -+ -+ fb->fb_bus_address = fbinfo->base; -+ fbinfo->base &= ~0xc0000000; -+ fb->fb.fix.smem_start = fbinfo->base; -+ fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; -+ fb->fb.screen_size = fbinfo->screen_size; -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ fb->fb.screen_base = -+ (void *)ioremap_wc(fbinfo->base, fb->fb.screen_size); -+ if (!fb->fb.screen_base) { -+ /* the console may currently be locked */ -+ console_trylock(); -+ console_unlock(); -+ pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); -+ return -EIO; -+ } ++ ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); ++ if (ret) { ++ dev_err(info->device, ++ "Failed to allocate GPU framebuffer (%d)\n", ret); ++ return ret; + } -+ print_debug -+ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", -+ (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, -+ fbinfo->xres, fbinfo->yres, fbinfo->bpp, -+ fbinfo->pitch, (int)fb->fb.screen_size, val); + -+ return val; ++ if (info->var.bits_per_pixel <= 8) ++ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else ++ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; ++ ++ fb->fb.fix.line_length = fbinfo.pitch; ++ fbinfo.base |= 0x40000000; ++ fb->fb_bus_address = fbinfo.base; ++ fbinfo.base &= ~0xc0000000; ++ fb->fb.fix.smem_start = fbinfo.base; ++ fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; ++ fb->fb.screen_size = fbinfo.screen_size; ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); ++ if (!fb->fb.screen_base) { ++ /* the console may currently be locked */ ++ console_trylock(); ++ console_unlock(); ++ dev_err(info->device, "Failed to set screen_base\n"); ++ return -ENOMEM; ++ } ++ ++ print_debug ++ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", ++ (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, ++ fbinfo.xres, fbinfo.yres, fbinfo.bpp, ++ fbinfo.pitch, (int)fb->fb.screen_size); ++ ++ return 0; +} + +static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) @@ -70467,15 +71072,34 @@ index 0000000..f6ac7da + /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ + if (fb->fb.var.bits_per_pixel <= 8) { + if (regno < 256) { -+ /* blue [0:4], green [5:10], red [11:15] */ -+ fb->info->cmap[regno] = ((red >> (16-5)) & 0x1f) << 11 | -+ ((green >> (16-6)) & 0x3f) << 5 | -+ ((blue >> (16-5)) & 0x1f) << 0; ++ /* blue [23:16], green [15:8], red [7:0] */ ++ fb->gpu_cmap[regno] = ((red >> 8) & 0xff) << 0 | ++ ((green >> 8) & 0xff) << 8 | ++ ((blue >> 8) & 0xff) << 16; + } + /* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */ + /* So just call it for what looks like the last colour in a list for now. */ -+ if (regno == 15 || regno == 255) -+ bcm2708_fb_set_par(info); ++ if (regno == 15 || regno == 255) { ++ struct packet { ++ u32 offset; ++ u32 length; ++ u32 cmap[256]; ++ } *packet; ++ int ret; ++ ++ packet = kmalloc(sizeof(*packet), GFP_KERNEL); ++ if (!packet) ++ return -ENOMEM; ++ packet->offset = 0; ++ packet->length = regno + 1; ++ memcpy(packet->cmap, fb->gpu_cmap, sizeof(packet->cmap)); ++ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, ++ packet, (2 + packet->length) * sizeof(u32)); ++ if (ret || packet->offset) ++ dev_err(info->device, "Failed to set palette (%d,%u)\n", ++ ret, packet->offset); ++ kfree(packet); ++ } + } else if (regno < 16) { + fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | + convert_bitfield(blue, &fb->fb.var.blue) | @@ -70487,32 +71111,36 @@ index 0000000..f6ac7da + +static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) +{ -+ s32 result = -1; -+ u32 p[7]; -+ if ( (blank_mode == FB_BLANK_NORMAL) || -+ (blank_mode == FB_BLANK_UNBLANK)) { ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ u32 value; ++ int ret; + -+ p[0] = 28; // size = sizeof u32 * length of p -+ p[1] = VCMSG_PROCESS_REQUEST; // process request -+ p[2] = VCMSG_SET_BLANK_SCREEN; // (the tag id) -+ p[3] = 4; // (size of the response buffer) -+ p[4] = 4; // (size of the request data) -+ p[5] = blank_mode; -+ p[6] = VCMSG_PROPERTY_END; // end tag -+ -+ bcm_mailbox_property(&p, p[0]); -+ -+ if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -+ result = 0; -+ else -+ pr_err("bcm2708_fb_blank(%d) returns=%d p[1]=0x%x\n", blank_mode, p[5], p[1]); ++ switch (blank_mode) { ++ case FB_BLANK_UNBLANK: ++ value = 0; ++ break; ++ case FB_BLANK_NORMAL: ++ case FB_BLANK_VSYNC_SUSPEND: ++ case FB_BLANK_HSYNC_SUSPEND: ++ case FB_BLANK_POWERDOWN: ++ value = 1; ++ break; ++ default: ++ return -EINVAL; + } -+ return result; ++ ++ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, ++ &value, sizeof(value)); ++ if (ret) ++ dev_err(info->device, "bcm2708_fb_blank(%d) failed: %d\n", ++ blank_mode, ret); ++ ++ return ret; +} + +static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ -+ s32 result = -1; ++ s32 result; + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + result = bcm2708_fb_set_par(info); @@ -70523,25 +71151,25 @@ index 0000000..f6ac7da + +static int bcm2708_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +{ -+ s32 result = -1; -+ u32 p[7]; -+ if (cmd == FBIO_WAITFORVSYNC) { -+ p[0] = 28; // size = sizeof u32 * length of p -+ p[1] = VCMSG_PROCESS_REQUEST; // process request -+ p[2] = VCMSG_SET_VSYNC; // (the tag id) -+ p[3] = 4; // (size of the response buffer) -+ p[4] = 4; // (size of the request data) -+ p[5] = 0; // dummy -+ p[6] = VCMSG_PROPERTY_END; // end tag ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ u32 dummy = 0; ++ int ret; + -+ bcm_mailbox_property(&p, p[0]); -+ -+ if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -+ result = 0; -+ else -+ pr_err("bcm2708_fb_ioctl %x,%lx returns=%d p[1]=0x%x\n", cmd, arg, p[5], p[1]); ++ switch (cmd) { ++ case FBIO_WAITFORVSYNC: ++ ret = rpi_firmware_property(fb->fw, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC, ++ &dummy, sizeof(dummy)); ++ break; ++ default: ++ dev_err(info->device, "Unknown ioctl 0x%x\n", cmd); ++ return -EINVAL; + } -+ return result; ++ ++ if (ret) ++ dev_err(info->device, "ioctl 0x%x failed (%d)\n", cmd, ret); ++ ++ return ret; +} +static void bcm2708_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) @@ -70736,20 +71364,7 @@ index 0000000..f6ac7da +static int bcm2708_fb_register(struct bcm2708_fb *fb) +{ + int ret; -+ dma_addr_t dma; -+ void *mem; + -+ mem = -+ dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, -+ GFP_KERNEL); -+ -+ if (NULL == mem) { -+ pr_err(": unable to allocate fbinfo buffer\n"); -+ ret = -ENOMEM; -+ } else { -+ fb->info = (struct fbinfo_s *)mem; -+ fb->dma = dma; -+ } + fb->fb.fbops = &bcm2708_fb_ops; + fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA; + fb->fb.pseudo_palette = fb->cmap; @@ -70808,9 +71423,22 @@ index 0000000..f6ac7da + +static int bcm2708_fb_probe(struct platform_device *dev) +{ ++ struct device_node *fw_np; ++ struct rpi_firmware *fw; + struct bcm2708_fb *fb; + int ret; + ++ fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0); ++/* Remove comment when booting without Device Tree is no longer supported ++ if (!fw_np) { ++ dev_err(&dev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++*/ ++ fw = rpi_firmware_get(fw_np); ++ if (!fw) ++ return -EPROBE_DEFER; ++ + fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); + if (!fb) { + dev_err(&dev->dev, @@ -70819,6 +71447,7 @@ index 0000000..f6ac7da + goto free_region; + } + ++ fb->fw = fw; + bcm2708_fb_debugfs_init(fb); + + fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, @@ -70852,6 +71481,7 @@ index 0000000..f6ac7da + fb->dma_chan, fb->dma_chan_base); + + fb->dev = dev; ++ fb->fb.device = &dev->dev; + + ret = bcm2708_fb_register(fb); + if (ret == 0) { @@ -70884,8 +71514,6 @@ index 0000000..f6ac7da + dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); + bcm_dma_chan_free(fb->dma_chan); + -+ dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, -+ fb->dma); + bcm2708_fb_debugfs_deinit(fb); + + free_irq(fb->dma_irq, fb); @@ -73428,10 +74056,10 @@ index 3c14e43..7626beb6a 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From 7b98bf652df7771dd8eb79528dd7e276f2038585 Mon Sep 17 00:00:00 2001 +From 99dd78ca9d2537b3d348f2cc0f6d29c11b94c7e8 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 007/204] dmaengine: Add support for BCM2708 +Subject: [PATCH 016/113] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -73535,22 +74163,43 @@ bcm2708-dmaengine supports residue reporting at burst level but didn't report this via the residue_granularity field. Without this field set properly we get playback issues with I2S cards. + +dmaengine: bcm2708-dmaengine: Fix memory leak when stopping a running transfer + +bcm2708-dmaengine: Use more DMA channels (but not 12) + +1) Only the bcm2708_fb drivers uses the legacy DMA API, and +it requires a BULK-capable channel, so all other types +(FAST, NORMAL and LITE) can be made available to the regular +DMA API. + +2) DMA channels 11-14 share an interrupt. The driver can't +handle this, so don't use channels 12-14 (12 was used, probably +because it appears to have an interrupt, but in reality that +interrupt is for activity on ANY channel). This may explain +a lockup encountered when running out of DMA channels. + +The combined effect of this patch is to leave 7 DMA channels +available + channel 0 for bcm2708_fb via the legacy API. + +See: https://github.com/raspberrypi/linux/issues/1110 + https://github.com/raspberrypi/linux/issues/1108 --- arch/arm/mach-bcm2708/bcm2708.c | 68 ++ arch/arm/mach-bcm2709/bcm2709.c | 68 ++ - drivers/dma/Kconfig | 13 +- + drivers/dma/Kconfig | 11 + drivers/dma/Makefile | 1 + - drivers/dma/bcm2708-dmaengine.c | 1298 +++++++++++++++++++++++++++++ + drivers/dma/bcm2708-dmaengine.c | 1314 +++++++++++++++++++++++++++++ include/linux/platform_data/dma-bcm2708.h | 127 +++ - 6 files changed, 1574 insertions(+), 1 deletion(-) + 6 files changed, 1589 insertions(+) create mode 100644 drivers/dma/bcm2708-dmaengine.c create mode 100644 include/linux/platform_data/dma-bcm2708.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 1735b72..1622300 100644 +index 354dbf6..5624964 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -234,6 +234,73 @@ static struct amba_device *amba_devs[] __initdata = { +@@ -238,6 +238,73 @@ static struct amba_device *amba_devs[] __initdata = { &uart0_device, }; @@ -73624,16 +74273,16 @@ index 1735b72..1622300 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -463,6 +530,7 @@ void __init bcm2708_init(void) +@@ -451,6 +518,7 @@ void __init bcm2708_init(void) bcm2708_init_clocks(); bcm2708_dt_init(); + bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index b173422..fee17e2 100644 +index 5fcd153..ebb6cbc 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -244,6 +244,73 @@ static struct amba_device *amba_devs[] __initdata = { @@ -73710,21 +74359,21 @@ index b173422..fee17e2 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -483,6 +550,7 @@ void __init bcm2709_init(void) +@@ -468,6 +535,7 @@ void __init bcm2709_init(void) bcm2709_init_clocks(); bcm2709_dt_init(); + bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index bda2cb0..21e781f 100644 +index b458475..b0f042c 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig -@@ -337,6 +337,17 @@ config DMA_BCM2835 - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS +@@ -470,6 +470,17 @@ config TIMB_DMA + help + Enable support for the Timberdale FPGA DMA engine. +config DMA_BCM2708 + tristate "BCM2708 DMA engine support" @@ -73740,33 +74389,24 @@ index bda2cb0..21e781f 100644 config TI_CPPI41 tristate "AM33xx CPPI41 DMA support" depends on ARCH_OMAP -@@ -385,7 +396,7 @@ config MOXART_DMA - select DMA_VIRTUAL_CHANNELS - help - Enable support for the MOXA ART SoC DMA controller. -- -+ - config FSL_EDMA - tristate "Freescale eDMA engine support" - depends on OF diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile -index 69f77d5..678e162 100644 +index 7711a71..7308bd3 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o - obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o - obj-$(CONFIG_DMA_OMAP) += omap-dma.o - obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o +@@ -18,6 +18,7 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o + obj-$(CONFIG_AT_XDMAC) += at_xdmac.o + obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o + obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o +obj-$(CONFIG_DMA_BCM2708) += bcm2708-dmaengine.o - obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o + obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c new file mode 100644 -index 0000000..987ed53 +index 0000000..85ce18b --- /dev/null +++ b/drivers/dma/bcm2708-dmaengine.c -@@ -0,0 +1,1298 @@ +@@ -0,0 +1,1314 @@ +/* + * BCM2835 DMA engine support + * @@ -73953,7 +74593,7 @@ index 0000000..987ed53 +} + +static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) ++ unsigned required_feature_set) +{ + u32 chans; + int chan = 0; @@ -73962,10 +74602,8 @@ index 0000000..987ed53 + chans = dmaman->chan_available; + for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) + /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) ++ features */ ++ if (required_feature_set & (1 << feature)) + chans &= dmaman->has_feature[feature]; + + if (!chans) @@ -73997,7 +74635,7 @@ index 0000000..987ed53 + +/* DMA Manager Monitor */ + -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++extern int bcm_dma_chan_alloc(unsigned required_feature_set, + void __iomem **out_dma_base, int *out_dma_irq) +{ + struct vc_dmaman *dmaman = g_dmaman; @@ -74009,7 +74647,7 @@ index 0000000..987ed53 + return -ENODEV; + + mutex_lock(&dmaman->lock); -+ chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); ++ chan = vc_dmaman_chan_alloc(dmaman, required_feature_set); + if (chan < 0) + goto out; + @@ -74211,6 +74849,7 @@ index 0000000..987ed53 + return container_of(t, struct bcm2835_desc, vd.tx); +} + ++#if 0 +static void dma_dumpregs(struct bcm2835_chan *c) +{ + pr_debug("-------------DMA DUMPREGS-------------\n"); @@ -74226,6 +74865,7 @@ index 0000000..987ed53 + readl(c->chan_base + BCM2835_DMA_NEXTCB)); + pr_debug("--------------------------------------\n"); +} ++#endif + +static void bcm2835_dma_desc_free(struct virt_dma_desc *vd) +{ @@ -74631,6 +75271,7 @@ index 0000000..987ed53 + uint32_t len = sg_dma_len(sgent); + + for (j = 0; j < len; j += max_size) { ++ u32 waits; + struct bcm2835_dma_cb *control_block = + &d->control_block_base[i+splitct]; + @@ -74648,7 +75289,7 @@ index 0000000..987ed53 + } + + /* Common part */ -+ u32 waits = SDHCI_BCM_DMA_WAITS; ++ waits = SDHCI_BCM_DMA_WAITS; + if ((dma_debug >> 0) & 0x1f) + waits = (dma_debug >> 0) & 0x1f; + control_block->info |= BCM2835_DMA_WAITS(waits); @@ -74733,6 +75374,7 @@ index 0000000..987ed53 + * c->desc is NULL and exit.) + */ + if (c->desc) { ++ bcm2835_dma_desc_free(&c->desc->vd); + c->desc = NULL; + bcm2835_dma_abort(c->chan_base); + @@ -74842,6 +75484,14 @@ index 0000000..987ed53 + int rc; + int i; + int irq; ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++ static const u32 wanted_features[] = { ++ BCM_DMA_FEATURE_FAST, ++ BCM_DMA_FEATURE_NORMAL, ++ BCM_DMA_FEATURE_LITE ++ }; ++ int j; ++#endif + + + if (!pdev->dev.dma_mask) @@ -74888,20 +75538,24 @@ index 0000000..987ed53 + + platform_set_drvdata(pdev, od); + -+ for (i = 0; i < 5; i++) { ++ for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) { ++ + void __iomem *chan_base; + int chan_id; + -+ chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE, -+ &chan_base, -+ &irq); ++ chan_id = bcm_dma_chan_alloc(wanted_features[j], ++ &chan_base, ++ &irq); + -+ if (chan_id < 0) -+ break; ++ if (chan_id < 0) { ++ j++; ++ continue; ++ } + + rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq); + if (rc) + goto err_no_dma; ++ i++; + } + + if (pdev->dev.of_node) { @@ -74914,6 +75568,8 @@ index 0000000..987ed53 + } + } + ++ dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i); ++ +#else + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) @@ -75199,10 +75855,96 @@ index 0000000..2310e34 + +#endif /* _PLAT_BCM2708_DMA_H */ -From 44cbf9ce5089b224b53fa45eade2bfb7111bc2db Mon Sep 17 00:00:00 2001 +From dcdbec87712932f319e3772806c9cd2c538cefd3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 17 Apr 2015 19:30:22 +0100 +Subject: [PATCH 017/113] Add blk_pos parameter to mmc multi_io_quirk callback + +--- + drivers/mmc/card/block.c | 1 + + drivers/mmc/host/omap_hsmmc.c | 4 +++- + drivers/mmc/host/sh_mobile_sdhi.c | 4 +++- + drivers/mmc/host/tmio_mmc_pio.c | 4 +++- + include/linux/mmc/host.h | 4 +++- + 5 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index c742cfd..566fca5 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1428,6 +1428,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, + brq->data.blocks = card->host->ops->multi_io_quirk(card, + (rq_data_dir(req) == READ) ? + MMC_DATA_READ : MMC_DATA_WRITE, ++ blk_rq_pos(req), + brq->data.blocks); + } + +diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c +index 7fb0753..708d0fa 100644 +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -1832,7 +1832,9 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) + } + + static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, +- unsigned int direction, int blk_size) ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size) + { + /* This controller can't do multiblock reads due to hw bugs */ + if (direction == MMC_DATA_READ) +diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c +index 354f4f3..4f1ccf3 100644 +--- a/drivers/mmc/host/sh_mobile_sdhi.c ++++ b/drivers/mmc/host/sh_mobile_sdhi.c +@@ -170,7 +170,9 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) + } + + static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card, +- unsigned int direction, int blk_size) ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size) + { + /* + * In Renesas controllers, when performing a +diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c +index a10fde4..7b730d8 100644 +--- a/drivers/mmc/host/tmio_mmc_pio.c ++++ b/drivers/mmc/host/tmio_mmc_pio.c +@@ -1003,7 +1003,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) + } + + static int tmio_multi_io_quirk(struct mmc_card *card, +- unsigned int direction, int blk_size) ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size) + { + struct tmio_mmc_host *host = mmc_priv(card->host); + +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +index 17bec60..9597d4e 100644 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -143,7 +143,9 @@ struct mmc_host_ops { + * I/O. Returns the number of supported blocks for the request. + */ + int (*multi_io_quirk)(struct mmc_card *card, +- unsigned int direction, int blk_size); ++ unsigned int direction, ++ u32 blk_pos, ++ int blk_size); + }; + + struct mmc_card; + +From b180a5655934b26f809e588018cab2b2f9c3c937 Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 008/204] MMC: added alternative MMC driver +Subject: [PATCH 018/113] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -75266,21 +76008,23 @@ Add Device Tree entry for bcm2835-mmc. In non-DT mode, don't add the device in the board file. Signed-off-by: Noralf Trønnes + +bcm2835-mmc: Don't overwrite MMC capabilities from DT --- arch/arm/mach-bcm2708/bcm2708.c | 31 + arch/arm/mach-bcm2709/bcm2709.c | 35 +- drivers/mmc/core/quirks.c | 6 + drivers/mmc/host/Kconfig | 29 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1558 +++++++++++++++++++++++++++++++++++++++ - 6 files changed, 1658 insertions(+), 2 deletions(-) + drivers/mmc/host/bcm2835-mmc.c | 1559 +++++++++++++++++++++++++++++++++++++++ + 6 files changed, 1659 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 1622300..6257407 100644 +index 5624964..4ea857c 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -401,6 +401,34 @@ static struct platform_device bcm2708_gpio_device = { +@@ -390,6 +390,34 @@ static struct platform_device bcm2708_gpio_device = { }; #endif @@ -75315,7 +76059,7 @@ index 1622300..6257407 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -538,6 +566,9 @@ void __init bcm2708_init(void) +@@ -526,6 +554,9 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); @@ -75326,10 +76070,10 @@ index 1622300..6257407 100644 bcm2708_init_uart1(); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index fee17e2..07750ed 100644 +index ebb6cbc..b762819 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -421,6 +421,34 @@ static struct platform_device bcm2708_gpio_device = { +@@ -406,6 +406,34 @@ static struct platform_device bcm2708_gpio_device = { }; #endif @@ -75364,7 +76108,7 @@ index fee17e2..07750ed 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -558,8 +586,11 @@ void __init bcm2709_init(void) +@@ -543,8 +571,11 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); @@ -75402,7 +76146,7 @@ index dd1d1e0..bc3bbad 100644 } EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index b1f837e..0ef7417 100644 +index 8a1e349..6d5b8bb 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -4,6 +4,35 @@ @@ -75442,7 +76186,7 @@ index b1f837e..0ef7417 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index e3ab5b9..f1ee1f7 100644 +index 4f3452a..68e64ab 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -75452,13 +76196,13 @@ index e3ab5b9..f1ee1f7 100644 +obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o - obj-$(CONFIG_MMC_OMAP) += omap.o + obj-$(CONFIG_MMC_MTK) += mtk-sd.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..b7c4883 +index 0000000..164bfad --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1558 @@ +@@ -0,0 +1,1559 @@ +/* + * BCM2835 MMC host driver. + * @@ -76788,8 +77532,9 @@ index 0000000..b7c4883 + mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; +#endif + /* host controller capabilities */ -+ mmc->caps = MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ | -+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; ++ mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | ++ MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | ++ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; + + host->flags = SDHCI_AUTO_CMD23; + @@ -77018,10 +77763,10 @@ index 0000000..b7c4883 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From b0a083aa54f21ac74e866d9c016653d247e6d2b7 Mon Sep 17 00:00:00 2001 +From 03dd4d58692aa393fe68b09e0f1f4a58583afa27 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 009/204] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 019/113] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. @@ -77042,15 +77787,61 @@ Use at your own risk. bcm2835-sdhost: Round up the overclock, so 62 works for 62.5Mhz Also only warn once for each overclock setting. + +bcm2835-sdhost: Improve error handling and recovery + +1) Expose the hw_reset method to the MMC framework, removing many + internal calls by the driver. + +2) Reduce overclock setting on error. + +3) Increase timeout to cope with high capacity cards. + +4) Add properties and parameters to control pio_limit and debug. + +5) Reduce messages at probe time. + +bcm2835-sdhost: Further improve overclock back-off + +bcm2835-sdhost: Clear HBLC for PIO mode + +Also update pio_limit default in overlay README. + +bcm2835-sdhost: Add the ERASE capability + +See: https://github.com/raspberrypi/linux/issues/1076 + +bcm2835-sdhost: Ignore CRC7 for MMC CMD1 + +It seems that the sdhost interface returns CRC7 errors for CMD1, +which is the MMC-specific SEND_OP_COND. Returning these errors to +the MMC layer causes a downward spiral, but ignoring them seems +to be harmless. + +bcm2835-mmc/sdhost: Remove ARCH_BCM2835 differences + +The bcm2835-mmc driver (and -sdhost driver that copied from it) +contains code to handle SDIO interrupts in a threaded interrupt +handler rather than waking the MMC framework thread. The change +follows a patch from Russell King that adds the facility as the +preferred way of working. + +However, the new code path is only present in ARCH_BCM2835 +builds, which I have taken to be a way of testing the waters +rather than making the change across the board; I can't see +any technical reason why it wouldn't be enabled for MACH_BCM270X +builds. So this patch standardises on the ARCH_BCM2835 code, +removing the old code paths. --- drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 1702 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 1713 insertions(+) + drivers/mmc/host/bcm2835-mmc.c | 28 +- + drivers/mmc/host/bcm2835-sdhost.c | 1912 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 1927 insertions(+), 24 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-sdhost.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 0ef7417..1af139a 100644 +index 6d5b8bb..3b9febc 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER @@ -77071,7 +77862,7 @@ index 0ef7417..1af139a 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index f1ee1f7..8c656a5 100644 +index 68e64ab..edf2855 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -77082,12 +77873,111 @@ index f1ee1f7..8c656a5 100644 obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c +index 164bfad..0f89e57 100644 +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -684,12 +684,10 @@ void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd + } + + timeout = jiffies; +-#ifdef CONFIG_ARCH_BCM2835 + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else +-#endif +- timeout += 10 * HZ; ++ timeout += 10 * HZ; + mod_timer(&host->timer, timeout); + + host->cmd = cmd; +@@ -984,9 +982,6 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + struct bcm2835_host *host = dev_id; + u32 intmask, mask, unexpected = 0; + int max_loops = 16; +-#ifndef CONFIG_ARCH_BCM2835 +- int cardint = 0; +-#endif + + spin_lock(&host->lock); + +@@ -1015,13 +1010,9 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + mmc_hostname(host->mmc)); + + if (intmask & SDHCI_INT_CARD_INT) { +-#ifndef CONFIG_ARCH_BCM2835 +- cardint = 1; +-#else + bcm2835_mmc_enable_sdio_irq_nolock(host, false); + host->thread_isr |= SDHCI_INT_CARD_INT; + result = IRQ_WAKE_THREAD; +-#endif + } + + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | +@@ -1048,15 +1039,9 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + bcm2835_mmc_dumpregs(host); + } + +-#ifndef CONFIG_ARCH_BCM2835 +- if (cardint) +- mmc_signal_sdio_irq(host->mmc); +-#endif +- + return result; + } + +-#ifdef CONFIG_ARCH_BCM2835 + static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) + { + struct bcm2835_host *host = dev_id; +@@ -1079,7 +1064,6 @@ static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) + + return isr ? IRQ_HANDLED : IRQ_NONE; + } +-#endif + + + +@@ -1323,14 +1307,15 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) + + /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ + host->timeout_clk = mmc->f_max / 1000; +-#ifdef CONFIG_ARCH_BCM2835 + mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; +-#endif ++ + /* host controller capabilities */ + mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | + MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; + ++ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; ++ + host->flags = SDHCI_AUTO_CMD23; + + dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); +@@ -1378,14 +1363,9 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) + init_waitqueue_head(&host->buf_ready_int); + + bcm2835_mmc_init(host, 0); +-#ifndef CONFIG_ARCH_BCM2835 +- ret = devm_request_irq(dev, host->irq, bcm2835_mmc_irq, 0, +- mmc_hostname(mmc), host); +-#else + ret = devm_request_threaded_irq(dev, host->irq, bcm2835_mmc_irq, + bcm2835_mmc_thread_irq, IRQF_SHARED, + mmc_hostname(mmc), host); +-#endif + if (ret) { + dev_err(dev, "Failed to request IRQ %d: %d\n", host->irq, ret); + goto untasklet; diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c new file mode 100644 -index 0000000..eef8a24 +index 0000000..0623392 --- /dev/null +++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -0,0 +1,1702 @@ +@@ -0,0 +1,1912 @@ +/* + * BCM2835 SD host driver. + * @@ -77180,9 +78070,8 @@ index 0000000..eef8a24 +/* Reserved */ +#define SDHSTS_DATA_FLAG 0x01 + -+#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) ++#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) +#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) -+/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ + +#define SDHCFG_BUSY_IRPT_EN (1<<10) +#define SDHCFG_BLOCK_IRPT_EN (1<<8) @@ -77201,16 +78090,7 @@ index 0000000..eef8a24 +#define SDEDM_READ_THRESHOLD_SHIFT 14 +#define SDEDM_THRESHOLD_MASK 0x1f + -+/* the inclusive limit in bytes under which PIO will be used instead of DMA */ -+#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#else -+#define PIO_DMA_BARRIER 0 -+#endif -+ -+#define MIN_FREQ 400000 -+#define TIMEOUT_VAL 0xE -+#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) ++#define MHZ 1000000 + +#ifndef BCM2708_PERI_BASE + #define BCM2708_PERI_BASE 0x20000000 @@ -77228,19 +78108,20 @@ index 0000000..eef8a24 + + struct mmc_host *mmc; + -+ u32 timeout; ++ u32 pio_timeout; /* In jiffies */ + + int clock; /* Current clock speed */ + + bool slow_card; /* Force 11-bit divisor */ + + unsigned int max_clk; /* Max possible freq */ -+ unsigned int timeout_clk; /* Timeout freq (KHz) */ + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + + struct timer_list timer; /* Timer for timeouts */ + ++ struct timer_list pio_timer; /* PIO error detection timer */ ++ + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + @@ -77260,6 +78141,8 @@ index 0000000..eef8a24 + + unsigned int use_busy:1; /* Wait for busy interrupt */ + ++ unsigned int debug:1; /* Enable debug output */ ++ + u32 thread_isr; + + /*DMA part*/ @@ -77275,7 +78158,8 @@ index 0000000..eef8a24 + struct timeval stop_time; /* when the last stop was issued */ + u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ + u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -+ u32 max_overclock; /* Highest reported */ ++ u32 overclock; /* Current frequency if overclocked, else zero */ ++ u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ +}; + + @@ -77294,41 +78178,79 @@ index 0000000..eef8a24 + return readl_relaxed(host->ioaddr + reg); +} + ++static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, ++ struct mmc_command *cmd, ++ const char *label) ++{ ++ if (cmd) ++ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", ++ mmc_hostname(host->mmc), ++ (cmd == host->cmd) ? '>' : ' ', ++ label, cmd->opcode, cmd->arg, cmd->flags, ++ cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], ++ cmd->error); ++} ++ +static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) +{ -+ pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", ++ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); ++ if (host->mrq->data) ++ pr_err("%s: data blocks %x blksz %x - err %d\n", ++ mmc_hostname(host->mmc), ++ host->mrq->data->blocks, ++ host->mrq->data->blksz, ++ host->mrq->data->error); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); ++ ++ pr_info("%s: =========== REGISTER DUMP ===========\n", + mmc_hostname(host->mmc)); + -+ pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", ++ pr_info("%s: SDCMD 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCMD)); -+ pr_info(DRIVER_NAME ": SDARG 0x%08x\n", ++ pr_info("%s: SDARG 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDARG)); -+ pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", ++ pr_info("%s: SDTOUT 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDTOUT)); -+ pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", ++ pr_info("%s: SDCDIV 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCDIV)); -+ pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", ++ pr_info("%s: SDRSP0 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP0)); -+ pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", ++ pr_info("%s: SDRSP1 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP1)); -+ pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", ++ pr_info("%s: SDRSP2 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP2)); -+ pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", ++ pr_info("%s: SDRSP3 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP3)); -+ pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", ++ pr_info("%s: SDHSTS 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHSTS)); -+ pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", ++ pr_info("%s: SDVDD 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDVDD)); -+ pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", ++ pr_info("%s: SDEDM 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDEDM)); -+ pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", ++ pr_info("%s: SDHCFG 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHCFG)); -+ pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", ++ pr_info("%s: SDHBCT 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBCT)); -+ pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", ++ pr_info("%s: SDHBLC 0x%08x\n", ++ mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBLC)); + -+ pr_debug(DRIVER_NAME ": ===========================================\n"); ++ pr_info("%s: ===========================================\n", ++ mmc_hostname(host->mmc)); +} + + @@ -77338,12 +78260,10 @@ index 0000000..eef8a24 +} + + -+static void bcm2835_sdhost_reset(struct bcm2835_host *host) ++static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) +{ + u32 temp; + -+ pr_debug("bcm2835_sdhost_reset\n"); -+ + bcm2835_sdhost_set_power(host, false); + + bcm2835_sdhost_write(host, 0, SDCMD); @@ -77371,6 +78291,20 @@ index 0000000..eef8a24 + mmiowb(); +} + ++ ++static void bcm2835_sdhost_reset(struct mmc_host *mmc) ++{ ++ struct bcm2835_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ if (host->debug) ++ pr_info("%s: reset\n", mmc_hostname(mmc)); ++ spin_lock_irqsave(&host->lock, flags); ++ ++ bcm2835_sdhost_reset_internal(host); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ +static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + +static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) @@ -77380,7 +78314,7 @@ index 0000000..eef8a24 + /* Set interrupt enables */ + host->hcfg = SDHCFG_BUSY_IRPT_EN; + -+ bcm2835_sdhost_reset(host); ++ bcm2835_sdhost_reset_internal(host); + + if (soft) { + /* force clock reconfiguration */ @@ -77510,6 +78444,29 @@ index 0000000..eef8a24 + spin_unlock_irqrestore(&host->lock, flags); +} + ++static bool data_transfer_wait(struct bcm2835_host *host) ++{ ++ unsigned long timeout = 1000000; ++ while (timeout) ++ { ++ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (sdhsts & SDHSTS_DATA_FLAG) { ++ bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); ++ break; ++ } ++ timeout--; ++ } ++ if (timeout == 0) { ++ pr_err("%s: Data %s timeout\n", ++ mmc_hostname(host->mmc), ++ (host->data->flags & MMC_DATA_READ) ? "read" : "write"); ++ bcm2835_sdhost_dumpregs(host); ++ host->data->error = -ETIMEDOUT; ++ return false; ++ } ++ return true; ++} ++ +static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; @@ -77533,35 +78490,15 @@ index 0000000..eef8a24 + buf = (u32 *)host->sg_miter.addr; + + while (len) { -+ while (1) { -+ u32 hsts; -+ hsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (hsts & SDHSTS_DATA_FLAG) -+ break; -+ -+ if (hsts & SDHSTS_ERROR_MASK) { -+ pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", -+ mmc_hostname(host->mmc), -+ hsts, -+ bcm2835_sdhost_read(host, SDHBCT), -+ blksize + len); -+ if (hsts & SDHSTS_REW_TIME_OUT) -+ host->data->error = -ETIMEDOUT; -+ else if (hsts & (SDHSTS_CRC16_ERROR || -+ SDHSTS_CRC7_ERROR)) -+ host->data->error = -EILSEQ; -+ else { -+ pr_err("%s: unexpected data error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ } -+ } -+ } ++ if (!data_transfer_wait(host)) ++ break; + + *(buf++) = bcm2835_sdhost_read(host, SDDATA); + len -= 4; + } ++ ++ if (host->data->error) ++ break; + } + + sg_miter_stop(&host->sg_miter); @@ -77592,11 +78529,15 @@ index 0000000..eef8a24 + buf = host->sg_miter.addr; + + while (len) { -+ while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) -+ continue; ++ if (!data_transfer_wait(host)) ++ break; ++ + bcm2835_sdhost_write(host, *(buf++), SDDATA); + len -= 4; + } ++ ++ if (host->data->error) ++ break; + } + + sg_miter_stop(&host->sg_miter); @@ -77607,12 +78548,37 @@ index 0000000..eef8a24 + +static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) +{ ++ u32 sdhsts; ++ bool is_read; + BUG_ON(!host->data); + -+ if (host->data->flags & MMC_DATA_READ) ++ is_read = (host->data->flags & MMC_DATA_READ) != 0; ++ if (is_read) + bcm2835_sdhost_read_block_pio(host); + else + bcm2835_sdhost_write_block_pio(host); ++ ++ sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (sdhsts & (SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | ++ SDHSTS_FIFO_ERROR)) { ++ pr_err("%s: %s transfer error - HSTS %x\n", ++ mmc_hostname(host->mmc), ++ is_read ? "read" : "write", ++ sdhsts); ++ host->data->error = -EILSEQ; ++ } else if ((sdhsts & (SDHSTS_CMD_TIME_OUT | ++ SDHSTS_REW_TIME_OUT))) { ++ pr_err("%s: %s timeout error - HSTS %x\n", ++ mmc_hostname(host->mmc), ++ is_read ? "read" : "write", ++ sdhsts); ++ host->data->error = -ETIMEDOUT; ++ } else if (!is_read && !host->data->error) { ++ /* Start a timer in case a transfer error occurs because ++ there is no error interrupt */ ++ mod_timer(&host->pio_timer, jiffies + host->pio_timeout); ++ } +} + + @@ -77697,6 +78663,7 @@ index 0000000..eef8a24 + host->flush_fifo = 0; + host->data->bytes_xfered = 0; + ++ host->use_dma = host->have_dma && (data->blocks > host->pio_limit); + if (!host->use_dma) { + int flags; + @@ -77709,13 +78676,10 @@ index 0000000..eef8a24 + host->blocks = data->blocks; + } + -+ host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; -+ + bcm2835_sdhost_set_transfer_irqs(host); + + bcm2835_sdhost_write(host, data->blksz, SDHBCT); -+ if (host->use_dma) -+ bcm2835_sdhost_write(host, data->blocks, SDHBLC); ++ bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); + + BUG_ON(!host->data); +} @@ -77723,27 +78687,31 @@ index 0000000..eef8a24 + +void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) +{ -+ u32 sdcmd; ++ u32 sdcmd, sdhsts; + unsigned long timeout; ++ int delay; + + WARN_ON(host->cmd); + -+ if (1) { -+ pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", -+ cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); -+ if (cmd->data) -+ pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ } ++ if (cmd->data) ++ pr_debug("%s: send_command %d 0x%x " ++ "(flags 0x%x) - %s %d*%d\n", ++ mmc_hostname(host->mmc), ++ cmd->opcode, cmd->arg, cmd->flags, ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ else ++ pr_debug("%s: send_command %d 0x%x (flags 0x%x)\n", ++ mmc_hostname(host->mmc), ++ cmd->opcode, cmd->arg, cmd->flags); + -+ /* Wait max 10 ms */ -+ timeout = 1000; ++ /* Wait max 100 ms */ ++ timeout = 10000; + + while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { + if (timeout == 0) { -+ pr_err("%s: Previous command never completed.\n", ++ pr_err("%s: previous command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + cmd->error = -EIO; @@ -77754,28 +78722,34 @@ index 0000000..eef8a24 + udelay(10); + } + -+ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { -+ host->max_delay = (1000-timeout)/100; -+ pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); ++ delay = (10000 - timeout)/100; ++ if (delay > host->max_delay) { ++ host->max_delay = delay; ++ pr_warning("%s: controller hung for %d ms\n", ++ mmc_hostname(host->mmc), ++ host->max_delay); + } + + timeout = jiffies; -+#ifdef CONFIG_ARCH_BCM2835 + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else -+#endif -+ timeout += 10 * HZ; ++ timeout += 10 * HZ; + mod_timer(&host->timer, timeout); + + host->cmd = cmd; + ++ /* Clear any error flags */ ++ sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (sdhsts & SDHSTS_ERROR_MASK) ++ bcm2835_sdhost_write(host, sdhsts, SDHSTS); ++ + bcm2835_sdhost_prepare_data(host, cmd); + + bcm2835_sdhost_write(host, cmd->arg, SDARG); + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { -+ pr_err("%s: Unsupported response type!\n", ++ pr_err("%s: unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); @@ -77873,13 +78847,6 @@ index 0000000..eef8a24 + pr_debug("transfer_complete(error %d, stop %d)\n", + data->error, data->stop ? 1 : 0); + -+ if (data->error) -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ bcm2835_sdhost_reset(host); -+ + /* + * Need to send CMD12 if - + * a) open-ended multiblock transfer (no CMD23) @@ -77902,7 +78869,7 @@ index 0000000..eef8a24 +static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) +{ + u32 sdcmd; -+ int timeout = 1000; ++ unsigned long timeout; +#ifdef DEBUG + struct timeval before, after; + int timediff = 0; @@ -77915,6 +78882,8 @@ index 0000000..eef8a24 +#ifdef DEBUG + do_gettimeofday(&before); +#endif ++ /* Wait max 100 ms */ ++ timeout = 10000; + for (sdcmd = bcm2835_sdhost_read(host, SDCMD); + (sdcmd & SDCMD_NEW_FLAG) && timeout; + timeout--) { @@ -77935,7 +78904,7 @@ index 0000000..eef8a24 +#endif + + if (timeout == 0) { -+ pr_err("%s: Command never completed.\n", ++ pr_err("%s: command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + host->cmd->error = -EIO; @@ -77965,21 +78934,37 @@ index 0000000..eef8a24 + { + u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); + -+ pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -+ mmc_hostname(host->mmc), sdcmd, sdhsts, -+ bcm2835_sdhost_read(host, SDEDM)); ++ if (host->debug) ++ pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", ++ mmc_hostname(host->mmc), sdcmd, sdhsts, ++ bcm2835_sdhost_read(host, SDEDM)); + -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ { -+ pr_err("%s: unexpected command error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; ++ if ((sdhsts & SDHSTS_CRC7_ERROR) && ++ (host->cmd->opcode == 1)) { ++ if (host->debug) ++ pr_info("%s: ignoring CRC7 error for CMD1\n", ++ mmc_hostname(host->mmc)); ++ } else { ++ if (sdhsts & SDHSTS_CMD_TIME_OUT) { ++ switch (host->cmd->opcode) { ++ case 5: case 52: case 53: ++ /* Don't warn about SDIO commands */ ++ break; ++ default: ++ pr_err("%s: command timeout\n", ++ mmc_hostname(host->mmc)); ++ break; ++ } ++ host->cmd->error = -ETIMEDOUT; ++ } else { ++ pr_err("%s: unexpected command error\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ } ++ tasklet_schedule(&host->finish_tasklet); ++ return; + } -+ tasklet_schedule(&host->finish_tasklet); -+ return; + } + + if (host->cmd->flags & MMC_RSP_PRESENT) { @@ -77987,11 +78972,13 @@ index 0000000..eef8a24 + int i; + for (i = 0; i < 4; i++) + host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); -+ pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", ++ pr_debug("%s: finish_command %08x %08x %08x %08x\n", ++ mmc_hostname(host->mmc), + host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); + } else { + host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); -+ pr_debug("bcm2835_sdhost_finish_command: %08x\n", ++ pr_debug("%s: finish_command %08x\n", ++ mmc_hostname(host->mmc), + host->cmd->resp[0]); + } + } @@ -78022,7 +79009,7 @@ index 0000000..eef8a24 + } +} + -+static void bcm2835_sdhost_timeout_timer(unsigned long data) ++static void bcm2835_sdhost_timeout(unsigned long data) +{ + struct bcm2835_host *host; + unsigned long flags; @@ -78032,7 +79019,7 @@ index 0000000..eef8a24 + spin_lock_irqsave(&host->lock, flags); + + if (host->mrq) { -+ pr_err("%s: Timeout waiting for hardware interrupt.\n", ++ pr_err("%s: timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + @@ -78054,6 +79041,41 @@ index 0000000..eef8a24 + spin_unlock_irqrestore(&host->lock, flags); +} + ++static void bcm2835_sdhost_pio_timeout(unsigned long data) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ host = (struct bcm2835_host *)data; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host->data) { ++ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ ++ if (sdhsts & SDHSTS_REW_TIME_OUT) { ++ pr_err("%s: transfer timeout\n", ++ mmc_hostname(host->mmc)); ++ if (host->debug) ++ bcm2835_sdhost_dumpregs(host); ++ } else { ++ pr_err("%s: unexpected transfer timeout\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ } ++ ++ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, ++ SDHSTS); ++ ++ host->data->error = -ETIMEDOUT; ++ ++ bcm2835_sdhost_finish_data(host); ++ } ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ +static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) +{ + if (enable) @@ -78069,7 +79091,7 @@ index 0000000..eef8a24 + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + -+ pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); ++ pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); + spin_lock_irqsave(&host->lock, flags); + bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); + spin_unlock_irqrestore(&host->lock, flags); @@ -78077,11 +79099,12 @@ index 0000000..eef8a24 + +static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) +{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | ++ SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | ++ SDHSTS_FIFO_ERROR); + + if (!host->cmd) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " ++ pr_err("%s: got command busy interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); @@ -78089,7 +79112,7 @@ index 0000000..eef8a24 + } + + if (!host->use_busy) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " ++ pr_err("%s: got command busy interrupt 0x%08x even " + "though not expecting one.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); @@ -78097,14 +79120,28 @@ index 0000000..eef8a24 + } + host->use_busy = 0; + -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->cmd->error = -EILSEQ; ++ if (intmask & SDHSTS_ERROR_MASK) ++ { ++ pr_err("sdhost_busy_irq: intmask %x, data %p\n", intmask, host->mrq->data); ++ if (intmask & SDHSTS_CRC7_ERROR) ++ host->cmd->error = -EILSEQ; ++ else if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR)) { ++ if (host->mrq->data) ++ host->mrq->data->error = -EILSEQ; ++ else ++ host->cmd->error = -EILSEQ; ++ } else if (intmask & SDHSTS_REW_TIME_OUT) { ++ if (host->mrq->data) ++ host->mrq->data->error = -ETIMEDOUT; ++ else ++ host->cmd->error = -ETIMEDOUT; ++ } else if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; + -+ if (host->cmd->error) ++ bcm2835_sdhost_dumpregs(host); + tasklet_schedule(&host->finish_tasklet); ++ } + else + bcm2835_sdhost_finish_command(host); + @@ -78113,8 +79150,9 @@ index 0000000..eef8a24 + +static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) +{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ const u32 handled = (SDHSTS_REW_TIME_OUT | ++ SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR); + + /* There are no dedicated data/space available interrupt + status bits, so it is necessary to use the single shared @@ -78124,13 +79162,19 @@ index 0000000..eef8a24 + if (!host->data) + return 0; + -+ // XXX FIFO_ERROR -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR | ++ SDHSTS_REW_TIME_OUT)) { ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR)) ++ host->data->error = -EILSEQ; ++ else ++ host->data->error = -ETIMEDOUT; ++ ++ bcm2835_sdhost_dumpregs(host); ++ tasklet_schedule(&host->finish_tasklet); ++ return handled; ++ } + + /* Use the block interrupt for writes after the first block */ + if (host->data->flags & MMC_DATA_WRITE) { @@ -78157,31 +79201,48 @@ index 0000000..eef8a24 +{ + struct dma_chan *dma_chan; + u32 dir_data; -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ const u32 handled = (SDHSTS_REW_TIME_OUT | ++ SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR); + + if (!host->data) { -+ pr_err("%s: Got block interrupt 0x%08x even " ++ pr_err("%s: got block interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); + return handled; + } + -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR | ++ SDHSTS_REW_TIME_OUT)) { ++ if (intmask & (SDHSTS_CRC16_ERROR | ++ SDHSTS_FIFO_ERROR)) ++ host->data->error = -EILSEQ; ++ else ++ host->data->error = -ETIMEDOUT; ++ ++ if (host->debug) ++ bcm2835_sdhost_dumpregs(host); ++ tasklet_schedule(&host->finish_tasklet); ++ return handled; ++ } + + if (!host->use_dma) { + BUG_ON(!host->blocks); + host->blocks--; -+ if ((host->blocks == 0) || host->data->error) ++ if ((host->blocks == 0) || host->data->error) { ++ /* Cancel the timer */ ++ del_timer(&host->pio_timer); ++ + bcm2835_sdhost_finish_data(host); -+ else ++ } else { + bcm2835_sdhost_transfer_pio(host); ++ ++ /* Reset the timer */ ++ mod_timer(&host->pio_timer, ++ jiffies + host->pio_timeout); ++ } + } else if (host->data->flags & MMC_DATA_WRITE) { + dma_chan = host->dma_chan_tx; + dir_data = DMA_TO_DEVICE; @@ -78202,9 +79263,7 @@ index 0000000..eef8a24 + struct bcm2835_host *host = dev_id; + u32 unexpected = 0, early = 0; + int loops = 0; -+#ifndef CONFIG_ARCH_BCM2835 -+ int cardint = 0; -+#endif ++ + spin_lock(&host->lock); + + for (loops = 0; loops < 1; loops++) { @@ -78215,7 +79274,7 @@ index 0000000..eef8a24 + SDHSTS_BLOCK_IRPT | + SDHSTS_SDIO_IRPT | + SDHSTS_DATA_FLAG); -+ if ((handled == SDHSTS_DATA_FLAG) && // XXX ++ if ((handled == SDHSTS_DATA_FLAG) && + (loops == 0) && !host->data) { + pr_err("%s: sdhost_irq data interrupt 0x%08x even " + "though no data operation was in progress.\n", @@ -78250,13 +79309,9 @@ index 0000000..eef8a24 + handled |= bcm2835_sdhost_block_irq(host, intmask); + + if (intmask & SDHSTS_SDIO_IRPT) { -+#ifndef CONFIG_ARCH_BCM2835 -+ cardint = 1; -+#else + bcm2835_sdhost_enable_sdio_irq_nolock(host, false); + host->thread_isr |= SDHSTS_SDIO_IRPT; + result = IRQ_WAKE_THREAD; -+#endif + } + + unexpected |= (intmask & ~handled); @@ -78267,23 +79322,18 @@ index 0000000..eef8a24 + spin_unlock(&host->lock); + + if (early) -+ pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); ++ pr_debug("%s: early %x (loops %d)\n", ++ mmc_hostname(host->mmc), early, loops); + + if (unexpected) { -+ pr_err("%s: Unexpected interrupt 0x%08x.\n", ++ pr_err("%s: unexpected interrupt 0x%08x.\n", + mmc_hostname(host->mmc), unexpected); + bcm2835_sdhost_dumpregs(host); + } + -+#ifndef CONFIG_ARCH_BCM2835 -+ if (cardint) -+ mmc_signal_sdio_irq(host->mmc); -+#endif -+ + return result; +} + -+#ifdef CONFIG_ARCH_BCM2835 +static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) +{ + struct bcm2835_host *host = dev_id; @@ -78308,7 +79358,6 @@ index 0000000..eef8a24 + + return isr ? IRQ_HANDLED : IRQ_NONE; +} -+#endif + + + @@ -78317,8 +79366,13 @@ index 0000000..eef8a24 + int div = 0; /* Initialized for compiler warning */ + unsigned int input_clock = clock; + -+ if (host->overclock_50 && (clock == 50000000)) -+ clock = host->overclock_50 * 1000000 + 999999; ++ if (host->debug) ++ pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); ++ ++ if ((host->overclock_50 > 50) && ++ (clock == 50*MHZ)) { ++ clock = host->overclock_50 * MHZ + (MHZ - 1); ++ } + + /* The SDCDIV register has 11 bits, and holds (div - 2). + But in data mode the max is 50MHz wihout a minimum, and only the @@ -78365,17 +79419,35 @@ index 0000000..eef8a24 + clock = host->max_clk / (div + 2); + host->mmc->actual_clock = clock; + -+ if ((clock > input_clock) && (clock > host->max_overclock)) { -+ pr_warn("%s: Overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); -+ host->max_overclock = clock; ++ if (clock > input_clock) { ++ /* Save the closest value, to make it easier ++ to reduce in the event of error */ ++ host->overclock_50 = (clock/MHZ); ++ ++ if (clock != host->overclock) { ++ pr_warn("%s: overclocking to %dHz\n", ++ mmc_hostname(host->mmc), clock); ++ host->overclock = clock; ++ } ++ } ++ else if (host->overclock) ++ { ++ host->overclock = 0; ++ if (clock == 50 * MHZ) ++ pr_warn("%s: cancelling overclock\n", ++ mmc_hostname(host->mmc)); + } + + host->cdiv = div; + bcm2835_sdhost_write(host, host->cdiv, SDCDIV); + -+ pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); ++ /* Set the timeout to 500ms */ ++ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); ++ ++ if (host->debug) ++ pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", ++ mmc_hostname(host->mmc), input_clock, ++ host->max_clk, host->cdiv, host->mmc->actual_clock); +} + +static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) @@ -78383,29 +79455,40 @@ index 0000000..eef8a24 + struct bcm2835_host *host; + unsigned long flags; + -+ if (1) { ++ host = mmc_priv(mmc); ++ ++ if (host->debug) { + struct mmc_command *cmd = mrq->cmd; -+ const char *src = "cmd"; + BUG_ON(!cmd); -+ pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", -+ src, cmd->opcode, cmd->arg, cmd->flags); + if (cmd->data) -+ pr_debug("bcm2835_sdhost_request: %s %d*%d\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); ++ pr_info("%s: cmd %d 0x%x (flags 0x%x) - %s %d*%d\n", ++ mmc_hostname(mmc), ++ cmd->opcode, cmd->arg, cmd->flags, ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ else ++ pr_info("%s: cmd %d 0x%x (flags 0x%x)\n", ++ mmc_hostname(mmc), ++ cmd->opcode, cmd->arg, cmd->flags); + } + ++ /* Reset the error statuses in case this is a retry */ ++ if (mrq->cmd) ++ mrq->cmd->error = 0; ++ if (mrq->data) ++ mrq->data->error = 0; ++ if (mrq->stop) ++ mrq->stop->error = 0; ++ + if (mrq->data && !is_power_of_2(mrq->data->blksz)) { -+ pr_err("%s: Unsupported block size (%d bytes)\n", ++ pr_err("%s: unsupported block size (%d bytes)\n", + mmc_hostname(mmc), mrq->data->blksz); + mrq->cmd->error = -EINVAL; + mmc_request_done(mmc, mrq); + return; + } + -+ host = mmc_priv(mmc); -+ + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); @@ -78435,9 +79518,12 @@ index 0000000..eef8a24 + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + -+ pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); ++ if (host->debug) ++ pr_info("%s: ios clock %d, pwr %d, bus_width %d, " ++ "timing %d, vdd %d, drv_type %d\n", ++ mmc_hostname(mmc), ++ ios->clock, ios->power_mode, ios->bus_width, ++ ios->timing, ios->signal_voltage, ios->drv_type); + + spin_lock_irqsave(&host->lock, flags); + @@ -78486,6 +79572,7 @@ index 0000000..eef8a24 + .request = bcm2835_sdhost_request, + .set_ios = bcm2835_sdhost_set_ios, + .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, ++ .hw_reset = bcm2835_sdhost_reset, + .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, +}; + @@ -78513,15 +79600,19 @@ index 0000000..eef8a24 + + mrq = host->mrq; + -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ if (((mrq->cmd && mrq->cmd->error) || -+ (mrq->data && (mrq->data->error || -+ (mrq->data->stop && mrq->data->stop->error))))) { -+ -+ bcm2835_sdhost_reset(host); ++ /* Drop the overclock after any data corruption, or after any ++ error overclocked */ ++ if (host->overclock) { ++ if ((mrq->cmd && mrq->cmd->error) || ++ (mrq->data && mrq->data->error) || ++ (mrq->stop && mrq->stop->error)) { ++ host->overclock_50--; ++ pr_warn("%s: reducing overclock due to errors\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_set_clock(host,50*MHZ); ++ mrq->cmd->error = -EILSEQ; ++ mrq->cmd->retries = 1; ++ } + } + + host->mrq = NULL; @@ -78540,35 +79631,37 @@ index 0000000..eef8a24 +{ + struct mmc_host *mmc; + struct dma_slave_config cfg; ++ char pio_limit_string[20]; + int ret; + + mmc = host->mmc; + -+ bcm2835_sdhost_reset(host); ++ bcm2835_sdhost_reset_internal(host); + + mmc->f_max = host->max_clk; + mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; + -+ /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ -+ host->timeout_clk = mmc->f_max / 1000; -+#ifdef CONFIG_ARCH_BCM2835 -+ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; -+#endif ++ mmc->max_busy_timeout = (~(unsigned int)0)/(mmc->f_max/1000); ++ ++ pr_debug("f_max %d, f_min %d, max_busy_timeout %d\n", ++ mmc->f_max, mmc->f_min, mmc->max_busy_timeout); ++ + /* host controller capabilities */ + mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | + MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -+ MMC_CAP_NEEDS_POLL | ++ MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | + (ALLOW_CMD23 * MMC_CAP_CMD23); + + spin_lock_init(&host->lock); + + if (host->allow_dma) { -+ if (!host->dma_chan_tx || !host->dma_chan_rx || -+ IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { -+ pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); ++ if (IS_ERR_OR_NULL(host->dma_chan_tx) || ++ IS_ERR_OR_NULL(host->dma_chan_rx)) { ++ pr_err("%s: unable to initialise DMA channels. " ++ "Falling back to PIO\n", ++ mmc_hostname(mmc)); + host->have_dma = false; + } else { -+ pr_info("DMA channels allocated for the SDHost driver"); + host->have_dma = true; + + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -78586,7 +79679,6 @@ index 0000000..eef8a24 + ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); + } + } else { -+ pr_info("Forcing PIO mode\n"); + host->have_dma = false; + } + @@ -78602,18 +79694,18 @@ index 0000000..eef8a24 + tasklet_init(&host->finish_tasklet, + bcm2835_sdhost_tasklet_finish, (unsigned long)host); + -+ setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); ++ setup_timer(&host->timer, bcm2835_sdhost_timeout, ++ (unsigned long)host); ++ ++ setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, ++ (unsigned long)host); + + bcm2835_sdhost_init(host, 0); -+#ifndef CONFIG_ARCH_BCM2835 -+ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -+ mmc_hostname(mmc), host); -+#else -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, ++ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, ++ bcm2835_sdhost_thread_irq, + IRQF_SHARED, mmc_hostname(mmc), host); -+#endif + if (ret) { -+ pr_err("%s: Failed to request IRQ %d: %d\n", ++ pr_err("%s: failed to request IRQ %d: %d\n", + mmc_hostname(mmc), host->irq, ret); + goto untasklet; + } @@ -78621,10 +79713,13 @@ index 0000000..eef8a24 + mmiowb(); + mmc_add_host(mmc); + -+ pr_info("Load BCM2835 SDHost driver\n"); -+ if (host->delay_after_stop) -+ pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", -+ host->delay_after_stop); ++ pio_limit_string[0] = '\0'; ++ if (host->have_dma && (host->pio_limit > 0)) ++ sprintf(pio_limit_string, " (>%d)", host->pio_limit); ++ pr_info("%s: %s loaded - DMA %s%s\n", ++ mmc_hostname(mmc), DRIVER_NAME, ++ host->have_dma ? "enabled" : "disabled", ++ pio_limit_string); + + return 0; + @@ -78652,7 +79747,8 @@ index 0000000..eef8a24 + mmc->ops = &bcm2835_sdhost_ops; + host = mmc_priv(mmc); + host->mmc = mmc; -+ host->timeout = msecs_to_jiffies(1000); ++ host->pio_timeout = msecs_to_jiffies(500); ++ host->max_delay = 1; /* Warn if over 1ms */ + spin_lock_init(&host->lock); + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -78678,8 +79774,12 @@ index 0000000..eef8a24 + of_property_read_u32(node, + "brcm,overclock-50", + &host->overclock_50); ++ of_property_read_u32(node, ++ "brcm,pio-limit", ++ &host->pio_limit); + host->allow_dma = ALLOW_DMA && + !of_property_read_bool(node, "brcm,force-pio"); ++ host->debug = of_property_read_bool(node, "brcm,debug"); + } + + if (host->allow_dma) { @@ -78791,10 +79891,10 @@ index 0000000..eef8a24 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Phil Elwell"); -From a48f15d3cdee3004a03d04e296247625130dcbf7 Mon Sep 17 00:00:00 2001 +From a18b06512f88e732fb152b3e0af5e75312600753 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 010/204] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 020/113] cma: Add vc_cma driver to enable use of CMA Signed-off-by: popcornmix @@ -78815,23 +79915,23 @@ vc_cma: Make the vc_cma area the default contiguous DMA area create mode 100644 include/linux/broadcom/vc_cma.h diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index a4af8221..59e4d63 100644 +index a043107..2ba2d82 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig -@@ -590,6 +590,8 @@ config DEVPORT +@@ -4,6 +4,8 @@ - source "drivers/s390/char/Kconfig" + menu "Character devices" +source "drivers/char/broadcom/Kconfig" + - config MSM_SMD_PKT - bool "Enable device interface for some SMD packet ports" - default n + source "drivers/tty/Kconfig" + + config DEVMEM diff --git a/drivers/char/Makefile b/drivers/char/Makefile -index d06cde26..a9f9daf 100644 +index d8a7579..9d8662e 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile -@@ -62,3 +62,4 @@ js-rtc-y = rtc.o +@@ -60,3 +60,4 @@ js-rtc-y = rtc.o obj-$(CONFIG_TILE_SROM) += tile-srom.o obj-$(CONFIG_XILLYBUS) += xillybus/ @@ -80119,10 +81219,10 @@ index 0000000..5325832 + +#endif /* VC_CMA_H */ -From ebd29c2fcd995ebe287b4d9e771bd1f6730e6e13 Mon Sep 17 00:00:00 2001 +From bf392eddd6a629189c74d00058aafbe3ec2c3a9e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 011/204] bcm2708: alsa sound driver +Subject: [PATCH 021/113] bcm2708: alsa sound driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -80179,10 +81279,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 sound/arm/vc_vchi_audioserv_defs.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6257407..df32241 100644 +index 4ea857c..7557854 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -429,6 +429,57 @@ struct platform_device bcm2835_emmc_device = { +@@ -418,6 +418,57 @@ struct platform_device bcm2835_emmc_device = { }; #endif /* CONFIG_MMC_BCM2835 */ @@ -80240,7 +81340,7 @@ index 6257407..df32241 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -571,6 +622,8 @@ void __init bcm2708_init(void) +@@ -559,6 +610,8 @@ void __init bcm2708_init(void) #endif bcm2708_init_led(); bcm2708_init_uart1(); @@ -80250,10 +81350,10 @@ index 6257407..df32241 100644 if (!use_dt) { for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 07750ed..62c95cb 100644 +index b762819..25c42b6 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -449,6 +449,57 @@ struct platform_device bcm2835_emmc_device = { +@@ -434,6 +434,57 @@ struct platform_device bcm2835_emmc_device = { }; #endif /* CONFIG_MMC_BCM2835 */ @@ -80311,7 +81411,7 @@ index 07750ed..62c95cb 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -591,6 +642,8 @@ void __init bcm2709_init(void) +@@ -576,6 +627,8 @@ void __init bcm2709_init(void) #endif bcm2709_init_led(); bcm2709_init_uart1(); @@ -82964,10 +84064,67 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From 4978dc22bb85d1c218085aa253224bdaea6f89fc Mon Sep 17 00:00:00 2001 +From 2d9dceb6822a27c0da5c7198df976ae9f0043f0b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 27 May 2015 17:22:15 +0100 +Subject: [PATCH 022/113] bcm2835-audio: Create the platform device if the DT + node is disabled + +For backwards compatibility, allow the built-in ALSA driver to be enabled +either by loading the module from /etc/modules or by enabling the "/audio" +node in DT. +--- + arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- + arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- + 2 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 7557854..296492a 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -610,8 +610,14 @@ void __init bcm2708_init(void) + #endif + bcm2708_init_led(); + bcm2708_init_uart1(); +- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) +- bcm_register_device_dt(&bcm2708_alsa_devices[i]); ++ ++ /* Only create the platform devices for the ALSA driver in the ++ absence of an enabled "audio" DT node */ ++ if (!use_dt || ++ !of_device_is_available(of_find_node_by_path("/audio"))) { ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device(&bcm2708_alsa_devices[i]); ++ } + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 25c42b6..46a274e 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -627,8 +627,14 @@ void __init bcm2709_init(void) + #endif + bcm2709_init_led(); + bcm2709_init_uart1(); +- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) +- bcm_register_device_dt(&bcm2708_alsa_devices[i]); ++ ++ /* Only create the platform devices for the ALSA driver in the ++ absence of an enabled "audio" DT node */ ++ if (!use_dt || ++ !of_device_is_available(of_find_node_by_path("/audio"))) { ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device(&bcm2708_alsa_devices[i]); ++ } + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + +From 82d330e12d1b94ca06a4d9ba837ec54a7fd56df1 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 012/204] bcm2708 vchiq driver +Subject: [PATCH 023/113] bcm2708 vchiq driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -83057,6 +84214,84 @@ Based on work by Lubomir Rintel. Signed-off-by: Noralf Trønnes vchiq: Change logging level for inbound data + +vchiq_arm: Two cacheing fixes + +1) Make fragment size vary with cache line size +Without this patch, non-cache-line-aligned transfers may corrupt +(or be corrupted by) adjacent data structures. + +Both ARM and VC need to be updated to enable this feature. This is +ensured by having the loader apply a new DT parameter - +cache-line-size. The existence of this parameter guarantees that the +kernel is capable, and the parameter will only be modified from the +safe default if the loader is capable. + +2) Flush/invalidate vmalloc'd memory, and invalidate after reads + +vchiq: fix NULL pointer dereference when closing driver + +The following code run as root will cause a null pointer dereference oops: + + int fd = open("/dev/vc-cma", O_RDONLY); + if (fd < 0) + err(1, "open failed"); + (void)close(fd); + +[ 1704.877721] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[ 1704.877725] pgd = b899c000 +[ 1704.877736] [00000000] *pgd=37fab831, *pte=00000000, *ppte=00000000 +[ 1704.877748] Internal error: Oops: 817 [#1] PREEMPT SMP ARM +[ 1704.877765] Modules linked in: evdev i2c_bcm2708 uio_pdrv_genirq uio +[ 1704.877774] CPU: 2 PID: 3656 Comm: stress-ng-fstat Not tainted 3.19.1-12-generic-bcm2709 #12-Ubuntu +[ 1704.877777] Hardware name: BCM2709 +[ 1704.877783] task: b8ab9b00 ti: b7e68000 task.ti: b7e68000 +[ 1704.877798] PC is at __down_interruptible+0x50/0xec +[ 1704.877806] LR is at down_interruptible+0x5c/0x68 +[ 1704.877813] pc : [<80630ee8>] lr : [<800704b0>] psr: 60080093 +sp : b7e69e50 ip : b7e69e88 fp : b7e69e84 +[ 1704.877817] r10: b88123c8 r9 : 00000010 r8 : 00000001 +[ 1704.877822] r7 : b8ab9b00 r6 : 7fffffff r5 : 80a1cc34 r4 : 80a1cc34 +[ 1704.877826] r3 : b7e69e50 r2 : 00000000 r1 : 00000000 r0 : 80a1cc34 +[ 1704.877833] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user +[ 1704.877838] Control: 10c5387d Table: 3899c06a DAC: 00000015 +[ 1704.877843] Process do-oops (pid: 3656, stack limit = 0xb7e68238) +[ 1704.877848] Stack: (0xb7e69e50 to 0xb7e6a000) +[ 1704.877856] 9e40: 80a1cc3c 00000000 00000010 b88123c8 +[ 1704.877865] 9e60: b7e69e84 80a1cc34 fff9fee9 ffffffff b7e68000 00000009 b7e69ea4 b7e69e88 +[ 1704.877874] 9e80: 800704b0 80630ea4 fff9fee9 60080013 80a1cc28 fff9fee9 b7e69edc b7e69ea8 +[ 1704.877884] 9ea0: 8040f558 80070460 fff9fee9 ffffffff 00000000 00000000 00000009 80a1cb7c +[ 1704.877893] 9ec0: 00000000 80a1cb7c 00000000 00000010 b7e69ef4 b7e69ee0 803e1ba4 8040f514 +[ 1704.877902] 9ee0: 00000e48 80a1cb7c b7e69f14 b7e69ef8 803e1c9c 803e1b74 b88123c0 b92acb18 +[ 1704.877911] 9f00: b8812790 b8d815d8 b7e69f24 b7e69f18 803e2250 803e1bc8 b7e69f5c b7e69f28 +[ 1704.877921] 9f20: 80167bac 803e222c 00000000 00000000 b7e69f54 b8ab9ffc 00000000 8098c794 +[ 1704.877930] 9f40: b8ab9b00 8000efc4 b7e68000 00000000 b7e69f6c b7e69f60 80167d6c 80167b28 +[ 1704.877939] 9f60: b7e69f8c b7e69f70 80047d38 80167d60 b7e68000 b7e68010 8000efc4 b7e69fb0 +[ 1704.877949] 9f80: b7e69fac b7e69f90 80012820 80047c84 01155490 011549a8 00000001 00000006 +[ 1704.877957] 9fa0: 00000000 b7e69fb0 8000ee5c 80012790 00000000 353d8c0f 7efc4308 00000000 +[ 1704.877966] 9fc0: 01155490 011549a8 00000001 00000006 00000000 00000000 76cf3ba0 00000003 +[ 1704.877975] 9fe0: 00000000 7efc42e4 0002272f 76e2ed66 60080030 00000003 00000000 00000000 +[ 1704.877998] [<80630ee8>] (__down_interruptible) from [<800704b0>] (down_interruptible+0x5c/0x68) +[ 1704.878015] [<800704b0>] (down_interruptible) from [<8040f558>] (vchiu_queue_push+0x50/0xd8) +[ 1704.878032] [<8040f558>] (vchiu_queue_push) from [<803e1ba4>] (send_worker_msg+0x3c/0x54) +[ 1704.878045] [<803e1ba4>] (send_worker_msg) from [<803e1c9c>] (vc_cma_set_reserve+0xe0/0x1c4) +[ 1704.878057] [<803e1c9c>] (vc_cma_set_reserve) from [<803e2250>] (vc_cma_release+0x30/0x38) +[ 1704.878069] [<803e2250>] (vc_cma_release) from [<80167bac>] (__fput+0x90/0x1e0) +[ 1704.878082] [<80167bac>] (__fput) from [<80167d6c>] (____fput+0x18/0x1c) +[ 1704.878094] [<80167d6c>] (____fput) from [<80047d38>] (task_work_run+0xc0/0xf8) +[ 1704.878109] [<80047d38>] (task_work_run) from [<80012820>] (do_work_pending+0x9c/0xc4) +[ 1704.878123] [<80012820>] (do_work_pending) from [<8000ee5c>] (work_pending+0xc/0x20) +[ 1704.878133] Code: e50b1034 e3a01000 e50b2030 e580300c (e5823000) + +..the fix is to ensure that we have actually initialized the queue before we attempt +to push any items onto it. This occurs if we do an open() followed by a close() without +any activity in between. + +Signed-off-by: Colin Ian King + +vchiq_arm: Sort out the vmalloc case + +See: https://github.com/raspberrypi/linux/issues/1055 --- arch/arm/mach-bcm2708/bcm2708.c | 26 + arch/arm/mach-bcm2708/include/mach/platform.h | 2 + @@ -83075,8 +84310,8 @@ vchiq: Change logging level for inbound data .../misc/vc04_services/interface/vchi/vchi_mh.h | 42 + .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 40 + .../vc04_services/interface/vchiq_arm/vchiq_2835.h | 42 + - .../interface/vchiq_arm/vchiq_2835_arm.c | 547 +++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2886 ++++++++++++++ + .../interface/vchiq_arm/vchiq_2835_arm.c | 580 +++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2903 +++++++++++++++ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 220 ++ .../interface/vchiq_arm/vchiq_build_info.h | 37 + .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 69 + @@ -83094,10 +84329,10 @@ vchiq: Change logging level for inbound data .../interface/vchiq_arm/vchiq_memdrv.h | 71 + .../interface/vchiq_arm/vchiq_pagelist.h | 58 + .../vc04_services/interface/vchiq_arm/vchiq_shim.c | 860 +++++ - .../vc04_services/interface/vchiq_arm/vchiq_util.c | 152 + - .../vc04_services/interface/vchiq_arm/vchiq_util.h | 81 + + .../vc04_services/interface/vchiq_arm/vchiq_util.c | 156 + + .../vc04_services/interface/vchiq_arm/vchiq_util.h | 82 + .../interface/vchiq_arm/vchiq_version.c | 59 + - 39 files changed, 12810 insertions(+) + 39 files changed, 12865 insertions(+) create mode 100644 drivers/misc/vc04_services/Kconfig create mode 100644 drivers/misc/vc04_services/Makefile create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h @@ -83133,11 +84368,11 @@ vchiq: Change logging level for inbound data create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index df32241..ecf0524 100644 +index 296492a..541ee37 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -376,6 +376,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -365,6 +365,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +static struct resource bcm2708_vchiq_resources[] = { @@ -83168,16 +84403,16 @@ index df32241..ecf0524 100644 #ifdef CONFIG_BCM2708_GPIO #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" -@@ -611,6 +636,7 @@ void __init bcm2708_init(void) +@@ -599,6 +624,7 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h -index 2e7e1bb..69674e9 100644 +index a132502..0c57a57 100644 --- a/arch/arm/mach-bcm2708/include/mach/platform.h +++ b/arch/arm/mach-bcm2708/include/mach/platform.h @@ -81,6 +81,8 @@ @@ -83190,11 +84425,11 @@ index 2e7e1bb..69674e9 100644 /* diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 62c95cb..de9feaa 100644 +index 46a274e..0a7bd3e 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -396,6 +396,31 @@ static struct platform_device bcm2708_vcio_device = { - }, +@@ -381,6 +381,31 @@ static struct platform_device bcm2708_rpifw_device = { + }, }; +static struct resource bcm2708_vchiq_resources[] = { @@ -83225,10 +84460,10 @@ index 62c95cb..de9feaa 100644 #ifdef CONFIG_BCM2708_GPIO #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" -@@ -631,6 +656,7 @@ void __init bcm2709_init(void) +@@ -616,6 +641,7 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_rpifw_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); @@ -83247,10 +84482,10 @@ index 7157f38..be99733 100644 /* diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 006242c..4e6f46c3 100644 +index ccccc29..098131f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig -@@ -524,6 +524,7 @@ source "drivers/misc/carma/Kconfig" +@@ -533,6 +533,7 @@ source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/mei/Kconfig" source "drivers/misc/vmw_vmci/Kconfig" @@ -83259,7 +84494,7 @@ index 006242c..4e6f46c3 100644 source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 7d5c4cd..43d2ac9 100644 +index 537d7f3..ac24d77 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_INTEL_MEI) += mei/ @@ -83272,13 +84507,13 @@ index 7d5c4cd..43d2ac9 100644 obj-$(CONFIG_ECHO) += echo/ diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig new file mode 100644 -index 0000000..c5ba283 +index 0000000..db8e1be --- /dev/null +++ b/drivers/misc/vc04_services/Kconfig @@ -0,0 +1,9 @@ +config BCM2708_VCHIQ + tristate "Videocore VCHIQ" -+ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX ++ depends on RASPBERRYPI_FIRMWARE + default y + help + Kernel to VideoCore communication interface for the @@ -84865,10 +86100,10 @@ index 0000000..7ea5c64 +#endif /* VCHIQ_2835_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c new file mode 100644 -index 0000000..c739083 +index 0000000..c9febcc --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -0,0 +1,547 @@ +@@ -0,0 +1,580 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -84910,10 +86145,11 @@ index 0000000..c739083 +#include +#include +#include -+#include +#include +#include ++#include +#include ++#include + +#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + @@ -84935,8 +86171,10 @@ index 0000000..c739083 +} VCHIQ_2835_ARM_STATE_T; + +static void __iomem *g_regs; -+static FRAGMENTS_T *g_fragments_base; -+static FRAGMENTS_T *g_free_fragments; ++static unsigned int g_cache_line_size = sizeof(CACHE_LINE_SIZE); ++static unsigned int g_fragments_size; ++static char *g_fragments_base; ++static char *g_free_fragments; +static struct semaphore g_free_fragments_sema; +static unsigned long g_virt_to_bus_offset; + @@ -84957,18 +86195,24 @@ index 0000000..c739083 +int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) +{ + struct device *dev = &pdev->dev; ++ struct rpi_firmware *fw = platform_get_drvdata(pdev); + VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; + struct resource *res; + void *slot_mem; + dma_addr_t slot_phys; ++ u32 channelbase; + int slot_mem_size, frag_mem_size; + int err, irq, i; + + g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); + ++ (void)of_property_read_u32(dev->of_node, "cache-line-size", ++ &g_cache_line_size); ++ g_fragments_size = 2 * g_cache_line_size; ++ + /* Allocate space for the channels in coherent memory */ + slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); -+ frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); ++ frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); + + slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, + &slot_phys, GFP_KERNEL); @@ -84988,15 +86232,15 @@ index 0000000..c739083 + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = + MAX_FRAGMENTS; + -+ g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); ++ g_fragments_base = (char *)slot_mem + slot_mem_size; + slot_mem_size += frag_mem_size; + + g_free_fragments = g_fragments_base; + for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { -+ *(FRAGMENTS_T **)&g_fragments_base[i] = -+ &g_fragments_base[i + 1]; ++ *(char **)&g_fragments_base[i*g_fragments_size] = ++ &g_fragments_base[(i + 1)*g_fragments_size]; + } -+ *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; ++ *(char **)&g_fragments_base[i * g_fragments_size] = NULL; + sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); + + if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) @@ -85021,13 +86265,12 @@ index 0000000..c739083 + } + + /* Send the base address of the slots to VideoCore */ -+ -+ dsb(); /* Ensure all writes have completed */ -+ -+ err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); -+ if (err) { -+ dev_err(dev, "mailbox write failed\n"); -+ return err; ++ channelbase = slot_phys; ++ err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, ++ &channelbase, sizeof(channelbase)); ++ if (err || channelbase) { ++ dev_err(dev, "failed to set channelbase\n"); ++ return err ? : -ENXIO; + } + + vchiq_log_info(vchiq_arm_log_level, @@ -85215,7 +86458,7 @@ index 0000000..c739083 +** cached area. + +** N.B. This implementation plays slightly fast and loose with the Linux -+** driver programming rules, e.g. its use of __virt_to_bus instead of ++** driver programming rules, e.g. its use of dmac_map_area instead of +** dma_map_single, but it isn't a multi-platform driver and it benefits +** from increased speed as a result. +*/ @@ -85226,7 +86469,6 @@ index 0000000..c739083 +{ + PAGELIST_T *pagelist; + struct page **pages; -+ struct page *page; + unsigned long *addrs; + unsigned int num_pages, offset, i; + char *addr, *base_addr, *next_addr; @@ -85257,10 +86499,25 @@ index 0000000..c739083 + pages = (struct page **)(addrs + num_pages + 1); + + if (is_vmalloc_addr(buf)) { -+ for (actual_pages = 0; actual_pages < num_pages; actual_pages++) { -+ pages[actual_pages] = vmalloc_to_page(buf + (actual_pages * PAGE_SIZE)); ++ int dir = (type == PAGELIST_WRITE) ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE; ++ unsigned long length = count; ++ unsigned int off = offset; ++ ++ for (actual_pages = 0; actual_pages < num_pages; ++ actual_pages++) { ++ struct page *pg = vmalloc_to_page(buf + (actual_pages * ++ PAGE_SIZE)); ++ size_t bytes = PAGE_SIZE - off; ++ ++ if (bytes > length) ++ bytes = length; ++ pages[actual_pages] = pg; ++ dmac_map_area(page_address(pg) + off, bytes, dir); ++ length -= bytes; ++ off = 0; + } -+ *need_release = 0; /* do not try and release vmalloc pages */ ++ *need_release = 0; /* do not try and release vmalloc pages */ + } else { + down_read(&task->mm->mmap_sem); + actual_pages = get_user_pages(task, task->mm, @@ -85289,7 +86546,7 @@ index 0000000..c739083 + actual_pages = -ENOMEM; + return actual_pages; + } -+ *need_release = 1; /* release user pages */ ++ *need_release = 1; /* release user pages */ + } + + pagelist->length = count; @@ -85322,10 +86579,10 @@ index 0000000..c739083 + + /* Partial cache lines (fragments) require special measures */ + if ((type == PAGELIST_READ) && -+ ((pagelist->offset & (CACHE_LINE_SIZE - 1)) || ++ ((pagelist->offset & (g_cache_line_size - 1)) || + ((pagelist->offset + pagelist->length) & -+ (CACHE_LINE_SIZE - 1)))) { -+ FRAGMENTS_T *fragments; ++ (g_cache_line_size - 1)))) { ++ char *fragments; + + if (down_interruptible(&g_free_fragments_sema) != 0) { + kfree(pagelist); @@ -85335,19 +86592,15 @@ index 0000000..c739083 + WARN_ON(g_free_fragments == NULL); + + down(&g_free_fragments_mutex); -+ fragments = (FRAGMENTS_T *) g_free_fragments; ++ fragments = g_free_fragments; + WARN_ON(fragments == NULL); -+ g_free_fragments = *(FRAGMENTS_T **) g_free_fragments; ++ g_free_fragments = *(char **) g_free_fragments; + up(&g_free_fragments_mutex); -+ pagelist->type = -+ PAGELIST_READ_WITH_FRAGMENTS + (fragments - -+ g_fragments_base); ++ pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + ++ (fragments - g_fragments_base) / g_fragments_size; + } + -+ for (page = virt_to_page(pagelist); -+ page <= virt_to_page(addrs + num_pages - 1); page++) { -+ flush_dcache_page(page); -+ } ++ dmac_flush_range(pagelist, addrs + num_pages); + + *ppagelist = pagelist; + @@ -85373,13 +86626,14 @@ index 0000000..c739083 + + /* Deal with any partial cache lines (fragments) */ + if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { -+ FRAGMENTS_T *fragments = g_fragments_base + -+ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS); ++ char *fragments = g_fragments_base + ++ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * ++ g_fragments_size; + int head_bytes, tail_bytes; -+ head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & -+ (CACHE_LINE_SIZE - 1); ++ head_bytes = (g_cache_line_size - pagelist->offset) & ++ (g_cache_line_size - 1); + tail_bytes = (pagelist->offset + actual) & -+ (CACHE_LINE_SIZE - 1); ++ (g_cache_line_size - 1); + + if ((actual >= 0) && (head_bytes != 0)) { + if (head_bytes > actual) @@ -85387,41 +86641,55 @@ index 0000000..c739083 + + memcpy((char *)page_address(pages[0]) + + pagelist->offset, -+ fragments->headbuf, ++ fragments, + head_bytes); + } + if ((actual >= 0) && (head_bytes < actual) && + (tail_bytes != 0)) { + memcpy((char *)page_address(pages[num_pages - 1]) + + ((pagelist->offset + actual) & -+ (PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)), -+ fragments->tailbuf, tail_bytes); ++ (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), ++ fragments + g_cache_line_size, ++ tail_bytes); + } + + down(&g_free_fragments_mutex); -+ *(FRAGMENTS_T **) fragments = g_free_fragments; ++ *(char **)fragments = g_free_fragments; + g_free_fragments = fragments; + up(&g_free_fragments_mutex); + up(&g_free_fragments_sema); + } + -+ if (*need_release) { -+ for (i = 0; i < num_pages; i++) { -+ if (pagelist->type != PAGELIST_WRITE) -+ set_page_dirty(pages[i]); ++ if (*need_release) { ++ unsigned int length = pagelist->length; ++ unsigned int offset = pagelist->offset; + -+ page_cache_release(pages[i]); ++ for (i = 0; i < num_pages; i++) { ++ struct page *pg = pages[i]; ++ ++ if (pagelist->type != PAGELIST_WRITE) { ++ unsigned int bytes = PAGE_SIZE - offset; ++ ++ if (bytes > length) ++ bytes = length; ++ dmac_unmap_area(page_address(pg) + offset, ++ bytes, DMA_FROM_DEVICE); ++ length -= bytes; ++ offset = 0; ++ set_page_dirty(pg); ++ } ++ page_cache_release(pg); + } -+ } ++ } + + kfree(pagelist); +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c new file mode 100644 -index 0000000..31e2cba +index 0000000..e11c0e0 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -0,0 +1,2886 @@ +@@ -0,0 +1,2903 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -85469,7 +86737,9 @@ index 0000000..31e2cba +#include +#include +#include ++#include +#include ++#include + +#include "vchiq_core.h" +#include "vchiq_ioctl.h" @@ -88217,9 +89487,24 @@ index 0000000..31e2cba + +static int vchiq_probe(struct platform_device *pdev) +{ ++ struct device_node *fw_node; ++ struct rpi_firmware *fw; + int err; + void *ptr_err; + ++ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++/* Remove comment when booting without Device Tree is no longer supported ++ if (!fw_node) { ++ dev_err(&pdev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++*/ ++ fw = rpi_firmware_get(fw_node); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ platform_set_drvdata(pdev, fw); ++ + /* create debugfs entries */ + err = vchiq_debugfs_init(); + if (err != 0) @@ -95912,10 +97197,10 @@ index 0000000..8072ff6 +EXPORT_SYMBOL(vchi_service_release); diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c new file mode 100644 -index 0000000..05e7979 +index 0000000..384acb8 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -@@ -0,0 +1,152 @@ +@@ -0,0 +1,156 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -95964,6 +97249,7 @@ index 0000000..05e7979 + queue->size = size; + queue->read = 0; + queue->write = 0; ++ queue->initialized = 1; + + sema_init(&queue->pop, 0); + sema_init(&queue->push, 0); @@ -95994,6 +97280,9 @@ index 0000000..05e7979 + +void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) +{ ++ if (!queue->initialized) ++ return; ++ + while (queue->write == queue->read + queue->size) { + if (down_interruptible(&queue->pop) != 0) { + flush_signals(current); @@ -96070,10 +97359,10 @@ index 0000000..05e7979 +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h new file mode 100644 -index 0000000..f4d0b66 +index 0000000..4055d4b --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -@@ -0,0 +1,81 @@ +@@ -0,0 +1,82 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -96136,6 +97425,7 @@ index 0000000..f4d0b66 + int size; + int read; + int write; ++ int initialized; + + struct semaphore pop; + struct semaphore push; @@ -96221,10 +97511,10 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From 5c91907c6aec2d89bf1d57ab85e01bfdab1f0801 Mon Sep 17 00:00:00 2001 +From 05522a38c9e37b1a6e4ce6efa64ba88c7fd31008 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 16:07:06 +0100 -Subject: [PATCH 013/204] vc_mem: Add vc_mem driver +Subject: [PATCH 024/113] vc_mem: Add vc_mem driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -96241,9 +97531,9 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2709/vc_mem.c | 431 ---------------------------- drivers/char/broadcom/Kconfig | 12 +- drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/vc_mem.c | 423 +++++++++++++++++++++++++++ + drivers/char/broadcom/vc_mem.c | 422 +++++++++++++++++++++++++++ include/linux/broadcom/vc_mem.h | 35 +++ - 6 files changed, 470 insertions(+), 467 deletions(-) + 6 files changed, 469 insertions(+), 467 deletions(-) delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c create mode 100644 drivers/char/broadcom/vc_mem.c @@ -96761,10 +98051,10 @@ index 13c5bca..fce918c 100644 +obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c new file mode 100644 -index 0000000..fcde6b1 +index 0000000..be64f23 --- /dev/null +++ b/drivers/char/broadcom/vc_mem.c -@@ -0,0 +1,423 @@ +@@ -0,0 +1,422 @@ +/***************************************************************************** +* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. +* @@ -96789,7 +98079,6 @@ index 0000000..fcde6b1 +#include +#include +#include -+#include +#include + +#define DRIVER_NAME "vc-mem" @@ -97230,10 +98519,10 @@ index 0000000..20a4753 + +#endif /* _VC_MEM_H */ -From 40c1f77329886c79e9ac40afe3dee52dec5a0f5f Mon Sep 17 00:00:00 2001 +From 4a45cf27c95ae5d03dd11ed522722bf69f2ed87e Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 014/204] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 025/113] vcsm: VideoCore shared memory service for BCM2835 Add experimental support for the VideoCore shared memory service. This allows user processes to allocate memory from VideoCore's @@ -98427,7 +99716,7 @@ index 0000000..7c6ba1a +} diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c new file mode 100644 -index 0000000..0bfb42e +index 0000000..b62a3b2 --- /dev/null +++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c @@ -0,0 +1,3211 @@ @@ -99801,8 +101090,8 @@ index 0000000..0bfb42e + return 0; + +error: -+ vmcs_sm_release_resource(resource, 0); + resource->res_stats[MAP_FAIL]++; ++ vmcs_sm_release_resource(resource, 0); + return ret; +} + @@ -101643,10 +102932,2646 @@ index 0000000..0bfb42e +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); -From 89476e1e5132eb053f40bcad4d31903c2660d737 Mon Sep 17 00:00:00 2001 +From 5269a44142c6e5c26d06f9b7833a8e95e3ba1fc9 Mon Sep 17 00:00:00 2001 +From: Luke Wren +Date: Fri, 21 Aug 2015 23:14:48 +0100 +Subject: [PATCH 026/113] Add /dev/gpiomem device for rootless user GPIO access + +Signed-off-by: Luke Wren +--- + drivers/char/broadcom/Kconfig | 9 ++ + drivers/char/broadcom/Makefile | 3 + + drivers/char/broadcom/bcm2835-gpiomem.c | 265 ++++++++++++++++++++++++++++++++ + 3 files changed, 277 insertions(+) + create mode 100644 drivers/char/broadcom/bcm2835-gpiomem.c + +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index 75fa1cb..b75c9b2 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -32,3 +32,12 @@ config BCM_VC_SM + help + Support for the VC shared memory on the Broadcom reference + design. Uses the VCHIQ stack. ++ ++config BCM2835_DEVGPIOMEM ++ tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835" ++ default m ++ help ++ Provides users with root-free access to the GPIO registers ++ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO ++ register page to the user's pointer. ++ +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index de8feb9..1eb06e9 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -1,3 +1,6 @@ + obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ + obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o + obj-$(CONFIG_BCM_VC_SM) += vc_sm/ ++ ++obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o ++ +diff --git a/drivers/char/broadcom/bcm2835-gpiomem.c b/drivers/char/broadcom/bcm2835-gpiomem.c +new file mode 100644 +index 0000000..0085e13 +--- /dev/null ++++ b/drivers/char/broadcom/bcm2835-gpiomem.c +@@ -0,0 +1,265 @@ ++/** ++ * GPIO memory device driver ++ * ++ * Creates a chardev /dev/gpiomem which will provide user access to ++ * the BCM2835's GPIO registers when it is mmap()'d. ++ * No longer need root for user GPIO access, but without relaxing permissions ++ * on /dev/mem. ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DEVICE_NAME "bcm2835-gpiomem" ++#define DRIVER_NAME "gpiomem-bcm2835" ++#define DEVICE_MINOR 0 ++ ++struct bcm2835_gpiomem_instance { ++ unsigned long gpio_regs_phys; ++ struct device *dev; ++}; ++ ++static struct cdev bcm2835_gpiomem_cdev; ++static dev_t bcm2835_gpiomem_devid; ++static struct class *bcm2835_gpiomem_class; ++static struct device *bcm2835_gpiomem_dev; ++static struct bcm2835_gpiomem_instance *inst; ++ ++ ++/**************************************************************************** ++* ++* GPIO mem chardev file ops ++* ++***************************************************************************/ ++ ++static int bcm2835_gpiomem_open(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ int ret = 0; ++ ++ dev_info(inst->dev, "gpiomem device opened."); ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, "Unknown minor device: %d", dev); ++ ret = -ENXIO; ++ } ++ return ret; ++} ++ ++static int bcm2835_gpiomem_release(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ int ret = 0; ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, "Unknown minor device %d", dev); ++ ret = -ENXIO; ++ } ++ return ret; ++} ++ ++static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = { ++#ifdef CONFIG_HAVE_IOREMAP_PROT ++ .access = generic_access_phys ++#endif ++}; ++ ++static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ /* Ignore what the user says - they're getting the GPIO regs ++ whether they like it or not! */ ++ unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT; ++ ++ vma->vm_page_prot = phys_mem_access_prot(file, gpio_page, ++ PAGE_SIZE, ++ vma->vm_page_prot); ++ vma->vm_ops = &bcm2835_gpiomem_vm_ops; ++ if (remap_pfn_range(vma, vma->vm_start, ++ gpio_page, ++ PAGE_SIZE, ++ vma->vm_page_prot)) { ++ return -EAGAIN; ++ } ++ return 0; ++} ++ ++static const struct file_operations ++bcm2835_gpiomem_fops = { ++ .owner = THIS_MODULE, ++ .open = bcm2835_gpiomem_open, ++ .release = bcm2835_gpiomem_release, ++ .mmap = bcm2835_gpiomem_mmap, ++}; ++ ++ ++ /**************************************************************************** ++* ++* Probe and remove functions ++* ++***************************************************************************/ ++ ++ ++static int bcm2835_gpiomem_probe(struct platform_device *pdev) ++{ ++ int err; ++ void *ptr_err; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct resource *ioresource; ++ ++ /* Allocate buffers and instance data */ ++ ++ inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL); ++ ++ if (!inst) { ++ err = -ENOMEM; ++ goto failed_inst_alloc; ++ } ++ ++ inst->dev = dev; ++ ++ /* Create character device entries */ ++ ++ err = alloc_chrdev_region(&bcm2835_gpiomem_devid, ++ DEVICE_MINOR, 1, DEVICE_NAME); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to allocate device number"); ++ goto failed_alloc_chrdev; ++ } ++ cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops); ++ bcm2835_gpiomem_cdev.owner = THIS_MODULE; ++ err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to register device"); ++ goto failed_cdev_add; ++ } ++ ++ /* Create sysfs entries */ ++ ++ bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME); ++ ptr_err = bcm2835_gpiomem_class; ++ if (IS_ERR(ptr_err)) ++ goto failed_class_create; ++ ++ bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL, ++ bcm2835_gpiomem_devid, NULL, ++ "gpiomem"); ++ ptr_err = bcm2835_gpiomem_dev; ++ if (IS_ERR(ptr_err)) ++ goto failed_device_create; ++ ++ /* Get address from device tree if available (*_resource() correctly ++ converts the bus address in device tree to a physical address), ++ or use hardcoded offset + BCM2708_PERI_BASE if not. ++ (In spite of its name 2708 actually seems to have the correct ++ mach-dependent value on 2709 etc, as it is defined in ++ mach-bcm270x/platform.h) */ ++ ++ if (node) { ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ inst->gpio_regs_phys = ioresource->start; ++ } else { ++ inst->gpio_regs_phys = GPIO_BASE; ++ } ++ ++ dev_info(inst->dev, "Initialised: Registers at 0x%08lx", ++ inst->gpio_regs_phys); ++ ++ return 0; ++ ++failed_device_create: ++ class_destroy(bcm2835_gpiomem_class); ++failed_class_create: ++ cdev_del(&bcm2835_gpiomem_cdev); ++ err = PTR_ERR(ptr_err); ++failed_cdev_add: ++ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); ++failed_alloc_chrdev: ++ kfree(inst); ++failed_inst_alloc: ++ dev_err(inst->dev, "could not load bcm2835_gpiomem"); ++ return err; ++} ++ ++static int bcm2835_gpiomem_remove(struct platform_device *pdev) ++{ ++ struct device *dev = inst->dev; ++ ++ kfree(inst); ++ device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid); ++ class_destroy(bcm2835_gpiomem_class); ++ cdev_del(&bcm2835_gpiomem_cdev); ++ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); ++ ++ dev_info(dev, "GPIO mem driver removed - OK"); ++ return 0; ++} ++ ++ /**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_gpiomem_of_match[] = { ++ {.compatible = "brcm,bcm2835-gpiomem",}, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match); ++ ++static struct platform_driver bcm2835_gpiomem_driver = { ++ .probe = bcm2835_gpiomem_probe, ++ .remove = bcm2835_gpiomem_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_gpiomem_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_gpiomem_driver); ++ ++MODULE_ALIAS("platform:gpiomem-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); ++MODULE_AUTHOR("Luke Wren "); + +From 33a380065a1ec643623f11adfc9e35cf68e5be0c Mon Sep 17 00:00:00 2001 +From: Luke Wren +Date: Sat, 5 Sep 2015 01:14:45 +0100 +Subject: [PATCH 027/113] Add SMI driver + +Signed-off-by: Luke Wren +--- + .../bindings/misc/brcm,bcm2835-smi-dev.txt | 17 + + .../devicetree/bindings/misc/brcm,bcm2835-smi.txt | 48 + + drivers/char/broadcom/Kconfig | 8 + + drivers/char/broadcom/Makefile | 2 +- + drivers/char/broadcom/bcm2835_smi_dev.c | 402 +++++++++ + drivers/misc/Kconfig | 8 + + drivers/misc/Makefile | 1 + + drivers/misc/bcm2835_smi.c | 985 +++++++++++++++++++++ + include/linux/broadcom/bcm2835_smi.h | 391 ++++++++ + 9 files changed, 1861 insertions(+), 1 deletion(-) + create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt + create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt + create mode 100644 drivers/char/broadcom/bcm2835_smi_dev.c + create mode 100644 drivers/misc/bcm2835_smi.c + create mode 100644 include/linux/broadcom/bcm2835_smi.h + +diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt +new file mode 100644 +index 0000000..68cc8eb +--- /dev/null ++++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt +@@ -0,0 +1,17 @@ ++* Broadcom BCM2835 SMI character device driver. ++ ++SMI or secondary memory interface is a peripheral specific to certain Broadcom ++SOCs, and is helpful for talking to things like parallel-interface displays ++and NAND flashes (in fact, most things with a parallel register interface). ++ ++This driver adds a character device which provides a user-space interface to ++an instance of the SMI driver. ++ ++Required properties: ++- compatible: "brcm,bcm2835-smi-dev" ++- smi_handle: a phandle to the smi node. ++ ++Optional properties: ++- None. ++ ++ +diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt +new file mode 100644 +index 0000000..b76dc69 +--- /dev/null ++++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt +@@ -0,0 +1,48 @@ ++* Broadcom BCM2835 SMI driver. ++ ++SMI or secondary memory interface is a peripheral specific to certain Broadcom ++SOCs, and is helpful for talking to things like parallel-interface displays ++and NAND flashes (in fact, most things with a parallel register interface). ++ ++Required properties: ++- compatible: "brcm,bcm2835-smi" ++- reg: Should contain location and length of SMI registers and SMI clkman regs ++- interrupts: *the* SMI interrupt. ++- pinctrl-names: should be "default". ++- pinctrl-0: the phandle of the gpio pin node. ++- brcm,smi-clock-source: the clock source for clkman ++- brcm,smi-clock-divisor: the integer clock divisor for clkman ++- dmas: the dma controller phandle and the DREQ number (4 on a 2835) ++- dma-names: the name used by the driver to request its channel. ++ Should be "rx-tx". ++ ++Optional properties: ++- None. ++ ++Examples: ++ ++8 data pin configuration: ++ ++smi: smi@7e600000 { ++ compatible = "brcm,bcm2835-smi"; ++ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; ++ interrupts = <2 16>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&smi_pins>; ++ brcm,smi-clock-source = <6>; ++ brcm,smi-clock-divisor = <4>; ++ dmas = <&dma 4>; ++ dma-names = "rx-tx"; ++ ++ status = "okay"; ++}; ++ ++smi_pins: smi_pins { ++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15>; ++ /* Alt 1: SMI */ ++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>; ++ /* /CS, /WE and /OE are pulled high, as they are ++ generally active low signals */ ++ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0>; ++}; ++ +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index b75c9b2..2292ed2 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -41,3 +41,11 @@ config BCM2835_DEVGPIOMEM + on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO + register page to the user's pointer. + ++config BCM2835_SMI_DEV ++ tristate "Character device driver for BCM2835 Secondary Memory Interface" ++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI ++ default m ++ help ++ This driver provides a character device interface (ioctl + read/write) to ++ Broadcom's Secondary Memory interface. The low-level functionality is provided ++ by the SMI driver itself. +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index 1eb06e9..667d33e 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -3,4 +3,4 @@ obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o + obj-$(CONFIG_BCM_VC_SM) += vc_sm/ + + obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o +- ++obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o +diff --git a/drivers/char/broadcom/bcm2835_smi_dev.c b/drivers/char/broadcom/bcm2835_smi_dev.c +new file mode 100644 +index 0000000..d6efd92 +--- /dev/null ++++ b/drivers/char/broadcom/bcm2835_smi_dev.c +@@ -0,0 +1,402 @@ ++/** ++ * Character device driver for Broadcom Secondary Memory Interface ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DEVICE_NAME "bcm2835-smi-dev" ++#define DRIVER_NAME "smi-dev-bcm2835" ++#define DEVICE_MINOR 0 ++ ++static struct cdev bcm2835_smi_cdev; ++static dev_t bcm2835_smi_devid; ++static struct class *bcm2835_smi_class; ++static struct device *bcm2835_smi_dev; ++ ++struct bcm2835_smi_dev_instance { ++ struct device *dev; ++}; ++ ++static struct bcm2835_smi_instance *smi_inst; ++static struct bcm2835_smi_dev_instance *inst; ++ ++static const char *const ioctl_names[] = { ++ "READ_SETTINGS", ++ "WRITE_SETTINGS", ++ "ADDRESS" ++}; ++ ++/**************************************************************************** ++* ++* SMI chardev file ops ++* ++***************************************************************************/ ++static long ++bcm2835_smi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret = 0; ++ ++ dev_info(inst->dev, "serving ioctl..."); ++ ++ switch (cmd) { ++ case BCM2835_SMI_IOC_GET_SETTINGS:{ ++ struct smi_settings *settings; ++ ++ dev_info(inst->dev, "Reading SMI settings to user."); ++ settings = bcm2835_smi_get_settings_from_regs(smi_inst); ++ if (copy_to_user((void *)arg, settings, ++ sizeof(struct smi_settings))) ++ dev_err(inst->dev, "settings copy failed."); ++ break; ++ } ++ case BCM2835_SMI_IOC_WRITE_SETTINGS:{ ++ struct smi_settings *settings; ++ ++ dev_info(inst->dev, "Setting user's SMI settings."); ++ settings = bcm2835_smi_get_settings_from_regs(smi_inst); ++ if (copy_from_user(settings, (void *)arg, ++ sizeof(struct smi_settings))) ++ dev_err(inst->dev, "settings copy failed."); ++ else ++ bcm2835_smi_set_regs_from_settings(smi_inst); ++ break; ++ } ++ case BCM2835_SMI_IOC_ADDRESS: ++ dev_info(inst->dev, "SMI address set: 0x%02x", (int)arg); ++ bcm2835_smi_set_address(smi_inst, arg); ++ break; ++ default: ++ dev_err(inst->dev, "invalid ioctl cmd: %d", cmd); ++ ret = -ENOTTY; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int bcm2835_smi_open(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ ++ dev_dbg(inst->dev, "SMI device opened."); ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, ++ "bcm2835_smi_release: Unknown minor device: %d", ++ dev); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++static int bcm2835_smi_release(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ ++ if (dev != DEVICE_MINOR) { ++ dev_err(inst->dev, ++ "bcm2835_smi_release: Unknown minor device %d", dev); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++static ssize_t dma_bounce_user( ++ enum dma_transfer_direction dma_dir, ++ char __user *user_ptr, ++ size_t count, ++ struct bcm2835_smi_bounce_info *bounce) ++{ ++ int chunk_size; ++ int chunk_no = 0; ++ int count_left = count; ++ ++ while (count_left) { ++ int rv; ++ void *buf; ++ ++ /* Wait for current chunk to complete: */ ++ if (down_timeout(&bounce->callback_sem, ++ msecs_to_jiffies(1000))) { ++ dev_err(inst->dev, "DMA bounce timed out"); ++ count -= (count_left); ++ break; ++ } ++ ++ if (bounce->callback_sem.count >= DMA_BOUNCE_BUFFER_COUNT - 1) ++ dev_err(inst->dev, "WARNING: Ring buffer overflow"); ++ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? ++ DMA_BOUNCE_BUFFER_SIZE : count_left; ++ buf = bounce->buffer[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; ++ if (dma_dir == DMA_DEV_TO_MEM) ++ rv = copy_to_user(user_ptr, buf, chunk_size); ++ else ++ rv = copy_from_user(buf, user_ptr, chunk_size); ++ if (rv) ++ dev_err(inst->dev, "copy_*_user() failed!: %d", rv); ++ user_ptr += chunk_size; ++ count_left -= chunk_size; ++ chunk_no++; ++ } ++ return count; ++} ++ ++static ssize_t ++bcm2835_read_file(struct file *f, char __user *user_ptr, ++ size_t count, loff_t *offs) ++{ ++ int odd_bytes; ++ ++ dev_dbg(inst->dev, "User reading %d bytes from SMI.", count); ++ /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */ ++ if (count > DMA_THRESHOLD_BYTES) ++ odd_bytes = count & 0x3; ++ else ++ odd_bytes = count; ++ count -= odd_bytes; ++ if (count) { ++ struct bcm2835_smi_bounce_info *bounce; ++ ++ count = bcm2835_smi_user_dma(smi_inst, ++ DMA_DEV_TO_MEM, user_ptr, count, ++ &bounce); ++ if (count) ++ count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr, ++ count, bounce); ++ } ++ if (odd_bytes) { ++ /* Read from FIFO directly if not using DMA */ ++ uint8_t buf[DMA_THRESHOLD_BYTES]; ++ ++ bcm2835_smi_read_buf(smi_inst, buf, odd_bytes); ++ if (copy_to_user(user_ptr, buf, odd_bytes)) ++ dev_err(inst->dev, "copy_to_user() failed."); ++ count += odd_bytes; ++ ++ } ++ return count; ++} ++ ++static ssize_t ++bcm2835_write_file(struct file *f, const char __user *user_ptr, ++ size_t count, loff_t *offs) ++{ ++ int odd_bytes; ++ ++ dev_dbg(inst->dev, "User writing %d bytes to SMI.", count); ++ if (count > DMA_THRESHOLD_BYTES) ++ odd_bytes = count & 0x3; ++ else ++ odd_bytes = count; ++ count -= odd_bytes; ++ if (count) { ++ struct bcm2835_smi_bounce_info *bounce; ++ ++ count = bcm2835_smi_user_dma(smi_inst, ++ DMA_MEM_TO_DEV, (char __user *)user_ptr, count, ++ &bounce); ++ if (count) ++ count = dma_bounce_user(DMA_MEM_TO_DEV, ++ (char __user *)user_ptr, ++ count, bounce); ++ } ++ if (odd_bytes) { ++ uint8_t buf[DMA_THRESHOLD_BYTES]; ++ ++ if (copy_from_user(buf, user_ptr, odd_bytes)) ++ dev_err(inst->dev, "copy_from_user() failed."); ++ else ++ bcm2835_smi_write_buf(smi_inst, buf, odd_bytes); ++ count += odd_bytes; ++ } ++ return count; ++} ++ ++static const struct file_operations ++bcm2835_smi_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = bcm2835_smi_ioctl, ++ .open = bcm2835_smi_open, ++ .release = bcm2835_smi_release, ++ .read = bcm2835_read_file, ++ .write = bcm2835_write_file, ++}; ++ ++ ++/**************************************************************************** ++* ++* bcm2835_smi_probe - called when the driver is loaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_dev_probe(struct platform_device *pdev) ++{ ++ int err; ++ void *ptr_err; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node, *smi_node; ++ ++ if (!node) { ++ dev_err(dev, "No device tree node supplied!"); ++ return -EINVAL; ++ } ++ ++ smi_node = of_parse_phandle(node, "smi_handle", 0); ++ ++ if (!smi_node) { ++ dev_err(dev, "No such property: smi_handle"); ++ return -ENXIO; ++ } ++ ++ smi_inst = bcm2835_smi_get(smi_node); ++ ++ if (!smi_inst) ++ return -EPROBE_DEFER; ++ ++ /* Allocate buffers and instance data */ ++ ++ inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL); ++ ++ if (!inst) ++ return -ENOMEM; ++ ++ inst->dev = dev; ++ ++ /* Create character device entries */ ++ ++ err = alloc_chrdev_region(&bcm2835_smi_devid, ++ DEVICE_MINOR, 1, DEVICE_NAME); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to allocate device number"); ++ return -ENOMEM; ++ } ++ cdev_init(&bcm2835_smi_cdev, &bcm2835_smi_fops); ++ bcm2835_smi_cdev.owner = THIS_MODULE; ++ err = cdev_add(&bcm2835_smi_cdev, bcm2835_smi_devid, 1); ++ if (err != 0) { ++ dev_err(inst->dev, "unable to register device"); ++ err = -ENOMEM; ++ goto failed_cdev_add; ++ } ++ ++ /* Create sysfs entries */ ++ ++ bcm2835_smi_class = class_create(THIS_MODULE, DEVICE_NAME); ++ ptr_err = bcm2835_smi_class; ++ if (IS_ERR(ptr_err)) ++ goto failed_class_create; ++ ++ bcm2835_smi_dev = device_create(bcm2835_smi_class, NULL, ++ bcm2835_smi_devid, NULL, ++ "smi"); ++ ptr_err = bcm2835_smi_dev; ++ if (IS_ERR(ptr_err)) ++ goto failed_device_create; ++ ++ dev_info(inst->dev, "initialised"); ++ ++ return 0; ++ ++failed_device_create: ++ class_destroy(bcm2835_smi_class); ++failed_class_create: ++ cdev_del(&bcm2835_smi_cdev); ++ err = PTR_ERR(ptr_err); ++failed_cdev_add: ++ unregister_chrdev_region(bcm2835_smi_devid, 1); ++ dev_err(dev, "could not load bcm2835_smi_dev"); ++ return err; ++} ++ ++/**************************************************************************** ++* ++* bcm2835_smi_remove - called when the driver is unloaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_dev_remove(struct platform_device *pdev) ++{ ++ device_destroy(bcm2835_smi_class, bcm2835_smi_devid); ++ class_destroy(bcm2835_smi_class); ++ cdev_del(&bcm2835_smi_cdev); ++ unregister_chrdev_region(bcm2835_smi_devid, 1); ++ ++ dev_info(inst->dev, "SMI character dev removed - OK"); ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_smi_dev_of_match[] = { ++ {.compatible = "brcm,bcm2835-smi-dev",}, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_smi_dev_of_match); ++ ++static struct platform_driver bcm2835_smi_dev_driver = { ++ .probe = bcm2835_smi_dev_probe, ++ .remove = bcm2835_smi_dev_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_smi_dev_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_smi_dev_driver); ++ ++MODULE_ALIAS("platform:smi-dev-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION( ++ "Character device driver for BCM2835's secondary memory interface"); ++MODULE_AUTHOR("Luke Wren "); +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 098131f..c25f99b 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D + select INPUT_POLLDEV + default n + ++config BCM2835_SMI ++ tristate "Broadcom 283x Secondary Memory Interface driver" ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 ++ default m ++ help ++ Driver for enabling and using Broadcom's Secondary/Slow Memory Interface. ++ Appears as /dev/bcm2835_smi. For ioctl interface see drivers/misc/bcm2835_smi.h ++ + config AD525X_DPOT + tristate "Analog Devices Digital Potentiometers" + depends on (I2C || SPI) && SYSFS +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index ac24d77..1acff5b 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o + obj-$(CONFIG_INTEL_MID_PTI) += pti.o + obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o + obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o ++obj-$(CONFIG_BCM2835_SMI) += bcm2835_smi.o + obj-$(CONFIG_BMP085) += bmp085.o + obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o + obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o +diff --git a/drivers/misc/bcm2835_smi.c b/drivers/misc/bcm2835_smi.c +new file mode 100644 +index 0000000..63a4ea0 +--- /dev/null ++++ b/drivers/misc/bcm2835_smi.c +@@ -0,0 +1,985 @@ ++/** ++ * Broadcom Secondary Memory Interface driver ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BCM2835_SMI_IMPLEMENTATION ++#include ++ ++#define DRIVER_NAME "smi-bcm2835" ++ ++#define N_PAGES_FROM_BYTES(n) ((n + PAGE_SIZE-1) / PAGE_SIZE) ++ ++#define DMA_WRITE_TO_MEM true ++#define DMA_READ_FROM_MEM false ++ ++struct bcm2835_smi_instance { ++ struct device *dev; ++ struct smi_settings settings; ++ __iomem void *smi_regs_ptr, *cm_smi_regs_ptr; ++ dma_addr_t smi_regs_busaddr; ++ ++ struct dma_chan *dma_chan; ++ struct dma_slave_config dma_config; ++ ++ struct bcm2835_smi_bounce_info bounce; ++ ++ struct scatterlist buffer_sgl; ++ ++ int clock_source; ++ int clock_divisor; ++ ++ /* Sometimes we are called into in an atomic context (e.g. by ++ JFFS2 + MTD) so we can't use a mutex */ ++ spinlock_t transaction_lock; ++}; ++ ++/**************************************************************************** ++* ++* SMI clock manager setup ++* ++***************************************************************************/ ++ ++static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst, ++ u32 val, unsigned reg) ++{ ++ writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg); ++} ++ ++static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst, ++ unsigned reg) ++{ ++ return readl(inst->cm_smi_regs_ptr + reg); ++} ++ ++static void smi_setup_clock(struct bcm2835_smi_instance *inst) ++{ ++ dev_dbg(inst->dev, "Setting up clock..."); ++ /* Disable SMI clock and wait for it to stop. */ ++ write_smi_cm_reg(inst, 0, CM_SMI_CTL); ++ while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY) ++ ; ++ ++ write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS), ++ CM_SMI_DIV); ++ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS), ++ CM_SMI_CTL); ++ ++ /* Enable the clock */ ++ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) | ++ CM_SMI_CTL_ENAB, CM_SMI_CTL); ++} ++ ++/**************************************************************************** ++* ++* SMI peripheral setup ++* ++***************************************************************************/ ++ ++static inline void write_smi_reg(struct bcm2835_smi_instance *inst, ++ u32 val, unsigned reg) ++{ ++ writel(val, inst->smi_regs_ptr + reg); ++} ++ ++static inline u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg) ++{ ++ return readl(inst->smi_regs_ptr + reg); ++} ++ ++/* Token-paste macro for e.g SMIDSR_RSTROBE -> value of SMIDSR_RSTROBE_MASK */ ++#define _CONCAT(x, y) x##y ++#define CONCAT(x, y) _CONCAT(x, y) ++ ++#define SET_BIT_FIELD(dest, field, bits) ((dest) = \ ++ ((dest) & ~CONCAT(field, _MASK)) | (((bits) << CONCAT(field, _OFFS))& \ ++ CONCAT(field, _MASK))) ++#define GET_BIT_FIELD(src, field) (((src) & \ ++ CONCAT(field, _MASK)) >> CONCAT(field, _OFFS)) ++ ++static void smi_dump_context_labelled(struct bcm2835_smi_instance *inst, ++ const char *label) ++{ ++ dev_err(inst->dev, "SMI context dump: %s", label); ++ dev_err(inst->dev, "SMICS: 0x%08x", read_smi_reg(inst, SMICS)); ++ dev_err(inst->dev, "SMIL: 0x%08x", read_smi_reg(inst, SMIL)); ++ dev_err(inst->dev, "SMIDSR: 0x%08x", read_smi_reg(inst, SMIDSR0)); ++ dev_err(inst->dev, "SMIDSW: 0x%08x", read_smi_reg(inst, SMIDSW0)); ++ dev_err(inst->dev, "SMIDC: 0x%08x", read_smi_reg(inst, SMIDC)); ++ dev_err(inst->dev, "SMIFD: 0x%08x", read_smi_reg(inst, SMIFD)); ++ dev_err(inst->dev, " "); ++} ++ ++static inline void smi_dump_context(struct bcm2835_smi_instance *inst) ++{ ++ smi_dump_context_labelled(inst, ""); ++} ++ ++static void smi_get_default_settings(struct bcm2835_smi_instance *inst) ++{ ++ struct smi_settings *settings = &inst->settings; ++ ++ settings->data_width = SMI_WIDTH_16BIT; ++ settings->pack_data = true; ++ ++ settings->read_setup_time = 1; ++ settings->read_hold_time = 1; ++ settings->read_pace_time = 1; ++ settings->read_strobe_time = 3; ++ ++ settings->write_setup_time = settings->read_setup_time; ++ settings->write_hold_time = settings->read_hold_time; ++ settings->write_pace_time = settings->read_pace_time; ++ settings->write_strobe_time = settings->read_strobe_time; ++ ++ settings->dma_enable = true; ++ settings->dma_passthrough_enable = false; ++ settings->dma_read_thresh = 0x01; ++ settings->dma_write_thresh = 0x3f; ++ settings->dma_panic_read_thresh = 0x20; ++ settings->dma_panic_write_thresh = 0x20; ++} ++ ++void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst) ++{ ++ struct smi_settings *settings = &inst->settings; ++ int smidsr_temp = 0, smidsw_temp = 0, smics_temp, ++ smidcs_temp, smidc_temp = 0; ++ ++ spin_lock(&inst->transaction_lock); ++ ++ /* temporarily disable the peripheral: */ ++ smics_temp = read_smi_reg(inst, SMICS); ++ write_smi_reg(inst, 0, SMICS); ++ smidcs_temp = read_smi_reg(inst, SMIDCS); ++ write_smi_reg(inst, 0, SMIDCS); ++ ++ if (settings->pack_data) ++ smics_temp |= SMICS_PXLDAT; ++ else ++ smics_temp &= ~SMICS_PXLDAT; ++ ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time); ++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time); ++ write_smi_reg(inst, smidsr_temp, SMIDSR0); ++ ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width); ++ if (settings->data_width == SMI_WIDTH_8BIT) ++ smidsw_temp |= SMIDSW_WSWAP; ++ else ++ smidsw_temp &= ~SMIDSW_WSWAP; ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time); ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time); ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time); ++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE, ++ settings->write_strobe_time); ++ write_smi_reg(inst, smidsw_temp, SMIDSW0); ++ ++ SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh); ++ SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh); ++ SET_BIT_FIELD(smidc_temp, SMIDC_PANICR, ++ settings->dma_panic_read_thresh); ++ SET_BIT_FIELD(smidc_temp, SMIDC_PANICW, ++ settings->dma_panic_write_thresh); ++ if (settings->dma_passthrough_enable) { ++ smidc_temp |= SMIDC_DMAP; ++ smidsr_temp |= SMIDSR_RDREQ; ++ write_smi_reg(inst, smidsr_temp, SMIDSR0); ++ smidsw_temp |= SMIDSW_WDREQ; ++ write_smi_reg(inst, smidsw_temp, SMIDSW0); ++ } else ++ smidc_temp &= ~SMIDC_DMAP; ++ if (settings->dma_enable) ++ smidc_temp |= SMIDC_DMAEN; ++ else ++ smidc_temp &= ~SMIDC_DMAEN; ++ ++ write_smi_reg(inst, smidc_temp, SMIDC); ++ ++ /* re-enable (if was previously enabled) */ ++ write_smi_reg(inst, smics_temp, SMICS); ++ write_smi_reg(inst, smidcs_temp, SMIDCS); ++ ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_set_regs_from_settings); ++ ++struct smi_settings *bcm2835_smi_get_settings_from_regs ++ (struct bcm2835_smi_instance *inst) ++{ ++ struct smi_settings *settings = &inst->settings; ++ int smidsr, smidsw, smidc; ++ ++ spin_lock(&inst->transaction_lock); ++ ++ smidsr = read_smi_reg(inst, SMIDSR0); ++ smidsw = read_smi_reg(inst, SMIDSW0); ++ smidc = read_smi_reg(inst, SMIDC); ++ ++ settings->pack_data = (read_smi_reg(inst, SMICS) & SMICS_PXLDAT) ? ++ true : false; ++ ++ settings->data_width = GET_BIT_FIELD(smidsr, SMIDSR_RWIDTH); ++ settings->read_setup_time = GET_BIT_FIELD(smidsr, SMIDSR_RSETUP); ++ settings->read_hold_time = GET_BIT_FIELD(smidsr, SMIDSR_RHOLD); ++ settings->read_pace_time = GET_BIT_FIELD(smidsr, SMIDSR_RPACE); ++ settings->read_strobe_time = GET_BIT_FIELD(smidsr, SMIDSR_RSTROBE); ++ ++ settings->write_setup_time = GET_BIT_FIELD(smidsw, SMIDSW_WSETUP); ++ settings->write_hold_time = GET_BIT_FIELD(smidsw, SMIDSW_WHOLD); ++ settings->write_pace_time = GET_BIT_FIELD(smidsw, SMIDSW_WPACE); ++ settings->write_strobe_time = GET_BIT_FIELD(smidsw, SMIDSW_WSTROBE); ++ ++ settings->dma_read_thresh = GET_BIT_FIELD(smidc, SMIDC_REQR); ++ settings->dma_write_thresh = GET_BIT_FIELD(smidc, SMIDC_REQW); ++ settings->dma_panic_read_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICR); ++ settings->dma_panic_write_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICW); ++ settings->dma_passthrough_enable = (smidc & SMIDC_DMAP) ? true : false; ++ settings->dma_enable = (smidc & SMIDC_DMAEN) ? true : false; ++ ++ spin_unlock(&inst->transaction_lock); ++ ++ return settings; ++} ++EXPORT_SYMBOL(bcm2835_smi_get_settings_from_regs); ++ ++static inline void smi_set_address(struct bcm2835_smi_instance *inst, ++ unsigned int address) ++{ ++ int smia_temp = 0, smida_temp = 0; ++ ++ SET_BIT_FIELD(smia_temp, SMIA_ADDR, address); ++ SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address); ++ ++ /* Write to both address registers - user doesn't care whether we're ++ doing programmed or direct transfers. */ ++ write_smi_reg(inst, smia_temp, SMIA); ++ write_smi_reg(inst, smida_temp, SMIDA); ++} ++ ++static void smi_setup_regs(struct bcm2835_smi_instance *inst) ++{ ++ ++ dev_dbg(inst->dev, "Initialising SMI registers..."); ++ /* Disable the peripheral if already enabled */ ++ write_smi_reg(inst, 0, SMICS); ++ write_smi_reg(inst, 0, SMIDCS); ++ ++ smi_get_default_settings(inst); ++ bcm2835_smi_set_regs_from_settings(inst); ++ smi_set_address(inst, 0); ++ ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ENABLE, SMICS); ++ write_smi_reg(inst, read_smi_reg(inst, SMIDCS) | SMIDCS_ENABLE, ++ SMIDCS); ++} ++ ++/**************************************************************************** ++* ++* Low-level SMI access functions ++* Other modules should use the exported higher-level functions e.g. ++* bcm2835_smi_write_buf() unless they have a good reason to use these ++* ++***************************************************************************/ ++ ++static inline uint32_t smi_read_single_word(struct bcm2835_smi_instance *inst) ++{ ++ int timeout = 0; ++ ++ write_smi_reg(inst, SMIDCS_ENABLE, SMIDCS); ++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_START, SMIDCS); ++ /* Make sure things happen in the right order...*/ ++ mb(); ++ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && ++ ++timeout < 10000) ++ ; ++ if (timeout < 10000) ++ return read_smi_reg(inst, SMIDD); ++ ++ dev_err(inst->dev, ++ "SMI direct read timed out (is the clock set up correctly?)"); ++ return 0; ++} ++ ++static inline void smi_write_single_word(struct bcm2835_smi_instance *inst, ++ uint32_t data) ++{ ++ int timeout = 0; ++ ++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE, SMIDCS); ++ write_smi_reg(inst, data, SMIDD); ++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE | SMIDCS_START, ++ SMIDCS); ++ ++ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && ++ ++timeout < 10000) ++ ; ++ if (timeout >= 10000) ++ dev_err(inst->dev, ++ "SMI direct write timed out (is the clock set up correctly?)"); ++} ++ ++/* Initiates a programmed read into the read FIFO. It is up to the caller to ++ * read data from the FIFO - either via paced DMA transfer, ++ * or polling SMICS_RXD to check whether data is available. ++ * SMICS_ACTIVE will go low upon completion. */ ++static void smi_init_programmed_read(struct bcm2835_smi_instance *inst, ++ int num_transfers) ++{ ++ int smics_temp; ++ ++ /* Disable the peripheral: */ ++ smics_temp = read_smi_reg(inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE); ++ write_smi_reg(inst, smics_temp, SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) ++ ; ++ ++ /* Program the transfer count: */ ++ write_smi_reg(inst, num_transfers, SMIL); ++ ++ /* re-enable and start: */ ++ smics_temp |= SMICS_ENABLE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ smics_temp |= SMICS_CLEAR; ++ /* Just to be certain: */ ++ mb(); ++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) ++ ; ++ write_smi_reg(inst, smics_temp, SMICS); ++ smics_temp |= SMICS_START; ++ write_smi_reg(inst, smics_temp, SMICS); ++} ++ ++/* Initiates a programmed write sequence, using data from the write FIFO. ++ * It is up to the caller to initiate a DMA transfer before calling, ++ * or use another method to keep the write FIFO topped up. ++ * SMICS_ACTIVE will go low upon completion. ++ */ ++static void smi_init_programmed_write(struct bcm2835_smi_instance *inst, ++ int num_transfers) ++{ ++ int smics_temp; ++ ++ /* Disable the peripheral: */ ++ smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) ++ ; ++ ++ /* Program the transfer count: */ ++ write_smi_reg(inst, num_transfers, SMIL); ++ ++ /* setup, re-enable and start: */ ++ smics_temp |= SMICS_WRITE | SMICS_ENABLE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ smics_temp |= SMICS_START; ++ write_smi_reg(inst, smics_temp, SMICS); ++} ++ ++/* Initiate a read and then poll FIFO for data, reading out as it appears. */ ++static void smi_read_fifo(struct bcm2835_smi_instance *inst, ++ uint32_t *dest, int n_bytes) ++{ ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { ++ smi_dump_context_labelled(inst, ++ "WARNING: read FIFO not empty at start of read call."); ++ while (read_smi_reg(inst, SMICS)) ++ ; ++ } ++ ++ /* Dispatch the read: */ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_read(inst, n_bytes); ++ else if (inst->settings.data_width == SMI_WIDTH_16BIT) ++ smi_init_programmed_read(inst, n_bytes / 2); ++ else { ++ dev_err(inst->dev, "Unsupported data width for read."); ++ return; ++ } ++ ++ /* Poll FIFO to keep it empty */ ++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) ++ *dest++ = read_smi_reg(inst, SMID); ++ ++ /* Ensure that the FIFO is emptied */ ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { ++ int fifo_count; ++ ++ fifo_count = GET_BIT_FIELD(read_smi_reg(inst, SMIFD), ++ SMIFD_FCNT); ++ while (fifo_count--) ++ *dest++ = read_smi_reg(inst, SMID); ++ } ++ ++ if (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) ++ smi_dump_context_labelled(inst, ++ "WARNING: transaction finished but done bit not set."); ++ ++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) ++ smi_dump_context_labelled(inst, ++ "WARNING: read FIFO not empty at end of read call."); ++ ++} ++ ++/* Initiate a write, and then keep the FIFO topped up. */ ++static void smi_write_fifo(struct bcm2835_smi_instance *inst, ++ uint32_t *src, int n_bytes) ++{ ++ int i, timeout = 0; ++ ++ /* Empty FIFOs if not already so */ ++ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) { ++ smi_dump_context_labelled(inst, ++ "WARNING: write fifo not empty at start of write call."); ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_CLEAR, ++ SMICS); ++ } ++ ++ /* Initiate the transfer */ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_write(inst, n_bytes); ++ else if (inst->settings.data_width == SMI_WIDTH_16BIT) ++ smi_init_programmed_write(inst, n_bytes / 2); ++ else { ++ dev_err(inst->dev, "Unsupported data width for write."); ++ return; ++ } ++ /* Fill the FIFO: */ ++ for (i = 0; i < (n_bytes - 1) / 4 + 1; ++i) { ++ while (!(read_smi_reg(inst, SMICS) & SMICS_TXD)) ++ ; ++ write_smi_reg(inst, *src++, SMID); ++ } ++ /* Busy wait... */ ++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE) && ++timeout < ++ 1000000) ++ ; ++ if (timeout >= 1000000) ++ smi_dump_context_labelled(inst, ++ "Timed out on write operation!"); ++ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) ++ smi_dump_context_labelled(inst, ++ "WARNING: FIFO not empty at end of write operation."); ++} ++ ++/**************************************************************************** ++* ++* SMI DMA operations ++* ++***************************************************************************/ ++ ++/* Disable SMI and put it into the correct direction before doing DMA setup. ++ Stops spurious DREQs during setup. Peripheral is re-enabled by init_*() */ ++static void smi_disable(struct bcm2835_smi_instance *inst, ++ enum dma_transfer_direction direction) ++{ ++ int smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; ++ ++ if (direction == DMA_DEV_TO_MEM) ++ smics_temp &= ~SMICS_WRITE; ++ else ++ smics_temp |= SMICS_WRITE; ++ write_smi_reg(inst, smics_temp, SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) ++ ; ++} ++ ++static struct scatterlist *smi_scatterlist_from_buffer( ++ struct bcm2835_smi_instance *inst, ++ dma_addr_t buf, ++ size_t len, ++ struct scatterlist *sg) ++{ ++ sg_init_table(sg, 1); ++ sg_dma_address(sg) = buf; ++ sg_dma_len(sg) = len; ++ return sg; ++} ++ ++static void smi_dma_callback_user_copy(void *param) ++{ ++ /* Notify the bottom half that a chunk is ready for user copy */ ++ struct bcm2835_smi_instance *inst = ++ (struct bcm2835_smi_instance *)param; ++ ++ up(&inst->bounce.callback_sem); ++} ++ ++/* Creates a descriptor, assigns the given callback, and submits the ++ descriptor to dmaengine. Does not block - can queue up multiple ++ descriptors and then wait for them all to complete. ++ sg_len is the number of control blocks, NOT the number of bytes. ++ dir can be DMA_MEM_TO_DEV or DMA_DEV_TO_MEM. ++ callback can be NULL - in this case it is not called. */ ++static inline struct dma_async_tx_descriptor *smi_dma_submit_sgl( ++ struct bcm2835_smi_instance *inst, ++ struct scatterlist *sgl, ++ size_t sg_len, ++ enum dma_transfer_direction dir, ++ dma_async_tx_callback callback) ++{ ++ struct dma_async_tx_descriptor *desc; ++ ++ desc = dmaengine_prep_slave_sg(inst->dma_chan, ++ sgl, ++ sg_len, ++ dir, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK | ++ DMA_PREP_FENCE); ++ if (!desc) { ++ dev_err(inst->dev, "read_sgl: dma slave preparation failed!"); ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) & ~SMICS_ACTIVE, ++ SMICS); ++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) ++ cpu_relax(); ++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ACTIVE, ++ SMICS); ++ return NULL; ++ } ++ desc->callback = callback; ++ desc->callback_param = inst; ++ if (dmaengine_submit(desc) < 0) ++ return NULL; ++ return desc; ++} ++ ++/* NB this function blocks until the transfer is complete */ ++static void ++smi_dma_read_sgl(struct bcm2835_smi_instance *inst, ++ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) ++{ ++ struct dma_async_tx_descriptor *desc; ++ ++ /* Disable SMI and set to read before dispatching DMA - if SMI is in ++ * write mode and TX fifo is empty, it will generate a DREQ which may ++ * cause the read DMA to complete before the SMI read command is even ++ * dispatched! We want to dispatch DMA before SMI read so that reading ++ * is gapless, for logic analyser. ++ */ ++ ++ smi_disable(inst, DMA_DEV_TO_MEM); ++ ++ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL); ++ dma_async_issue_pending(inst->dma_chan); ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_read(inst, n_bytes); ++ else ++ smi_init_programmed_read(inst, n_bytes / 2); ++ ++ if (dma_wait_for_async_tx(desc) == DMA_ERROR) ++ smi_dump_context_labelled(inst, "DMA timeout!"); ++} ++ ++static void ++smi_dma_write_sgl(struct bcm2835_smi_instance *inst, ++ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) ++{ ++ struct dma_async_tx_descriptor *desc; ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ smi_init_programmed_write(inst, n_bytes); ++ else ++ smi_init_programmed_write(inst, n_bytes / 2); ++ ++ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_MEM_TO_DEV, NULL); ++ dma_async_issue_pending(inst->dma_chan); ++ ++ if (dma_wait_for_async_tx(desc) == DMA_ERROR) ++ smi_dump_context_labelled(inst, "DMA timeout!"); ++ else ++ /* Wait for SMI to finish our writes */ ++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) ++ cpu_relax(); ++} ++ ++ssize_t bcm2835_smi_user_dma( ++ struct bcm2835_smi_instance *inst, ++ enum dma_transfer_direction dma_dir, ++ char __user *user_ptr, size_t count, ++ struct bcm2835_smi_bounce_info **bounce) ++{ ++ int chunk_no = 0, chunk_size, count_left = count; ++ struct scatterlist *sgl; ++ void (*init_trans_func)(struct bcm2835_smi_instance *, int); ++ ++ spin_lock(&inst->transaction_lock); ++ ++ if (dma_dir == DMA_DEV_TO_MEM) ++ init_trans_func = smi_init_programmed_read; ++ else ++ init_trans_func = smi_init_programmed_write; ++ ++ smi_disable(inst, dma_dir); ++ ++ sema_init(&inst->bounce.callback_sem, 0); ++ if (bounce) ++ *bounce = &inst->bounce; ++ while (count_left) { ++ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? ++ DMA_BOUNCE_BUFFER_SIZE : count_left; ++ if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) { ++ sgl = ++ &inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; ++ } else { ++ sgl = smi_scatterlist_from_buffer( ++ inst, ++ inst->bounce.phys[ ++ chunk_no % DMA_BOUNCE_BUFFER_COUNT], ++ chunk_size, ++ &inst->buffer_sgl); ++ } ++ ++ if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir, ++ smi_dma_callback_user_copy ++ )) { ++ dev_err(inst->dev, "sgl submit failed"); ++ count = 0; ++ goto out; ++ } ++ count_left -= chunk_size; ++ chunk_no++; ++ } ++ dma_async_issue_pending(inst->dma_chan); ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) ++ init_trans_func(inst, count); ++ else if (inst->settings.data_width == SMI_WIDTH_16BIT) ++ init_trans_func(inst, count / 2); ++out: ++ spin_unlock(&inst->transaction_lock); ++ return count; ++} ++EXPORT_SYMBOL(bcm2835_smi_user_dma); ++ ++ ++/**************************************************************************** ++* ++* High level buffer transfer functions - for use by other drivers ++* ++***************************************************************************/ ++ ++/* Buffer must be physically contiguous - i.e. kmalloc, not vmalloc! */ ++void bcm2835_smi_write_buf( ++ struct bcm2835_smi_instance *inst, ++ const void *buf, size_t n_bytes) ++{ ++ int odd_bytes = n_bytes & 0x3; ++ ++ n_bytes -= odd_bytes; ++ ++ spin_lock(&inst->transaction_lock); ++ ++ if (n_bytes > DMA_THRESHOLD_BYTES) { ++ dma_addr_t phy_addr = dma_map_single( ++ inst->dev, ++ (void *)buf, ++ n_bytes, ++ DMA_MEM_TO_DEV); ++ struct scatterlist *sgl = ++ smi_scatterlist_from_buffer(inst, phy_addr, n_bytes, ++ &inst->buffer_sgl); ++ ++ if (!sgl) { ++ smi_dump_context_labelled(inst, ++ "Error: could not create scatterlist for write!"); ++ goto out; ++ } ++ smi_dma_write_sgl(inst, sgl, 1, n_bytes); ++ ++ dma_unmap_single ++ (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); ++ } else if (n_bytes) { ++ smi_write_fifo(inst, (uint32_t *) buf, n_bytes); ++ } ++ buf += n_bytes; ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) { ++ while (odd_bytes--) ++ smi_write_single_word(inst, *(uint8_t *) (buf++)); ++ } else { ++ while (odd_bytes >= 2) { ++ smi_write_single_word(inst, *(uint16_t *)buf); ++ buf += 2; ++ odd_bytes -= 2; ++ } ++ if (odd_bytes) { ++ /* Reading an odd number of bytes on a 16 bit bus is ++ a user bug. It's kinder to fail early and tell them ++ than to e.g. transparently give them the bottom byte ++ of a 16 bit transfer. */ ++ dev_err(inst->dev, ++ "WARNING: odd number of bytes specified for wide transfer."); ++ dev_err(inst->dev, ++ "At least one byte dropped as a result."); ++ dump_stack(); ++ } ++ } ++out: ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_write_buf); ++ ++void bcm2835_smi_read_buf(struct bcm2835_smi_instance *inst, ++ void *buf, size_t n_bytes) ++{ ++ ++ /* SMI is inherently 32-bit, which causes surprising amounts of mess ++ for bytes % 4 != 0. Easiest to avoid this mess altogether ++ by handling remainder separately. */ ++ int odd_bytes = n_bytes & 0x3; ++ ++ spin_lock(&inst->transaction_lock); ++ n_bytes -= odd_bytes; ++ if (n_bytes > DMA_THRESHOLD_BYTES) { ++ dma_addr_t phy_addr = dma_map_single(inst->dev, ++ buf, n_bytes, ++ DMA_DEV_TO_MEM); ++ struct scatterlist *sgl = smi_scatterlist_from_buffer( ++ inst, phy_addr, n_bytes, ++ &inst->buffer_sgl); ++ if (!sgl) { ++ smi_dump_context_labelled(inst, ++ "Error: could not create scatterlist for read!"); ++ goto out; ++ } ++ smi_dma_read_sgl(inst, sgl, 1, n_bytes); ++ dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); ++ } else if (n_bytes) { ++ smi_read_fifo(inst, (uint32_t *)buf, n_bytes); ++ } ++ buf += n_bytes; ++ ++ if (inst->settings.data_width == SMI_WIDTH_8BIT) { ++ while (odd_bytes--) ++ *((uint8_t *) (buf++)) = smi_read_single_word(inst); ++ } else { ++ while (odd_bytes >= 2) { ++ *(uint16_t *) buf = smi_read_single_word(inst); ++ buf += 2; ++ odd_bytes -= 2; ++ } ++ if (odd_bytes) { ++ dev_err(inst->dev, ++ "WARNING: odd number of bytes specified for wide transfer."); ++ dev_err(inst->dev, ++ "At least one byte dropped as a result."); ++ dump_stack(); ++ } ++ } ++out: ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_read_buf); ++ ++void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, ++ unsigned int address) ++{ ++ spin_lock(&inst->transaction_lock); ++ smi_set_address(inst, address); ++ spin_unlock(&inst->transaction_lock); ++} ++EXPORT_SYMBOL(bcm2835_smi_set_address); ++ ++struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node) ++{ ++ struct platform_device *pdev; ++ ++ if (!node) ++ return NULL; ++ ++ pdev = of_find_device_by_node(node); ++ if (!pdev) ++ return NULL; ++ ++ return platform_get_drvdata(pdev); ++} ++EXPORT_SYMBOL(bcm2835_smi_get); ++ ++/**************************************************************************** ++* ++* bcm2835_smi_probe - called when the driver is loaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_dma_setup(struct bcm2835_smi_instance *inst) ++{ ++ int i, rv = 0; ++ ++ inst->dma_chan = dma_request_slave_channel(inst->dev, "rx-tx"); ++ ++ inst->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ inst->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ inst->dma_config.src_addr = inst->smi_regs_busaddr + SMID; ++ inst->dma_config.dst_addr = inst->dma_config.src_addr; ++ /* Direction unimportant - always overridden by prep_slave_sg */ ++ inst->dma_config.direction = DMA_DEV_TO_MEM; ++ dmaengine_slave_config(inst->dma_chan, &inst->dma_config); ++ /* Alloc and map bounce buffers */ ++ for (i = 0; i < DMA_BOUNCE_BUFFER_COUNT; ++i) { ++ inst->bounce.buffer[i] = ++ dmam_alloc_coherent(inst->dev, DMA_BOUNCE_BUFFER_SIZE, ++ &inst->bounce.phys[i], ++ GFP_KERNEL); ++ if (!inst->bounce.buffer[i]) { ++ dev_err(inst->dev, "Could not allocate buffer!"); ++ rv = -ENOMEM; ++ break; ++ } ++ smi_scatterlist_from_buffer( ++ inst, ++ inst->bounce.phys[i], ++ DMA_BOUNCE_BUFFER_SIZE, ++ &inst->bounce.sgl[i] ++ ); ++ } ++ ++ return rv; ++} ++ ++static int bcm2835_smi_probe(struct platform_device *pdev) ++{ ++ int err; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct resource *ioresource; ++ struct bcm2835_smi_instance *inst; ++ ++ /* Allocate buffers and instance data */ ++ ++ inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance), ++ GFP_KERNEL); ++ ++ if (!inst) ++ return -ENOMEM; ++ ++ inst->dev = dev; ++ spin_lock_init(&inst->transaction_lock); ++ ++ /* We require device tree support */ ++ if (!node) ++ return -EINVAL; ++ ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource); ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource); ++ inst->smi_regs_busaddr = be32_to_cpu( ++ *of_get_address(node, 0, NULL, NULL)); ++ of_property_read_u32(node, ++ "brcm,smi-clock-source", ++ &inst->clock_source); ++ of_property_read_u32(node, ++ "brcm,smi-clock-divisor", ++ &inst->clock_divisor); ++ ++ err = bcm2835_smi_dma_setup(inst); ++ if (err) ++ return err; ++ ++ /* Finally, do peripheral setup */ ++ ++ smi_setup_clock(inst); ++ smi_setup_regs(inst); ++ ++ platform_set_drvdata(pdev, inst); ++ ++ dev_info(inst->dev, "initialised"); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* bcm2835_smi_remove - called when the driver is unloaded. ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev); ++ struct device *dev = inst->dev; ++ ++ dev_info(dev, "SMI device removed - OK"); ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_smi_of_match[] = { ++ {.compatible = "brcm,bcm2835-smi",}, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_smi_of_match); ++ ++static struct platform_driver bcm2835_smi_driver = { ++ .probe = bcm2835_smi_probe, ++ .remove = bcm2835_smi_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_smi_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_smi_driver); ++ ++MODULE_ALIAS("platform:smi-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Device driver for BCM2835's secondary memory interface"); ++MODULE_AUTHOR("Luke Wren "); +diff --git a/include/linux/broadcom/bcm2835_smi.h b/include/linux/broadcom/bcm2835_smi.h +new file mode 100644 +index 0000000..ee3a75e +--- /dev/null ++++ b/include/linux/broadcom/bcm2835_smi.h +@@ -0,0 +1,391 @@ ++/** ++ * Declarations and definitions for Broadcom's Secondary Memory Interface ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. ++ */ ++ ++#ifndef BCM2835_SMI_H ++#define BCM2835_SMI_H ++ ++#include ++ ++#ifndef __KERNEL__ ++#include ++#include ++#endif ++ ++#define BCM2835_SMI_IOC_MAGIC 0x1 ++#define BCM2835_SMI_INVALID_HANDLE (~0) ++ ++/* IOCTLs 0x100...0x1ff are not device-specific - we can use them */ ++#define BCM2835_SMI_IOC_GET_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 0) ++#define BCM2835_SMI_IOC_WRITE_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 1) ++#define BCM2835_SMI_IOC_ADDRESS _IO(BCM2835_SMI_IOC_MAGIC, 2) ++#define BCM2835_SMI_IOC_MAX 2 ++ ++#define SMI_WIDTH_8BIT 0 ++#define SMI_WIDTH_16BIT 1 ++#define SMI_WIDTH_9BIT 2 ++#define SMI_WIDTH_18BIT 3 ++ ++/* max number of bytes where DMA will not be used */ ++#define DMA_THRESHOLD_BYTES 128 ++#define DMA_BOUNCE_BUFFER_SIZE (1024 * 1024 / 2) ++#define DMA_BOUNCE_BUFFER_COUNT 3 ++ ++ ++struct smi_settings { ++ int data_width; ++ /* Whether or not to pack multiple SMI transfers into a ++ single 32 bit FIFO word */ ++ bool pack_data; ++ ++ /* Timing for reads (writes the same but for WE) ++ * ++ * OE ----------+ +-------------------- ++ * | | ++ * +----------+ ++ * SD -<==============================>----------- ++ * SA -<=========================================>- ++ * <-setup-> <-strobe -> <-hold -> <- pace -> ++ */ ++ ++ int read_setup_time; ++ int read_hold_time; ++ int read_pace_time; ++ int read_strobe_time; ++ ++ int write_setup_time; ++ int write_hold_time; ++ int write_pace_time; ++ int write_strobe_time; ++ ++ bool dma_enable; /* DREQs */ ++ bool dma_passthrough_enable; /* External DREQs */ ++ int dma_read_thresh; ++ int dma_write_thresh; ++ int dma_panic_read_thresh; ++ int dma_panic_write_thresh; ++}; ++ ++/**************************************************************************** ++* ++* Declare exported SMI functions ++* ++***************************************************************************/ ++ ++#ifdef __KERNEL__ ++ ++#include /* for enum dma_transfer_direction */ ++#include ++#include ++ ++struct bcm2835_smi_instance; ++ ++struct bcm2835_smi_bounce_info { ++ struct semaphore callback_sem; ++ void *buffer[DMA_BOUNCE_BUFFER_COUNT]; ++ dma_addr_t phys[DMA_BOUNCE_BUFFER_COUNT]; ++ struct scatterlist sgl[DMA_BOUNCE_BUFFER_COUNT]; ++}; ++ ++ ++void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *); ++ ++struct smi_settings *bcm2835_smi_get_settings_from_regs( ++ struct bcm2835_smi_instance *inst); ++ ++void bcm2835_smi_write_buf( ++ struct bcm2835_smi_instance *inst, ++ const void *buf, ++ size_t n_bytes); ++ ++void bcm2835_smi_read_buf( ++ struct bcm2835_smi_instance *inst, ++ void *buf, ++ size_t n_bytes); ++ ++void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, ++ unsigned int address); ++ ++ssize_t bcm2835_smi_user_dma( ++ struct bcm2835_smi_instance *inst, ++ enum dma_transfer_direction dma_dir, ++ char __user *user_ptr, ++ size_t count, ++ struct bcm2835_smi_bounce_info **bounce); ++ ++struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node); ++ ++#endif /* __KERNEL__ */ ++ ++/**************************************************************** ++* ++* Implementation-only declarations ++* ++****************************************************************/ ++ ++#ifdef BCM2835_SMI_IMPLEMENTATION ++ ++/* Clock manager registers for SMI clock: */ ++#define CM_SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x1010b0) ++/* Clock manager "password" to protect registers from spurious writes */ ++#define CM_PWD (0x5a << 24) ++ ++#define CM_SMI_CTL 0x00 ++#define CM_SMI_DIV 0x04 ++ ++#define CM_SMI_CTL_FLIP (1 << 8) ++#define CM_SMI_CTL_BUSY (1 << 7) ++#define CM_SMI_CTL_KILL (1 << 5) ++#define CM_SMI_CTL_ENAB (1 << 4) ++#define CM_SMI_CTL_SRC_MASK (0xf) ++#define CM_SMI_CTL_SRC_OFFS (0) ++ ++#define CM_SMI_DIV_DIVI_MASK (0xf << 12) ++#define CM_SMI_DIV_DIVI_OFFS (12) ++#define CM_SMI_DIV_DIVF_MASK (0xff << 4) ++#define CM_SMI_DIV_DIVF_OFFS (4) ++ ++/* SMI register mapping:*/ ++#define SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x600000) ++ ++#define SMICS 0x00 /* control + status register */ ++#define SMIL 0x04 /* length/count (n external txfers) */ ++#define SMIA 0x08 /* address register */ ++#define SMID 0x0c /* data register */ ++#define SMIDSR0 0x10 /* device 0 read settings */ ++#define SMIDSW0 0x14 /* device 0 write settings */ ++#define SMIDSR1 0x18 /* device 1 read settings */ ++#define SMIDSW1 0x1c /* device 1 write settings */ ++#define SMIDSR2 0x20 /* device 2 read settings */ ++#define SMIDSW2 0x24 /* device 2 write settings */ ++#define SMIDSR3 0x28 /* device 3 read settings */ ++#define SMIDSW3 0x2c /* device 3 write settings */ ++#define SMIDC 0x30 /* DMA control registers */ ++#define SMIDCS 0x34 /* direct control/status register */ ++#define SMIDA 0x38 /* direct address register */ ++#define SMIDD 0x3c /* direct data registers */ ++#define SMIFD 0x40 /* FIFO debug register */ ++ ++ ++ ++/* Control and Status register bits: ++ * SMICS_RXF : RX fifo full: 1 when RX fifo is full ++ * SMICS_TXE : TX fifo empty: 1 when empty. ++ * SMICS_RXD : RX fifo contains data: 1 when there is data. ++ * SMICS_TXD : TX fifo can accept data: 1 when true. ++ * SMICS_RXR : RX fifo needs reading: 1 when fifo more than 3/4 full, or ++ * when "DONE" and fifo not emptied. ++ * SMICS_TXW : TX fifo needs writing: 1 when less than 1/4 full. ++ * SMICS_AFERR : AXI FIFO error: 1 when fifo read when empty or written ++ * when full. Write 1 to clear. ++ * SMICS_EDREQ : 1 when external DREQ received. ++ * SMICS_PXLDAT : Pixel data: write 1 to enable pixel transfer modes. ++ * SMICS_SETERR : 1 if there was an error writing to setup regs (e.g. ++ * tx was in progress). Write 1 to clear. ++ * SMICS_PVMODE : Set to 1 to enable pixel valve mode. ++ * SMICS_INTR : Set to 1 to enable interrupt on RX. ++ * SMICS_INTT : Set to 1 to enable interrupt on TX. ++ * SMICS_INTD : Set to 1 to enable interrupt on DONE condition. ++ * SMICS_TEEN : Tear effect mode enabled: Programmed transfers will wait ++ * for a TE trigger before writing. ++ * SMICS_PAD1 : Padding settings for external transfers. For writes: the ++ * number of bytes initially written to the TX fifo that ++ * SMICS_PAD0 : should be ignored. For reads: the number of bytes that will ++ * be read before the data, and should be dropped. ++ * SMICS_WRITE : Transfer direction: 1 = write to external device, 0 = read ++ * SMICS_CLEAR : Write 1 to clear the FIFOs. ++ * SMICS_START : Write 1 to start the programmed transfer. ++ * SMICS_ACTIVE : Reads as 1 when a programmed transfer is underway. ++ * SMICS_DONE : Reads as 1 when transfer finished. For RX, not set until ++ * FIFO emptied. ++ * SMICS_ENABLE : Set to 1 to enable the SMI peripheral, 0 to disable. ++ */ ++ ++#define SMICS_RXF (1 << 31) ++#define SMICS_TXE (1 << 30) ++#define SMICS_RXD (1 << 29) ++#define SMICS_TXD (1 << 28) ++#define SMICS_RXR (1 << 27) ++#define SMICS_TXW (1 << 26) ++#define SMICS_AFERR (1 << 25) ++#define SMICS_EDREQ (1 << 15) ++#define SMICS_PXLDAT (1 << 14) ++#define SMICS_SETERR (1 << 13) ++#define SMICS_PVMODE (1 << 12) ++#define SMICS_INTR (1 << 11) ++#define SMICS_INTT (1 << 10) ++#define SMICS_INTD (1 << 9) ++#define SMICS_TEEN (1 << 8) ++#define SMICS_PAD1 (1 << 7) ++#define SMICS_PAD0 (1 << 6) ++#define SMICS_WRITE (1 << 5) ++#define SMICS_CLEAR (1 << 4) ++#define SMICS_START (1 << 3) ++#define SMICS_ACTIVE (1 << 2) ++#define SMICS_DONE (1 << 1) ++#define SMICS_ENABLE (1 << 0) ++ ++/* Address register bits: */ ++ ++#define SMIA_DEVICE_MASK ((1 << 9) | (1 << 8)) ++#define SMIA_DEVICE_OFFS (8) ++#define SMIA_ADDR_MASK (0x3f) /* bits 5 -> 0 */ ++#define SMIA_ADDR_OFFS (0) ++ ++/* DMA control register bits: ++ * SMIDC_DMAEN : DMA enable: set 1: DMA requests will be issued. ++ * SMIDC_DMAP : DMA passthrough: when set to 0, top two data pins are used by ++ * SMI as usual. When set to 1, the top two pins are used for ++ * external DREQs: pin 16 read request, 17 write. ++ * SMIDC_PANIC* : Threshold at which DMA will panic during read/write. ++ * SMIDC_REQ* : Threshold at which DMA will generate a DREQ. ++ */ ++ ++#define SMIDC_DMAEN (1 << 28) ++#define SMIDC_DMAP (1 << 24) ++#define SMIDC_PANICR_MASK (0x3f << 18) ++#define SMIDC_PANICR_OFFS (18) ++#define SMIDC_PANICW_MASK (0x3f << 12) ++#define SMIDC_PANICW_OFFS (12) ++#define SMIDC_REQR_MASK (0x3f << 6) ++#define SMIDC_REQR_OFFS (6) ++#define SMIDC_REQW_MASK (0x3f) ++#define SMIDC_REQW_OFFS (0) ++ ++/* Device settings register bits: same for all 4 (or 3?) device register sets. ++ * Device read settings: ++ * SMIDSR_RWIDTH : Read transfer width. 00 = 8bit, 01 = 16bit, ++ * 10 = 18bit, 11 = 9bit. ++ * SMIDSR_RSETUP : Read setup time: number of core cycles between chip ++ * select/address and read strobe. Min 1, max 64. ++ * SMIDSR_MODE68 : 1 for System 68 mode (i.e. enable + direction pins, ++ * rather than OE + WE pin) ++ * SMIDSR_FSETUP : If set to 1, setup time only applies to first ++ * transfer after address change. ++ * SMIDSR_RHOLD : Number of core cycles between read strobe going ++ * inactive and CS/address going inactive. Min 1, max 64 ++ * SMIDSR_RPACEALL : When set to 1, this device's RPACE value will always ++ * be used for the next transaction, even if it is not ++ * to this device. ++ * SMIDSR_RPACE : Number of core cycles spent waiting between CS ++ * deassert and start of next transfer. Min 1, max 128 ++ * SMIDSR_RDREQ : 1 = use external DMA request on SD16 to pace reads ++ * from device. Must also set DMAP in SMICS. ++ * SMIDSR_RSTROBE : Number of cycles to assert the read strobe. ++ * min 1, max 128. ++ */ ++#define SMIDSR_RWIDTH_MASK ((1<<31)|(1<<30)) ++#define SMIDSR_RWIDTH_OFFS (30) ++#define SMIDSR_RSETUP_MASK (0x3f << 24) ++#define SMIDSR_RSETUP_OFFS (24) ++#define SMIDSR_MODE68 (1 << 23) ++#define SMIDSR_FSETUP (1 << 22) ++#define SMIDSR_RHOLD_MASK (0x3f << 16) ++#define SMIDSR_RHOLD_OFFS (16) ++#define SMIDSR_RPACEALL (1 << 15) ++#define SMIDSR_RPACE_MASK (0x7f << 8) ++#define SMIDSR_RPACE_OFFS (8) ++#define SMIDSR_RDREQ (1 << 7) ++#define SMIDSR_RSTROBE_MASK (0x7f) ++#define SMIDSR_RSTROBE_OFFS (0) ++ ++/* Device write settings: ++ * SMIDSW_WWIDTH : Write transfer width. 00 = 8bit, 01 = 16bit, ++ * 10= 18bit, 11 = 9bit. ++ * SMIDSW_WSETUP : Number of cycles between CS assert and write strobe. ++ * Min 1, max 64. ++ * SMIDSW_WFORMAT : Pixel format of input. 0 = 16bit RGB 565, ++ * 1 = 32bit RGBA 8888 ++ * SMIDSW_WSWAP : 1 = swap pixel data bits. (Use with SMICS_PXLDAT) ++ * SMIDSW_WHOLD : Time between WE deassert and CS deassert. 1 to 64 ++ * SMIDSW_WPACEALL : 1: this device's WPACE will be used for the next ++ * transfer, regardless of that transfer's device. ++ * SMIDSW_WPACE : Cycles between CS deassert and next CS assert. ++ * Min 1, max 128 ++ * SMIDSW_WDREQ : Use external DREQ on pin 17 to pace writes. DMAP must ++ * be set in SMICS. ++ * SMIDSW_WSTROBE : Number of cycles to assert the write strobe. ++ * Min 1, max 128 ++ */ ++#define SMIDSW_WWIDTH_MASK ((1<<31)|(1<<30)) ++#define SMIDSW_WWIDTH_OFFS (30) ++#define SMIDSW_WSETUP_MASK (0x3f << 24) ++#define SMIDSW_WSETUP_OFFS (24) ++#define SMIDSW_WFORMAT (1 << 23) ++#define SMIDSW_WSWAP (1 << 22) ++#define SMIDSW_WHOLD_MASK (0x3f << 16) ++#define SMIDSW_WHOLD_OFFS (16) ++#define SMIDSW_WPACEALL (1 << 15) ++#define SMIDSW_WPACE_MASK (0x7f << 8) ++#define SMIDSW_WPACE_OFFS (8) ++#define SMIDSW_WDREQ (1 << 7) ++#define SMIDSW_WSTROBE_MASK (0x7f) ++#define SMIDSW_WSTROBE_OFFS (0) ++ ++/* Direct transfer control + status register ++ * SMIDCS_WRITE : Direction of transfer: 1 -> write, 0 -> read ++ * SMIDCS_DONE : 1 when a transfer has finished. Write 1 to clear. ++ * SMIDCS_START : Write 1 to start a transfer, if one is not already underway. ++ * SMIDCE_ENABLE: Write 1 to enable SMI in direct mode. ++ */ ++ ++#define SMIDCS_WRITE (1 << 3) ++#define SMIDCS_DONE (1 << 2) ++#define SMIDCS_START (1 << 1) ++#define SMIDCS_ENABLE (1 << 0) ++ ++/* Direct transfer address register ++ * SMIDA_DEVICE : Indicates which of the device settings banks should be used. ++ * SMIDA_ADDR : The value to be asserted on the address pins. ++ */ ++ ++#define SMIDA_DEVICE_MASK ((1<<9)|(1<<8)) ++#define SMIDA_DEVICE_OFFS (8) ++#define SMIDA_ADDR_MASK (0x3f) ++#define SMIDA_ADDR_OFFS (0) ++ ++/* FIFO debug register ++ * SMIFD_FLVL : The high-tide mark of FIFO count during the most recent txfer ++ * SMIFD_FCNT : The current FIFO count. ++ */ ++#define SMIFD_FLVL_MASK (0x3f << 8) ++#define SMIFD_FLVL_OFFS (8) ++#define SMIFD_FCNT_MASK (0x3f) ++#define SMIFD_FCNT_OFFS (0) ++ ++#endif /* BCM2835_SMI_IMPLEMENTATION */ ++ ++#endif /* BCM2835_SMI_H */ + +From d263fa3cf01ecca6447ce0f62a43c33d715a27de Mon Sep 17 00:00:00 2001 +From: Luke Wren +Date: Sat, 5 Sep 2015 01:16:10 +0100 +Subject: [PATCH 028/113] Add SMI NAND driver + +Signed-off-by: Luke Wren +--- + .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++ + drivers/mtd/nand/Kconfig | 7 + + drivers/mtd/nand/Makefile | 1 + + drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++ + 4 files changed, 318 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt + create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c + +diff --git a/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt +new file mode 100644 +index 0000000..159544d +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt +@@ -0,0 +1,42 @@ ++* BCM2835 SMI NAND flash ++ ++This driver is a shim between the BCM2835 SMI driver (SMI is a peripheral for ++talking to parallel register interfaces) and Linux's MTD layer. ++ ++Required properties: ++- compatible: "brcm,bcm2835-smi-nand" ++- status: "okay" ++ ++Optional properties: ++- partition@n, where n is an integer from a consecutive sequence starting at 0 ++ - Difficult to store partition table on NAND device - normally put it ++ in the source code, kernel bootparams, or device tree (the best way!) ++ - Sub-properties: ++ - label: the partition name, as shown by mtdinfo /dev/mtd* ++ - reg: the size and offset of this partition. ++ - (optional) read-only: an empty property flagging as read only ++ ++Example: ++ ++nand: flash@0 { ++ compatible = "brcm,bcm2835-smi-nand"; ++ status = "okay"; ++ ++ partition@0 { ++ label = "stage2"; ++ // 128k ++ reg = <0 0x20000>; ++ read-only; ++ }; ++ partition@1 { ++ label = "firmware"; ++ // 16M ++ reg = <0x20000 0x1000000>; ++ read-only; ++ }; ++ partition@2 { ++ label = "root"; ++ // 2G ++ reg = <0x1020000 0x80000000>; ++ }; ++}; +\ No newline at end of file +diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig +index 3324281..1dc71d9 100644 +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -41,6 +41,13 @@ config MTD_SM_COMMON + tristate + default n + ++config MTD_NAND_BCM2835_SMI ++ tristate "Use Broadcom's Secondary Memory Interface as a NAND controller (BCM283x)" ++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI && MTD_NAND ++ default m ++ help ++ Uses the BCM2835's SMI peripheral as a NAND controller. ++ + config MTD_NAND_DENALI + tristate + +diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile +index 075a027..fad42ff 100644 +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o + obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o + obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o + obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o ++obj-$(CONFIG_MTD_NAND_BCM2835_SMI) += bcm2835_smi_nand.o + obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o + obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o + obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o +diff --git a/drivers/mtd/nand/bcm2835_smi_nand.c b/drivers/mtd/nand/bcm2835_smi_nand.c +new file mode 100644 +index 0000000..b747326 +--- /dev/null ++++ b/drivers/mtd/nand/bcm2835_smi_nand.c +@@ -0,0 +1,268 @@ ++/** ++ * NAND flash driver for Broadcom Secondary Memory Interface ++ * ++ * Written by Luke Wren ++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. ++ * ++ * 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, ++ * without modification. ++ * 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. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DEVICE_NAME "bcm2835-smi-nand" ++#define DRIVER_NAME "smi-nand-bcm2835" ++ ++struct bcm2835_smi_nand_host { ++ struct bcm2835_smi_instance *smi_inst; ++ struct nand_chip nand_chip; ++ struct mtd_info mtd; ++ struct device *dev; ++}; ++ ++/**************************************************************************** ++* ++* NAND functionality implementation ++* ++****************************************************************************/ ++ ++#define SMI_NAND_CLE_PIN 0x01 ++#define SMI_NAND_ALE_PIN 0x02 ++ ++static inline void bcm2835_smi_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, ++ unsigned int ctrl) ++{ ++ uint32_t cmd32 = cmd; ++ uint32_t addr = ~(SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ if (ctrl & NAND_CLE) ++ addr |= SMI_NAND_CLE_PIN; ++ if (ctrl & NAND_ALE) ++ addr |= SMI_NAND_ALE_PIN; ++ /* Lower ALL the CS pins! */ ++ if (ctrl & NAND_NCE) ++ addr &= (SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); ++ ++ bcm2835_smi_set_address(inst, addr); ++ ++ if (cmd != NAND_CMD_NONE) ++ bcm2835_smi_write_buf(inst, &cmd32, 1); ++} ++ ++static inline uint8_t bcm2835_smi_nand_read_byte(struct mtd_info *mtd) ++{ ++ uint8_t byte; ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_read_buf(inst, &byte, 1); ++ return byte; ++} ++ ++static inline void bcm2835_smi_nand_write_byte(struct mtd_info *mtd, ++ uint8_t byte) ++{ ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_write_buf(inst, &byte, 1); ++} ++ ++static inline void bcm2835_smi_nand_write_buf(struct mtd_info *mtd, ++ const uint8_t *buf, int len) ++{ ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_write_buf(inst, buf, len); ++} ++ ++static inline void bcm2835_smi_nand_read_buf(struct mtd_info *mtd, ++ uint8_t *buf, int len) ++{ ++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); ++ struct bcm2835_smi_instance *inst = host->smi_inst; ++ ++ bcm2835_smi_read_buf(inst, buf, len); ++} ++ ++/**************************************************************************** ++* ++* Probe and remove functions ++* ++***************************************************************************/ ++ ++static int bcm2835_smi_nand_probe(struct platform_device *pdev) ++{ ++ struct bcm2835_smi_nand_host *host; ++ struct nand_chip *this; ++ struct mtd_info *mtd; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node, *smi_node; ++ struct mtd_part_parser_data ppdata; ++ struct smi_settings *smi_settings; ++ struct bcm2835_smi_instance *smi_inst; ++ int ret = -ENXIO; ++ ++ if (!node) { ++ dev_err(dev, "No device tree node supplied!"); ++ return -EINVAL; ++ } ++ ++ smi_node = of_parse_phandle(node, "smi_handle", 0); ++ ++ /* Request use of SMI peripheral: */ ++ smi_inst = bcm2835_smi_get(smi_node); ++ ++ if (!smi_inst) { ++ dev_err(dev, "Could not register with SMI."); ++ return -EPROBE_DEFER; ++ } ++ ++ /* Set SMI timing and bus width */ ++ ++ smi_settings = bcm2835_smi_get_settings_from_regs(smi_inst); ++ ++ smi_settings->data_width = SMI_WIDTH_8BIT; ++ smi_settings->read_setup_time = 2; ++ smi_settings->read_hold_time = 1; ++ smi_settings->read_pace_time = 1; ++ smi_settings->read_strobe_time = 3; ++ ++ smi_settings->write_setup_time = 2; ++ smi_settings->write_hold_time = 1; ++ smi_settings->write_pace_time = 1; ++ smi_settings->write_strobe_time = 3; ++ ++ bcm2835_smi_set_regs_from_settings(smi_inst); ++ ++ host = devm_kzalloc(dev, sizeof(struct bcm2835_smi_nand_host), ++ GFP_KERNEL); ++ if (!host) ++ return -ENOMEM; ++ ++ host->dev = dev; ++ host->smi_inst = smi_inst; ++ ++ platform_set_drvdata(pdev, host); ++ ++ /* Link the structures together */ ++ ++ this = &host->nand_chip; ++ mtd = &host->mtd; ++ mtd->priv = this; ++ mtd->owner = THIS_MODULE; ++ mtd->dev.parent = dev; ++ mtd->name = DRIVER_NAME; ++ ppdata.of_node = node; ++ ++ /* 20 us command delay time... */ ++ this->chip_delay = 20; ++ ++ this->priv = host; ++ this->cmd_ctrl = bcm2835_smi_nand_cmd_ctrl; ++ this->read_byte = bcm2835_smi_nand_read_byte; ++ this->write_byte = bcm2835_smi_nand_write_byte; ++ this->write_buf = bcm2835_smi_nand_write_buf; ++ this->read_buf = bcm2835_smi_nand_read_buf; ++ ++ this->ecc.mode = NAND_ECC_SOFT; ++ ++ /* Should never be accessed directly: */ ++ ++ this->IO_ADDR_R = (void *)0xdeadbeef; ++ this->IO_ADDR_W = (void *)0xdeadbeef; ++ ++ /* First scan to find the device and get the page size */ ++ ++ if (nand_scan_ident(mtd, 1, NULL)) ++ return -ENXIO; ++ ++ /* Second phase scan */ ++ ++ if (nand_scan_tail(mtd)) ++ return -ENXIO; ++ ++ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); ++ if (!ret) ++ return 0; ++ ++ nand_release(mtd); ++ return -EINVAL; ++} ++ ++static int bcm2835_smi_nand_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_smi_nand_host *host = platform_get_drvdata(pdev); ++ ++ nand_release(&host->mtd); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* Register the driver with device tree ++* ++***************************************************************************/ ++ ++static const struct of_device_id bcm2835_smi_nand_of_match[] = { ++ {.compatible = "brcm,bcm2835-smi-nand",}, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, bcm2835_smi_nand_of_match); ++ ++static struct platform_driver bcm2835_smi_nand_driver = { ++ .probe = bcm2835_smi_nand_probe, ++ .remove = bcm2835_smi_nand_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_smi_nand_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2835_smi_nand_driver); ++ ++MODULE_ALIAS("platform:smi-nand-bcm2835"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION ++ ("Driver for NAND chips using Broadcom Secondary Memory Interface"); ++MODULE_AUTHOR("Luke Wren "); + +From e28e00facc7bc54d995a0111f3a301cf3d5cadc7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:51:55 +0100 -Subject: [PATCH 015/204] Add hwrng (hardware random number generator) driver +Subject: [PATCH 029/113] Add hwrng (hardware random number generator) driver --- drivers/char/hw_random/Kconfig | 13 +++- @@ -101823,10 +105748,10 @@ index 0000000..340f004 +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL and additional rights"); -From 0f09a4b263925916b493657ad19334d1b62ee299 Mon Sep 17 00:00:00 2001 +From fa1c1a7ff57c800a80cb50c0ed4908e098bc8d66 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 016/204] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 030/113] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -102679,29 +106604,29 @@ index 0000000..24563ec +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -From 7dc35f47e29f40755b9a66b6c1b8f693d0a7e414 Mon Sep 17 00:00:00 2001 +From 72e14f691b5b697160bb2bc0926ff3adb3672ef0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 017/204] Add cpufreq driver +Subject: [PATCH 031/113] Add cpufreq driver Signed-off-by: popcornmix --- drivers/cpufreq/Kconfig.arm | 9 ++ drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/bcm2835-cpufreq.c | 224 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 234 insertions(+) + drivers/cpufreq/bcm2835-cpufreq.c | 213 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 223 insertions(+) create mode 100644 drivers/cpufreq/bcm2835-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index 4f3dbc8..a1039f0 100644 +index cd0391e..d54b721 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm -@@ -258,6 +258,15 @@ config ARM_SPEAR_CPUFREQ +@@ -206,6 +206,15 @@ config ARM_SPEAR_CPUFREQ help This adds the CPUFreq driver support for SPEAr SOCs. +config ARM_BCM2835_CPUFREQ -+ depends on BCM2708_MBOX ++ depends on RASPBERRYPI_FIRMWARE + bool "BCM2835 Driver" + default y + help @@ -102709,27 +106634,27 @@ index 4f3dbc8..a1039f0 100644 + + If in doubt, say N. + - config ARM_TEGRA_CPUFREQ - bool "TEGRA CPUFreq support" + config ARM_TEGRA20_CPUFREQ + bool "Tegra20 CPUFreq support" depends on ARCH_TEGRA diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index cdce92a..c420f3f 100644 +index 4134038..51ce004 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile -@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o +@@ -73,6 +73,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o +obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o - obj-$(CONFIG_ARM_TEGRA_CPUFREQ) += tegra-cpufreq.o + obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o + obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o - diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c new file mode 100644 -index 0000000..6735da9 +index 0000000..3eb9e93 --- /dev/null +++ b/drivers/cpufreq/bcm2835-cpufreq.c -@@ -0,0 +1,224 @@ +@@ -0,0 +1,213 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -102758,7 +106683,7 @@ index 0000000..6735da9 +#include +#include +#include -+#include ++#include + +/* ---------- DEFINES ---------- */ +/*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ @@ -102775,23 +106700,6 @@ index 0000000..6735da9 +#define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) +#define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__) + -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the message id */ -+ uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -+ uint32_t data_size; /* amount of data being sent or received */ -+ uint32_t dev_id; /* the ID of the clock/voltage to get or set */ -+ uint32_t val; /* the value (e.g. rate (in Hz)) to set */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ +/* ---------- GLOBALS ---------- */ +static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */ + @@ -102806,62 +106714,63 @@ index 0000000..6735da9 + clk_rate either gets or sets the clock rates. + =============================================== +*/ ++ ++static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) ++{ ++ struct rpi_firmware *fw = rpi_firmware_get(NULL); ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ int ret; ++ ++ packet.id = id; ++ packet.val = *val; ++ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); ++ if (ret) ++ return ret; ++ ++ *val = packet.val; ++ ++ return 0; ++} ++ +static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) +{ -+ int s, actual_rate=0; -+ struct vc_msg msg; ++ u32 rate = arm_rate * 1000; ++ int ret; + -+ /* wipe all previous message data */ -+ memset(&msg, 0, sizeof msg); ++ ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate); ++ if (ret) { ++ print_err("Failed to set clock: %d (%d)\n", arm_rate, ret); ++ return 0; ++ } + -+ msg.msg_size = sizeof msg; ++ rate /= 1000; ++ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate); + -+ msg.tag.tag_id = VCMSG_SET_CLOCK_RATE; -+ msg.tag.buffer_size = 8; -+ msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */ -+ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; -+ msg.tag.val = arm_rate * 1000; -+ -+ /* send the message */ -+ s = bcm_mailbox_property(&msg, sizeof msg); -+ -+ /* check if it was all ok and return the rate in KHz */ -+ if (s == 0 && (msg.request_code & 0x80000000)) -+ actual_rate = msg.tag.val/1000; -+ -+ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate); -+ return actual_rate; ++ return rate; +} + +static uint32_t bcm2835_cpufreq_get_clock(int tag) +{ -+ int s; -+ int arm_rate = 0; -+ struct vc_msg msg; ++ u32 rate; ++ int ret; + -+ /* wipe all previous message data */ -+ memset(&msg, 0, sizeof msg); ++ ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate); ++ if (ret) { ++ print_err("Failed to get clock (%d)\n", ret); ++ return 0; ++ } + -+ msg.msg_size = sizeof msg; -+ msg.tag.tag_id = tag; -+ msg.tag.buffer_size = 8; -+ msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */ -+ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; ++ rate /= 1000; ++ print_debug("%s frequency = %u\n", ++ tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current": ++ tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min": ++ tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max": ++ "Unexpected", rate); + -+ /* send the message */ -+ s = bcm_mailbox_property(&msg, sizeof msg); -+ -+ /* check if it was all ok and return the rate in KHz */ -+ if (s == 0 && (msg.request_code & 0x80000000)) -+ arm_rate = msg.tag.val/1000; -+ -+ print_debug("%s frequency = %d\n", -+ tag == VCMSG_GET_CLOCK_RATE ? "Current": -+ tag == VCMSG_GET_MIN_CLOCK ? "Min": -+ tag == VCMSG_GET_MAX_CLOCK ? "Max": -+ "Unexpected", arm_rate); -+ -+ return arm_rate; ++ return rate; +} + +/* @@ -102897,9 +106806,14 @@ index 0000000..6735da9 + /* measured value of how long it takes to change frequency */ + const unsigned int transition_latency = 355000; /* ns */ + ++ if (!rpi_firmware_get(NULL)) { ++ print_err("Firmware is not available\n"); ++ return -ENODEV; ++ } ++ + /* now find out what the maximum and minimum frequencies are */ -+ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK); -+ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK); ++ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); ++ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); + + print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency); + return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency); @@ -102933,8 +106847,8 @@ index 0000000..6735da9 + +static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu) +{ -+ unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE); -+ print_debug("%d: freq=%d\n", cpu, actual_rate); ++ unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE); ++ print_debug("cpu%d: freq=%d\n", cpu, actual_rate); + return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency; +} + @@ -102955,10 +106869,10 @@ index 0000000..6735da9 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From d8057ff6ba5dece8ae393713e563362dc53bbde4 Mon Sep 17 00:00:00 2001 +From 9a6fb64fe686eca62c0d649cbae566e4626d32e3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 018/204] Added hwmon/thermal driver for reporting core +Subject: [PATCH 032/113] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -102976,15 +106890,15 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2709/bcm2709.c | 6 ++ drivers/thermal/Kconfig | 7 ++ drivers/thermal/Makefile | 1 + - drivers/thermal/bcm2835-thermal.c | 190 ++++++++++++++++++++++++++++++++++++++ - 5 files changed, 210 insertions(+) + drivers/thermal/bcm2835-thermal.c | 141 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 161 insertions(+) create mode 100644 drivers/thermal/bcm2835-thermal.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index ecf0524..978aaff 100644 +index 541ee37..30b77dc 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -505,6 +505,10 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -494,6 +494,10 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -102995,9 +106909,9 @@ index ecf0524..978aaff 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -651,6 +655,8 @@ void __init bcm2708_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -645,6 +649,8 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2835_thermal_device); + @@ -103005,10 +106919,10 @@ index ecf0524..978aaff 100644 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index de9feaa..0e5c8e3 100644 +index 0a7bd3e..c6341ba 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -525,6 +525,10 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -510,6 +510,10 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103019,9 +106933,9 @@ index de9feaa..0e5c8e3 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -671,6 +675,8 @@ void __init bcm2709_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -662,6 +666,8 @@ void __init bcm2709_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2835_thermal_device); + @@ -103029,15 +106943,15 @@ index de9feaa..0e5c8e3 100644 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index af40db0..ddc77ad 100644 +index 5aabc4b..748880c 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig -@@ -238,6 +238,13 @@ config INTEL_POWERCLAMP +@@ -271,6 +271,13 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. +config THERMAL_BCM2835 -+ depends on BCM2708_MBOX ++ depends on RASPBERRYPI_FIRMWARE + tristate "BCM2835 Thermal Driver" + help + This will enable temperature monitoring for the Broadcom BCM2835 @@ -103047,23 +106961,23 @@ index af40db0..ddc77ad 100644 tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile -index fa0dc48..453d4d9 100644 +index 26f1608..61b0d4f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile -@@ -33,6 +33,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o +@@ -35,6 +35,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o +obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o + obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE) += intel_soc_dts_iosf.o obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o - obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c new file mode 100644 -index 0000000..3bc80f1 +index 0000000..c1d8f1b --- /dev/null +++ b/drivers/thermal/bcm2835-thermal.c -@@ -0,0 +1,190 @@ +@@ -0,0 +1,141 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -103078,161 +106992,113 @@ index 0000000..3bc80f1 +* consent. +*****************************************************************************/ + -+#include +#include -+#include -+#include +#include -+#include -+#include +#include ++#include + -+ -+/* --- DEFINITIONS --- */ -+#define MODULE_NAME "bcm2835_thermal" -+ -+/*#define THERMAL_DEBUG_ENABLE*/ -+ -+#ifdef THERMAL_DEBUG_ENABLE -+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) -+#else -+#define print_debug(fmt,...) -+#endif -+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) -+ -+#define VC_TAG_GET_TEMP 0x00030006 -+#define VC_TAG_GET_MAX_TEMP 0x0003000A -+ -+typedef enum { -+ TEMP, -+ MAX_TEMP, -+} temp_type; -+ -+/* --- STRUCTS --- */ -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the tag ID for the temperature */ -+ uint32_t buffer_size; /* size of the buffer (should be 8) */ -+ uint32_t request_code; /* identifies message as a request (should be 0) */ -+ uint32_t id; /* extra ID field (should be 0) */ -+ uint32_t val; /* returned value of the temperature */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ -+struct bcm2835_thermal_data { -+ struct thermal_zone_device *thermal_dev; -+ struct vc_msg msg; -+}; -+ -+/* --- GLOBALS --- */ -+static struct bcm2835_thermal_data bcm2835_data; -+ -+/* Thermal Device Operations */ -+static struct thermal_zone_device_ops ops; -+ -+/* --- FUNCTIONS --- */ -+ -+static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id) ++static int bcm2835_thermal_get_property(struct thermal_zone_device *tz, ++ unsigned long *temp, u32 tag) +{ -+ int result = -1, retry = 3; -+ print_debug("IN"); ++ struct rpi_firmware *fw = tz->devdata; ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ int ret; + + *temp = 0; -+ while (result != 0 && retry-- > 0) { -+ /* wipe all previous message data */ -+ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg); -+ -+ /* prepare message */ -+ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg; -+ bcm2835_data.msg.tag.buffer_size = 8; -+ bcm2835_data.msg.tag.tag_id = tag_id; -+ -+ /* send the message */ -+ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg); -+ print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code); -+ if (!(bcm2835_data.msg.request_code & 0x80000000)) -+ result = -1; ++ packet.id = 0; ++ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); ++ if (ret) { ++ dev_err(&tz->device, "Failed to get temperature\n"); ++ return ret; + } + -+ /* check if it was all ok and return the rate in milli degrees C */ -+ if (result == 0) -+ *temp = (uint)bcm2835_data.msg.tag.val; -+ else -+ print_err("Failed to get temperature! (%x:%d)\n", tag_id, result); -+ print_debug("OUT"); -+ return result; -+} ++ *temp = packet.val; ++ dev_dbg(&tz->device, "%stemp=%lu\n", ++ tag == RPI_FIRMWARE_GET_MAX_TEMPERATURE ? "max" : "", *temp); + -+static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp) -+{ -+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP); -+} -+ -+static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp) -+{ -+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP); -+} -+ -+static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type) -+{ -+ *trip_type = THERMAL_TRIP_HOT; + return 0; +} + -+ -+static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode) ++static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz, ++ unsigned long *temp) +{ -+ *dev_mode = THERMAL_DEVICE_ENABLED; ++ return bcm2835_thermal_get_property(tz, temp, ++ RPI_FIRMWARE_GET_TEMPERATURE); ++} ++ ++static int bcm2835_thermal_get_max_temp(struct thermal_zone_device *tz, ++ int trip, unsigned long *temp) ++{ ++ /* ++ * The maximum safe temperature of the SoC. ++ * Overclock may be disabled above this temperature. ++ */ ++ return bcm2835_thermal_get_property(tz, temp, ++ RPI_FIRMWARE_GET_MAX_TEMPERATURE); ++} ++ ++static int bcm2835_thermal_get_trip_type(struct thermal_zone_device *tz, ++ int trip, enum thermal_trip_type *type) ++{ ++ *type = THERMAL_TRIP_HOT; ++ + return 0; +} + -+ -+static int bcm2835_thermal_probe(struct platform_device *pdev) ++static int bcm2835_thermal_get_mode(struct thermal_zone_device *tz, ++ enum thermal_device_mode *mode) +{ -+ print_debug("IN"); -+ print_debug("THERMAL Driver has been probed!"); -+ -+ /* check that the device isn't null!*/ -+ if(pdev == NULL) -+ { -+ print_debug("Platform device is empty!"); -+ return -ENODEV; -+ } -+ -+ if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0))) -+ { -+ print_debug("Unable to register the thermal device!"); -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+ -+static int bcm2835_thermal_remove(struct platform_device *pdev) -+{ -+ print_debug("IN"); -+ -+ thermal_zone_device_unregister(bcm2835_data.thermal_dev); -+ -+ print_debug("OUT"); ++ *mode = THERMAL_DEVICE_ENABLED; + + return 0; +} + +static struct thermal_zone_device_ops ops = { -+ .get_temp = bcm2835_get_temp, -+ .get_trip_temp = bcm2835_get_max_temp, -+ .get_trip_type = bcm2835_get_trip_type, -+ .get_mode = bcm2835_get_mode, ++ .get_temp = bcm2835_thermal_get_temp, ++ .get_trip_temp = bcm2835_thermal_get_max_temp, ++ .get_trip_type = bcm2835_thermal_get_trip_type, ++ .get_mode = bcm2835_thermal_get_mode, +}; + ++static int bcm2835_thermal_probe(struct platform_device *pdev) ++{ ++ struct device_node *fw_np; ++ struct rpi_firmware *fw; ++ struct thermal_zone_device *tz; ++ ++ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++/* Remove comment when booting without Device Tree is no longer supported ++ if (!fw_np) { ++ dev_err(&pdev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++*/ ++ fw = rpi_firmware_get(fw_np); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ tz = thermal_zone_device_register("bcm2835_thermal", 1, 0, fw, &ops, ++ NULL, 0, 0); ++ if (IS_ERR(tz)) { ++ dev_err(&pdev->dev, "Failed to register the thermal device\n"); ++ return PTR_ERR(tz); ++ } ++ ++ platform_set_drvdata(pdev, tz); ++ ++ return 0; ++} ++ ++static int bcm2835_thermal_remove(struct platform_device *pdev) ++{ ++ thermal_zone_device_unregister(platform_get_drvdata(pdev)); ++ ++ return 0; ++} ++ +static const struct of_device_id bcm2835_thermal_of_match_table[] = { + { .compatible = "brcm,bcm2835-thermal", }, + {}, @@ -103243,22 +107109,21 @@ index 0000000..3bc80f1 + .probe = bcm2835_thermal_probe, + .remove = bcm2835_thermal_remove, + .driver = { -+ .name = "bcm2835_thermal", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_thermal_of_match_table, -+ }, ++ .name = "bcm2835_thermal", ++ .of_match_table = bcm2835_thermal_of_match_table, ++ }, +}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Dorian Peake"); -+MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); -+ +module_platform_driver(bcm2835_thermal_driver); ++ ++MODULE_AUTHOR("Dorian Peake"); ++MODULE_AUTHOR("Noralf Trønnes"); ++MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); ++MODULE_LICENSE("GPL"); -From 320c58bca444bc390f7eccfebbb529fe8e98ed10 Mon Sep 17 00:00:00 2001 +From 0e7a0a423a5a6a1f125ea03eb0dc9d2fd9344a26 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:41:33 +0100 -Subject: [PATCH 019/204] Add Chris Boot's spi driver. +Subject: [PATCH 033/113] Add Chris Boot's spi driver. spi: bcm2708: add device tree support @@ -103292,6 +107157,10 @@ This does not affect behaviour under the current clock implementation. Also add a missing clk_disable_unprepare() in the probe error path. Signed-off-by: Noralf Tronnes + +spi-bcm2708: Increase timeout from 150ms to 1s + +See: https://github.com/raspberrypi/linux/issues/260 --- arch/arm/mach-bcm2708/Kconfig | 7 + arch/arm/mach-bcm2708/bcm2708.c | 53 ++++ @@ -103319,10 +107188,10 @@ index 4cbda0c..68e3706 100644 + Binds spidev driver to the SPI0 master endmenu diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 978aaff..31ad9da 100644 +index 30b77dc..3e5181f 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -34,6 +34,7 @@ +@@ -35,6 +35,7 @@ #include #include #include @@ -103330,7 +107199,7 @@ index 978aaff..31ad9da 100644 #include #include -@@ -505,6 +506,50 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -494,6 +495,50 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103381,16 +107250,16 @@ index 978aaff..31ad9da 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -655,6 +700,8 @@ void __init bcm2708_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -649,6 +694,8 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2708_spi_device); + bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -665,6 +712,12 @@ void __init bcm2708_init(void) +@@ -659,6 +706,12 @@ void __init bcm2708_init(void) } system_rev = boardrev; system_serial_low = serial; @@ -103402,9 +107271,9 @@ index 978aaff..31ad9da 100644 +#endif } - static void timer_set_mode(enum clock_event_mode mode, + static int timer_set_oneshot(struct clock_event_device *unused) diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 0e5c8e3..6874633 100644 +index c6341ba..bb86982 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -34,6 +34,7 @@ @@ -103415,7 +107284,7 @@ index 0e5c8e3..6874633 100644 #include #include -@@ -525,6 +526,50 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -510,6 +511,50 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103466,16 +107335,16 @@ index 0e5c8e3..6874633 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -675,6 +720,8 @@ void __init bcm2709_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); +@@ -666,6 +711,8 @@ void __init bcm2709_init(void) + bcm_register_device(&bcm2708_alsa_devices[i]); + } + bcm_register_device_dt(&bcm2708_spi_device); + bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -685,6 +732,12 @@ void __init bcm2709_init(void) +@@ -676,6 +723,12 @@ void __init bcm2709_init(void) } system_rev = boardrev; system_serial_low = serial; @@ -103489,19 +107358,19 @@ index 0e5c8e3..6874633 100644 #ifdef SYSTEM_TIMER diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 72b0590..ea5e5de 100644 +index 4887f31..47ab8ee 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -77,7 +77,7 @@ config SPI_ATMEL - +@@ -78,7 +78,7 @@ config SPI_ATMEL config SPI_BCM2835 tristate "BCM2835 SPI controller" + depends on GPIOLIB - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST depends on GPIOLIB help This selects a driver for the Broadcom BCM2835 SPI master. -@@ -87,6 +87,14 @@ config SPI_BCM2835 +@@ -88,6 +88,14 @@ config SPI_BCM2835 is for the regular SPI controller. Slave mode operation is not also not supported. @@ -103517,7 +107386,7 @@ index 72b0590..ea5e5de 100644 tristate "SPI controller driver for ADI Blackfin5xx" depends on BLACKFIN && !BF60x diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile -index d8cbf65..0dcd03d 100644 +index 6a7f6f9..11bb1e7 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o @@ -103530,7 +107399,7 @@ index d8cbf65..0dcd03d 100644 obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c new file mode 100644 -index 0000000..041b5e2 +index 0000000..5c0214e --- /dev/null +++ b/drivers/spi/spi-bcm2708.c @@ -0,0 +1,635 @@ @@ -103606,9 +107475,9 @@ index 0000000..041b5e2 +#define SPI_CS_CS_10 0x00000002 +#define SPI_CS_CS_01 0x00000001 + -+#define SPI_TIMEOUT_MS 150 ++#define SPI_TIMEOUT_MS 1000 + -+#define DRV_NAME "bcm2708_spi" ++#define DRV_NAME "bcm2708_spi" + +struct bcm2708_spi { + spinlock_t lock; @@ -104170,10 +108039,10 @@ index 0000000..041b5e2 +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From db4e6f4abd7eb95d3224be99d7f04c791f4ceb8d Mon Sep 17 00:00:00 2001 +From 3040b3426c57b28ae1d5c7f173fe3a7697d51009 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 020/204] Add Chris Boot's i2c driver +Subject: [PATCH 034/113] Add Chris Boot's i2c driver i2c-bcm2708: fixed baudrate @@ -104224,20 +108093,44 @@ Fix grabbing lock from atomic context in i2c driver - Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock. i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl + +i2c-bcm2708: Increase timeouts to allow larger transfers + +Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting +for completion. The default timeout is 1 second. + +See: https://github.com/raspberrypi/linux/issues/260 + +i2c-bcm2708/BCM270X_DT: Add support for I2C2 + +The third I2C bus (I2C2) is normally reserved for HDMI use. Careless +use of this bus can break an attached display - use with caution. + +It is recommended to disable accesses by VideoCore by setting +hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt. + +The interface is disabled by default - enable using the +i2c2_iknowwhatimdoing DT parameter. + +bcm2708-spi: Don't use static pin configuration with DT + +Also remove superfluous error checking - the SPI framework ensures the +validity of the chip_select value. --- arch/arm/mach-bcm2708/bcm2708.c | 51 ++++ arch/arm/mach-bcm2709/bcm2709.c | 51 ++++ drivers/i2c/busses/Kconfig | 21 +- drivers/i2c/busses/Makefile | 2 + - drivers/i2c/busses/i2c-bcm2708.c | 522 +++++++++++++++++++++++++++++++++++++++ - 5 files changed, 646 insertions(+), 1 deletion(-) + drivers/i2c/busses/i2c-bcm2708.c | 524 +++++++++++++++++++++++++++++++++++++++ + drivers/spi/spi-bcm2708.c | 11 +- + 6 files changed, 650 insertions(+), 10 deletions(-) create mode 100644 drivers/i2c/busses/i2c-bcm2708.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 31ad9da..26be516 100644 +index 3e5181f..7dc0cc7 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -83,6 +83,7 @@ static unsigned uart_clock = UART0_CLOCK; +@@ -84,6 +84,7 @@ static unsigned uart_clock = UART0_CLOCK; static unsigned disk_led_gpio = 16; static unsigned disk_led_active_low = 1; static unsigned reboot_part = 0; @@ -104245,7 +108138,7 @@ index 31ad9da..26be516 100644 static unsigned use_dt = 0; -@@ -550,6 +551,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { +@@ -539,6 +540,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { }; #endif @@ -104291,7 +108184,7 @@ index 31ad9da..26be516 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -702,6 +742,15 @@ void __init bcm2708_init(void) +@@ -696,6 +736,15 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2708_spi_device); @@ -104307,14 +108200,14 @@ index 31ad9da..26be516 100644 bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -893,3 +942,5 @@ module_param(uart_clock, uint, 0644); +@@ -878,3 +927,5 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); +module_param(vc_i2c_override, bool, 0644); +MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 6874633..50843df 100644 +index bb86982..7d70eeb 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -85,6 +85,7 @@ static unsigned uart_clock = UART0_CLOCK; @@ -104325,7 +108218,7 @@ index 6874633..50843df 100644 static unsigned use_dt = 0; -@@ -570,6 +571,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { +@@ -555,6 +556,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { }; #endif @@ -104371,7 +108264,7 @@ index 6874633..50843df 100644 static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; -@@ -722,6 +762,15 @@ void __init bcm2709_init(void) +@@ -713,6 +753,15 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2708_spi_device); @@ -104387,14 +108280,14 @@ index 6874633..50843df 100644 bcm_register_device_dt(&bcm2835_thermal_device); if (!use_dt) { -@@ -1061,3 +1110,5 @@ module_param(uart_clock, uint, 0644); +@@ -1052,3 +1101,5 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); +module_param(vc_i2c_override, bool, 0644); +MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 2255af2..5b0c772 100644 +index 08b8617..eb5f729 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" @@ -104433,7 +108326,7 @@ index 2255af2..5b0c772 100644 If you say yes to this option, support will be included for the BCM2835 I2C controller. diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index cdf941d..e0176d7 100644 +index 6df3b30..a58f550 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -2,6 +2,8 @@ @@ -104447,10 +108340,10 @@ index cdf941d..e0176d7 100644 diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c new file mode 100644 -index 0000000..8773203 +index 0000000..8b8762d --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,522 @@ +@@ -0,0 +1,524 @@ +/* + * Driver for Broadcom BCM2708 BSC Controllers + * @@ -104520,10 +108413,9 @@ index 0000000..8773203 +#define BSC_S_DONE 0x00000002 +#define BSC_S_TA 0x00000001 + -+#define I2C_TIMEOUT_MS 150 -+#define I2C_WAIT_LOOP_COUNT 40 ++#define I2C_WAIT_LOOP_COUNT 200 + -+#define DRV_NAME "bcm2708_i2c" ++#define DRV_NAME "bcm2708_i2c" + +static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); @@ -104758,7 +108650,7 @@ index 0000000..8773203 + goto error_timeout; + } + -+ ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); ++ ret = wait_for_completion_timeout(&bi->done, adap->timeout); + if (ret == 0) { + dev_err(&adap->dev, "transfer timed out\n"); + goto error_timeout; @@ -104860,8 +108752,11 @@ index 0000000..8773203 + case 1: + adap->class = I2C_CLASS_DDC; + break; ++ case 2: ++ adap->class = I2C_CLASS_DDC; ++ break; + default: -+ dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); ++ dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n"); + err = -ENXIO; + goto out_free_bi; + } @@ -104973,11 +108868,443 @@ index 0000000..8773203 +MODULE_AUTHOR("Chris Boot "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c +index 5c0214e..781c747 100644 +--- a/drivers/spi/spi-bcm2708.c ++++ b/drivers/spi/spi-bcm2708.c +@@ -386,14 +386,6 @@ static int bcm2708_spi_setup(struct spi_device *spi) + if (bs->stopping) + return -ESHUTDOWN; + +- if (!(spi->mode & SPI_NO_CS) && +- (spi->chip_select > spi->master->num_chipselect)) { +- dev_dbg(&spi->dev, +- "setup: invalid chipselect %u (%u defined)\n", +- spi->chip_select, spi->master->num_chipselect); +- return -EINVAL; +- } +- + state = spi->controller_state; + if (!state) { + state = kzalloc(sizeof(*state), GFP_KERNEL); +@@ -496,7 +488,8 @@ static int bcm2708_spi_probe(struct platform_device *pdev) + return PTR_ERR(clk); + } + +- bcm2708_init_pinmode(); ++ if (!pdev->dev.of_node) ++ bcm2708_init_pinmode(); + + master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + if (!master) { -From fb0599a8dc95e605fe75e510c39a99e77fe627f8 Mon Sep 17 00:00:00 2001 +From 1a6f52fa2ef4d7bc5a05f152162f42888b469252 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:27:06 +0200 +Subject: [PATCH 035/113] char: broadcom: Add vcio module +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add module for accessing the mailbox property channel through +/dev/vcio. Was previously in bcm2708-vcio. + +Signed-off-by: Noralf Trønnes +--- + drivers/char/broadcom/Kconfig | 6 ++ + drivers/char/broadcom/Makefile | 1 + + drivers/char/broadcom/vcio.c | 175 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 182 insertions(+) + create mode 100644 drivers/char/broadcom/vcio.c + +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index 2292ed2..5489f19 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -22,6 +22,12 @@ config BCM2708_VCMEM + help + Helper for videocore memory access and total size allocation. + ++config BCM_VCIO ++ tristate "Mailbox userspace access" ++ depends on BCM2835_MBOX ++ help ++ Gives access to the mailbox property channel from userspace. ++ + endif + + config BCM_VC_SM +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index 667d33e..14775c9 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -1,5 +1,6 @@ + obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ + obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o ++obj-$(CONFIG_BCM_VCIO) += vcio.o + obj-$(CONFIG_BCM_VC_SM) += vc_sm/ + + obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o +diff --git a/drivers/char/broadcom/vcio.c b/drivers/char/broadcom/vcio.c +new file mode 100644 +index 0000000..c19bc20 +--- /dev/null ++++ b/drivers/char/broadcom/vcio.c +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2015 Noralf Trønnes ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MBOX_CHAN_PROPERTY 8 ++ ++#define VCIO_IOC_MAGIC 100 ++#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) ++ ++static struct { ++ dev_t devt; ++ struct cdev cdev; ++ struct class *class; ++ struct rpi_firmware *fw; ++} vcio; ++ ++static int vcio_user_property_list(void *user) ++{ ++ u32 *buf, size; ++ int ret; ++ ++ /* The first 32-bit is the size of the buffer */ ++ if (copy_from_user(&size, user, sizeof(size))) ++ return -EFAULT; ++ ++ buf = kmalloc(size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ if (copy_from_user(buf, user, size)) { ++ kfree(buf); ++ return -EFAULT; ++ } ++ ++ /* Strip off protocol encapsulation */ ++ ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); ++ if (ret) { ++ kfree(buf); ++ return ret; ++ } ++ ++ buf[1] = RPI_FIRMWARE_STATUS_SUCCESS; ++ if (copy_to_user(user, buf, size)) ++ ret = -EFAULT; ++ ++ kfree(buf); ++ ++ return ret; ++} ++ ++static int vcio_device_open(struct inode *inode, struct file *file) ++{ ++ try_module_get(THIS_MODULE); ++ ++ return 0; ++} ++ ++static int vcio_device_release(struct inode *inode, struct file *file) ++{ ++ module_put(THIS_MODULE); ++ ++ return 0; ++} ++ ++static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, ++ unsigned long ioctl_param) ++{ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY: ++ return vcio_user_property_list((void *)ioctl_param); ++ default: ++ pr_err("unknown ioctl: %d\n", ioctl_num); ++ return -EINVAL; ++ } ++} ++ ++const struct file_operations vcio_fops = { ++ .unlocked_ioctl = vcio_device_ioctl, ++ .open = vcio_device_open, ++ .release = vcio_device_release, ++}; ++ ++static int __init vcio_init(void) ++{ ++ struct device_node *np; ++ static struct device *dev; ++ int ret; ++ ++ np = of_find_compatible_node(NULL, NULL, ++ "raspberrypi,bcm2835-firmware"); ++/* Uncomment this when we only boot with Device Tree ++ if (!of_device_is_available(np)) ++ return -ENODEV; ++*/ ++ vcio.fw = rpi_firmware_get(np); ++ if (!vcio.fw) ++ return -ENODEV; ++ ++ ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); ++ if (ret) { ++ pr_err("failed to allocate device number\n"); ++ return ret; ++ } ++ ++ cdev_init(&vcio.cdev, &vcio_fops); ++ vcio.cdev.owner = THIS_MODULE; ++ ret = cdev_add(&vcio.cdev, vcio.devt, 1); ++ if (ret) { ++ pr_err("failed to register device\n"); ++ goto err_unregister_chardev; ++ } ++ ++ /* ++ * Create sysfs entries ++ * 'bcm2708_vcio' is used for backwards compatibility so we don't break ++ * userspace. Raspian has a udev rule that changes the permissions. ++ */ ++ vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); ++ if (IS_ERR(vcio.class)) { ++ ret = PTR_ERR(vcio.class); ++ pr_err("failed to create class\n"); ++ goto err_cdev_del; ++ } ++ ++ dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); ++ if (IS_ERR(dev)) { ++ ret = PTR_ERR(dev); ++ pr_err("failed to create device\n"); ++ goto err_class_destroy; ++ } ++ ++ return 0; ++ ++err_class_destroy: ++ class_destroy(vcio.class); ++err_cdev_del: ++ cdev_del(&vcio.cdev); ++err_unregister_chardev: ++ unregister_chrdev_region(vcio.devt, 1); ++ ++ return ret; ++} ++module_init(vcio_init); ++ ++static void __exit vcio_exit(void) ++{ ++ device_destroy(vcio.class, vcio.devt); ++ class_destroy(vcio.class); ++ cdev_del(&vcio.cdev); ++ unregister_chrdev_region(vcio.devt, 1); ++} ++module_exit(vcio_exit); ++ ++MODULE_AUTHOR("Gray Girling"); ++MODULE_AUTHOR("Noralf Trønnes"); ++MODULE_DESCRIPTION("Mailbox userspace access"); ++MODULE_LICENSE("GPL"); + +From be94a3df5455d2d2848547fef93ca5912669977c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:21:20 +0200 +Subject: [PATCH 036/113] firmware: bcm2835: Add missing property tags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index 9d9efb7..d3933af 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -60,6 +60,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, + RPI_FIRMWARE_GET_TURBO = 0x00030009, + RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, ++ RPI_FIRMWARE_GET_STC = 0x0003000b, + RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, + RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, + RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, +@@ -69,10 +70,12 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, + RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, + RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, ++ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, + RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, + RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, + RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, + RPI_FIRMWARE_SET_TURBO = 0x00038009, ++ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, +@@ -86,6 +89,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, + RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, + RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, + RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, +@@ -95,6 +99,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, + RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, + RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, +@@ -103,6 +108,9 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, ++ ++ RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, + + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, + +From 67c97253ca03276086cebf0c93fe6c24544087e6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 26 Jun 2015 14:25:01 +0200 +Subject: [PATCH 037/113] firmware: bcm2835: Support ARCH_BCM270x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Support booting without Device Tree. +Turn on USB power. +Load driver early because of lacking support for deferred probing +in many drivers. + +Signed-off-by: Noralf Trønnes +--- + drivers/firmware/raspberrypi.c | 41 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 39 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c +index dd506cd3..b980d53 100644 +--- a/drivers/firmware/raspberrypi.c ++++ b/drivers/firmware/raspberrypi.c +@@ -28,6 +28,8 @@ struct rpi_firmware { + u32 enabled; + }; + ++static struct platform_device *g_pdev; ++ + static DEFINE_MUTEX(transaction_lock); + + static void response_callback(struct mbox_client *cl, void *msg) +@@ -183,6 +185,25 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) + } + } + ++static int raspberrypi_firmware_set_power(struct rpi_firmware *fw, ++ u32 domain, bool on) ++{ ++ struct { ++ u32 domain; ++ u32 on; ++ } packet; ++ int ret; ++ ++ packet.domain = domain; ++ packet.on = on; ++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POWER_STATE, ++ &packet, sizeof(packet)); ++ if (!ret && packet.on != on) ++ ret = -EINVAL; ++ ++ return ret; ++} ++ + static int rpi_firmware_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -207,9 +228,13 @@ static int rpi_firmware_probe(struct platform_device *pdev) + init_completion(&fw->c); + + platform_set_drvdata(pdev, fw); ++ g_pdev = pdev; + + rpi_firmware_print_firmware_revision(fw); + ++ if (raspberrypi_firmware_set_power(fw, 3, true)) ++ dev_err(dev, "failed to turn on USB power\n"); ++ + return 0; + } + +@@ -218,6 +243,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) + struct rpi_firmware *fw = platform_get_drvdata(pdev); + + mbox_free_channel(fw->chan); ++ g_pdev = NULL; + + return 0; + } +@@ -230,7 +256,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) + */ + struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) + { +- struct platform_device *pdev = of_find_device_by_node(firmware_node); ++ struct platform_device *pdev = g_pdev; + + if (!pdev) + return NULL; +@@ -253,7 +279,18 @@ static struct platform_driver rpi_firmware_driver = { + .probe = rpi_firmware_probe, + .remove = rpi_firmware_remove, + }; +-module_platform_driver(rpi_firmware_driver); ++ ++static int __init rpi_firmware_init(void) ++{ ++ return platform_driver_register(&rpi_firmware_driver); ++} ++subsys_initcall(rpi_firmware_init); ++ ++static void __init rpi_firmware_exit(void) ++{ ++ platform_driver_unregister(&rpi_firmware_driver); ++} ++module_exit(rpi_firmware_exit); + + MODULE_AUTHOR("Eric Anholt "); + MODULE_DESCRIPTION("Raspberry Pi firmware driver"); + +From 431856b45e7ed8fd40676902e48fe82569a89206 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 021/204] bcm2835: add v4l2 camera device +Subject: [PATCH 038/113] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -105215,16 +109542,46 @@ VIDIOC_TRY_FMT and VIDIOC_S_FMT tests were faling due to reporting V4L2_COLORSPACE_JPEG when the colour format wasn't V4L2_PIX_FMT_JPEG. Now reports V4L2_COLORSPACE_SMPTE170M for YUV formats. + +bcm2835 camera planar/packed stride length + +Added a field to the mmal_fmt struct used to compute the bytes per line +when using a particular format. This results in the correct stride being +calculated even when the format is planar. + +Signed-off-by: Garrett Wilson + +bcm2835: camera: check for scene not being found + +static analysis by cppcheck detected some potential NULL pointer +dereference issues: + +[drivers/media/platform/bcm2835/controls.c:854]: (error) Possible null + pointer dereference: scene + (and lines 858, 859 too) + +it is possible that scene is not found because of an invalue ctrl->val +and is therefore NULL and hence causing a null pointer dereference. + +Signed-off-by: Colin Ian King + +bcm2835: memcpy port data to m rather than rmsg + +static analysis by cppcheck detected a memcpy to rmsg which is +not actually initialized at that point. The memcpy should be copying +to variable m instead. + +Signed-off-by: Colin Ian King --- Documentation/video4linux/bcm2835-v4l2.txt | 60 + drivers/media/platform/Kconfig | 2 + drivers/media/platform/Makefile | 2 + drivers/media/platform/bcm2835/Kconfig | 25 + drivers/media/platform/bcm2835/Makefile | 5 + - drivers/media/platform/bcm2835/bcm2835-camera.c | 1828 +++++++++++++++++++++ + drivers/media/platform/bcm2835/bcm2835-camera.c | 1842 +++++++++++++++++++++ drivers/media/platform/bcm2835/bcm2835-camera.h | 126 ++ - drivers/media/platform/bcm2835/controls.c | 1322 +++++++++++++++ - drivers/media/platform/bcm2835/mmal-common.h | 52 + + drivers/media/platform/bcm2835/controls.c | 1324 +++++++++++++++ + drivers/media/platform/bcm2835/mmal-common.h | 53 + drivers/media/platform/bcm2835/mmal-encodings.h | 127 ++ drivers/media/platform/bcm2835/mmal-msg-common.h | 50 + drivers/media/platform/bcm2835/mmal-msg-format.h | 81 + @@ -105233,7 +109590,7 @@ Now reports V4L2_COLORSPACE_SMPTE170M for YUV formats. drivers/media/platform/bcm2835/mmal-parameters.h | 656 ++++++++ drivers/media/platform/bcm2835/mmal-vchiq.c | 1916 ++++++++++++++++++++++ drivers/media/platform/bcm2835/mmal-vchiq.h | 178 ++ - 17 files changed, 6941 insertions(+) + 17 files changed, 6958 insertions(+) create mode 100644 Documentation/video4linux/bcm2835-v4l2.txt create mode 100644 drivers/media/platform/bcm2835/Kconfig create mode 100644 drivers/media/platform/bcm2835/Makefile @@ -105317,7 +109674,7 @@ index 0000000..c585a8f + +$ v4l2-ctl --list-formats diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index 421f531..34ad311 100644 +index dc75694..2370af5 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -11,6 +11,8 @@ menuconfig V4L_PLATFORM_DRIVERS @@ -105330,7 +109687,7 @@ index 421f531..34ad311 100644 config VIDEO_VIA_CAMERA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index 8f85561..7b15c24 100644 +index efa0295..8c0b3b5 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,6 +2,8 @@ @@ -105386,10 +109743,10 @@ index 0000000..f17c79c +ccflags-$(CONFIG_VIDEO_BCM2835) += -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel -D__VCCOREVER__=0x04000000 diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c new file mode 100644 -index 0000000..eb4d831 +index 0000000..04a1711 --- /dev/null +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -0,0 +1,1828 @@ +@@ -0,0 +1,1842 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -105480,12 +109837,13 @@ index 0000000..eb4d831 +/* video formats */ +static struct mmal_fmt formats[] = { + { -+ .name = "4:2:0, packed YUV", ++ .name = "4:2:0, planar, YUV", + .fourcc = V4L2_PIX_FMT_YUV420, + .flags = 0, + .mmal = MMAL_ENCODING_I420, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { + .name = "4:2:2, packed, YUYV", @@ -105494,6 +109852,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_YUYV, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { + .name = "RGB24 (LE)", @@ -105502,6 +109861,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_BGR24, + .depth = 24, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 3, + }, + { + .name = "JPEG", @@ -105510,6 +109870,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_JPEG, + .depth = 8, + .mmal_component = MMAL_COMPONENT_IMAGE_ENCODE, ++ .ybbp = 0, + }, + { + .name = "H264", @@ -105518,6 +109879,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_H264, + .depth = 8, + .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, ++ .ybbp = 0, + }, + { + .name = "MJPEG", @@ -105526,6 +109888,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_MJPEG, + .depth = 8, + .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, ++ .ybbp = 0, + }, + { + .name = "4:2:2, packed, YVYU", @@ -105534,6 +109897,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_YVYU, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { + .name = "4:2:2, packed, VYUY", @@ -105542,6 +109906,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_VYUY, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { + .name = "4:2:2, packed, UYVY", @@ -105550,14 +109915,16 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_UYVY, + .depth = 16, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 2, + }, + { -+ .name = "4:2:0, packed, NV12", ++ .name = "4:2:0, planar, NV12", + .fourcc = V4L2_PIX_FMT_NV12, + .flags = 0, + .mmal = MMAL_ENCODING_NV12, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { + .name = "RGB24 (BE)", @@ -105566,22 +109933,25 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_RGB24, + .depth = 24, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 3, + }, + { -+ .name = "4:2:0, packed YVU", ++ .name = "4:2:0, planar, YVU", + .fourcc = V4L2_PIX_FMT_YVU420, + .flags = 0, + .mmal = MMAL_ENCODING_YV12, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { -+ .name = "4:2:0, packed, NV21", ++ .name = "4:2:0, planar, NV21", + .fourcc = V4L2_PIX_FMT_NV21, + .flags = 0, + .mmal = MMAL_ENCODING_NV21, + .depth = 12, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 1, + }, + { + .name = "RGB32 (BE)", @@ -105590,6 +109960,7 @@ index 0000000..eb4d831 + .mmal = MMAL_ENCODING_BGRA, + .depth = 32, + .mmal_component = MMAL_COMPONENT_CAMERA, ++ .ybbp = 4, + }, +}; + @@ -106163,7 +110534,7 @@ index 0000000..eb4d831 + a->fmt.width = preview_port->es.video.width; + a->fmt.height = preview_port->es.video.height; + a->fmt.pixelformat = V4L2_PIX_FMT_YUV420; -+ a->fmt.bytesperline = (preview_port->es.video.width * 3)>>1; ++ a->fmt.bytesperline = preview_port->es.video.width; + a->fmt.sizeimage = (preview_port->es.video.width * + preview_port->es.video.height * 3)>>1; + a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -106286,7 +110657,7 @@ index 0000000..eb4d831 + + v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1, + &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0); -+ f->fmt.pix.bytesperline = (f->fmt.pix.width * mfmt->depth)>>3; ++ f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; + + /* Image buffer has to be padded to allow for alignment, even though + * we then remove that padding before delivering the buffer. @@ -107352,10 +111723,10 @@ index 0000000..7fe9f65 +} diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c new file mode 100644 -index 0000000..3017b94 +index 0000000..f9f903f --- /dev/null +++ b/drivers/media/platform/bcm2835/controls.c -@@ -0,0 +1,1322 @@ +@@ -0,0 +1,1324 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -108203,6 +112574,8 @@ index 0000000..3017b94 + break; + } + } ++ if (!scene) ++ return -EINVAL; + if (i >= ARRAY_SIZE(scene_configs)) + return -EINVAL; + @@ -108680,10 +113053,10 @@ index 0000000..3017b94 +} diff --git a/drivers/media/platform/bcm2835/mmal-common.h b/drivers/media/platform/bcm2835/mmal-common.h new file mode 100644 -index 0000000..35698c8 +index 0000000..15788a1 --- /dev/null +++ b/drivers/media/platform/bcm2835/mmal-common.h -@@ -0,0 +1,52 @@ +@@ -0,0 +1,53 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -108716,6 +113089,7 @@ index 0000000..35698c8 + u32 mmal; + int depth; + u32 mmal_component; /* MMAL component index to be used to encode */ ++ u32 ybbp; /* depth of first Y plane for planar formats */ +}; + +/* buffer for one video frame */ @@ -110199,7 +114573,7 @@ index 0000000..aa0fd18 +}; diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c new file mode 100644 -index 0000000..76f249e +index 0000000..7813225 --- /dev/null +++ b/drivers/media/platform/bcm2835/mmal-vchiq.c @@ -0,0 +1,1916 @@ @@ -111056,7 +115430,7 @@ index 0000000..76f249e + sizeof(union mmal_es_specific_format)); + + m.u.port_info_set.format.extradata_size = port->format.extradata_size; -+ memcpy(rmsg->u.port_info_set.extradata, port->format.extradata, ++ memcpy(&m.u.port_info_set.extradata, port->format.extradata, + port->format.extradata_size); + + ret = send_synchronous_mmal_msg(instance, &m, @@ -112304,5226 +116678,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 55141e6e23fd7c2f2b98d6f472dd4e1f11fcdb50 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 23 Jan 2015 14:48:55 +0000 -Subject: [PATCH 022/204] scripts/dtc: Update to upstream version with overlay - patches - ---- - scripts/dtc/checks.c | 151 ++- - scripts/dtc/data.c | 12 +- - scripts/dtc/dtc-lexer.l | 70 +- - scripts/dtc/dtc-lexer.lex.c_shipped | 540 +++++----- - scripts/dtc/dtc-parser.tab.c_shipped | 1783 ++++++++++++++++------------------ - scripts/dtc/dtc-parser.tab.h_shipped | 116 ++- - scripts/dtc/dtc-parser.y | 158 +-- - scripts/dtc/dtc.c | 23 +- - scripts/dtc/dtc.h | 56 +- - scripts/dtc/flattree.c | 145 ++- - scripts/dtc/fstree.c | 16 +- - scripts/dtc/livetree.c | 4 +- - scripts/dtc/srcpos.c | 49 +- - scripts/dtc/srcpos.h | 15 +- - scripts/dtc/treesource.c | 14 +- - scripts/dtc/util.c | 18 +- - scripts/dtc/util.h | 4 +- - scripts/dtc/version_gen.h | 2 +- - 18 files changed, 1697 insertions(+), 1479 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index ee96a25..27f45f1 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -53,7 +53,7 @@ struct check { - void *data; - bool warn, error; - enum checkstatus status; -- int inprogress; -+ bool inprogress; - int num_prereqs; - struct check **prereq; - }; -@@ -113,6 +113,7 @@ static inline void check_msg(struct check *c, const char *fmt, ...) - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } -+ va_end(ap); - } - - #define FAIL(c, ...) \ -@@ -141,9 +142,9 @@ static void check_nodes_props(struct check *c, struct node *dt, struct node *nod - check_nodes_props(c, dt, child); - } - --static int run_check(struct check *c, struct node *dt) -+static bool run_check(struct check *c, struct node *dt) - { -- int error = 0; -+ bool error = false; - int i; - - assert(!c->inprogress); -@@ -151,11 +152,11 @@ static int run_check(struct check *c, struct node *dt) - if (c->status != UNCHECKED) - goto out; - -- c->inprogress = 1; -+ c->inprogress = true; - - for (i = 0; i < c->num_prereqs; i++) { - struct check *prq = c->prereq[i]; -- error |= run_check(prq, dt); -+ error = error || run_check(prq, dt); - if (prq->status != PASSED) { - c->status = PREREQ; - check_msg(c, "Failed prerequisite '%s'", -@@ -177,9 +178,9 @@ static int run_check(struct check *c, struct node *dt) - TRACE(c, "\tCompleted, status %d", c->status); - - out: -- c->inprogress = 0; -+ c->inprogress = false; - if ((c->status != PASSED) && (c->error)) -- error = 1; -+ error = true; - return error; - } - -@@ -457,22 +458,93 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -+ struct fixup *f, **fp; -+ struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; -+ int has_phandle_refs; -+ -+ has_phandle_refs = 0; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ has_phandle_refs = 1; -+ break; -+ } -+ -+ if (!has_phandle_refs) -+ return; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); -- if (! refnode) { -+ if (!refnode && !symbol_fixup_support) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ m->ref); - continue; - } - -- phandle = get_node_phandle(dt, refnode); -- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); -+ if (!refnode) { -+ /* allocate fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* search for an already existing fixup */ -+ for_each_fixup(dt, f) -+ if (strcmp(f->ref, m->ref) == 0) -+ break; -+ -+ /* no fixup found, add new */ -+ if (f == NULL) { -+ f = xmalloc(sizeof(*f)); -+ f->ref = m->ref; -+ f->entries = NULL; -+ f->next = NULL; -+ -+ /* add it to the tree */ -+ fp = &dt->fixups; -+ while (*fp) -+ fp = &(*fp)->next; -+ *fp = f; -+ } -+ -+ /* and now append fixup entry */ -+ fep = &f->entries; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ -+ /* mark the entry as unresolved */ -+ phandle = 0xdeadbeef; -+ } else { -+ phandle = get_node_phandle(dt, refnode); -+ -+ /* if it's a plugin, we need to record it */ -+ if (symbol_fixup_support && dt->is_plugin) { -+ -+ /* allocate a new local fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* append it to the local fixups */ -+ fep = &dt->local_fixups; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ } -+ } -+ -+ *((cell_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(phandle); - } -+ - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, - &duplicate_node_names, &explicit_phandles); -@@ -624,11 +696,11 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt, - if (!reg && !ranges) - return; - -- if ((node->parent->addr_cells == -1)) -+ if (node->parent->addr_cells == -1) - FAIL(c, "Relying on default #address-cells value for %s", - node->fullpath); - -- if ((node->parent->size_cells == -1)) -+ if (node->parent->size_cells == -1) - FAIL(c, "Relying on default #size-cells value for %s", - node->fullpath); - } -@@ -651,6 +723,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - -+static void check_auto_label_phandles(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct label *l; -+ struct symbol *s, **sp; -+ int has_label; -+ -+ if (!symbol_fixup_support) -+ return; -+ -+ has_label = 0; -+ for_each_label(node->labels, l) { -+ has_label = 1; -+ break; -+ } -+ -+ if (!has_label) -+ return; -+ -+ /* force allocation of a phandle for this node */ -+ (void)get_node_phandle(dt, node); -+ -+ /* add the symbol */ -+ for_each_label(node->labels, l) { -+ -+ s = xmalloc(sizeof(*s)); -+ s->label = l; -+ s->node = node; -+ s->next = NULL; -+ -+ /* add it to the symbols list */ -+ sp = &dt->symbols; -+ while (*sp) -+ sp = &((*sp)->next); -+ *sp = s; -+ } -+} -+NODE_WARNING(auto_label_phandles, NULL); -+ - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -669,6 +780,8 @@ static struct check *check_table[] = { - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -+ &auto_label_phandles, -+ - &always_fail, - }; - -@@ -706,15 +819,15 @@ static void disable_warning_error(struct check *c, bool warn, bool error) - c->error = c->error && !error; - } - --void parse_checks_option(bool warn, bool error, const char *optarg) -+void parse_checks_option(bool warn, bool error, const char *arg) - { - int i; -- const char *name = optarg; -+ const char *name = arg; - bool enable = true; - -- if ((strncmp(optarg, "no-", 3) == 0) -- || (strncmp(optarg, "no_", 3) == 0)) { -- name = optarg + 3; -+ if ((strncmp(arg, "no-", 3) == 0) -+ || (strncmp(arg, "no_", 3) == 0)) { -+ name = arg + 3; - enable = false; - } - -@@ -733,7 +846,7 @@ void parse_checks_option(bool warn, bool error, const char *optarg) - die("Unrecognized check name \"%s\"\n", name); - } - --void process_checks(int force, struct boot_info *bi) -+void process_checks(bool force, struct boot_info *bi) - { - struct node *dt = bi->dt; - int i; -diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c -index 4a40c5b..8cae237 100644 ---- a/scripts/dtc/data.c -+++ b/scripts/dtc/data.c -@@ -74,7 +74,7 @@ struct data data_copy_escape_string(const char *s, int len) - struct data d; - char *q; - -- d = data_grow_for(empty_data, strlen(s)+1); -+ d = data_grow_for(empty_data, len + 1); - - q = d.val; - while (i < len) { -@@ -250,20 +250,20 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref) - return data_append_markers(d, m); - } - --int data_is_one_string(struct data d) -+bool data_is_one_string(struct data d) - { - int i; - int len = d.len; - - if (len == 0) -- return 0; -+ return false; - - for (i = 0; i < len-1; i++) - if (d.val[i] == '\0') -- return 0; -+ return false; - - if (d.val[len-1] != '\0') -- return 0; -+ return false; - -- return 1; -+ return true; - } -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 3b41bfc..dd44ba2 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -20,7 +20,6 @@ - - %option noyywrap nounput noinput never-interactive - --%x INCLUDE - %x BYTESTRING - %x PROPNODENAME - %s V1 -@@ -40,6 +39,7 @@ LINECOMMENT "//".*\n - #include "dtc-parser.tab.h" - - YYLTYPE yylloc; -+extern bool treesource_error; - - /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ - #define YY_USER_ACTION \ -@@ -61,7 +61,8 @@ static int dts_version = 1; - BEGIN(V1); \ - - static void push_input_file(const char *filename); --static int pop_input_file(void); -+static bool pop_input_file(void); -+static void lexical_error(const char *fmt, ...); - %} - - %% -@@ -75,11 +76,11 @@ static int pop_input_file(void); - char *line, *tmp, *fn; - /* skip text before line # */ - line = yytext; -- while (!isdigit(*line)) -+ while (!isdigit((unsigned char)*line)) - line++; - /* skip digits in line # */ - tmp = line; -- while (!isspace(*tmp)) -+ while (!isspace((unsigned char)*tmp)) - tmp++; - /* "NULL"-terminate line # */ - *tmp = '\0'; -@@ -112,6 +113,11 @@ static int pop_input_file(void); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -@@ -146,15 +152,42 @@ static int pop_input_file(void); - } - - ([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { -- yylval.literal = xstrdup(yytext); -- DPRINT("Literal: '%s'\n", yylval.literal); -+ char *e; -+ DPRINT("Integer Literal: '%s'\n", yytext); -+ -+ errno = 0; -+ yylval.integer = strtoull(yytext, &e, 0); -+ -+ assert(!(*e) || !e[strspn(e, "UL")]); -+ -+ if (errno == ERANGE) -+ lexical_error("Integer literal '%s' out of range", -+ yytext); -+ else -+ /* ERANGE is the only strtoull error triggerable -+ * by strings matching the pattern */ -+ assert(errno == 0); - return DT_LITERAL; - } - - <*>{CHAR_LITERAL} { -- yytext[yyleng-1] = '\0'; -- yylval.literal = xstrdup(yytext+1); -- DPRINT("Character literal: %s\n", yylval.literal); -+ struct data d; -+ DPRINT("Character literal: %s\n", yytext); -+ -+ d = data_copy_escape_string(yytext+1, yyleng-2); -+ if (d.len == 1) { -+ lexical_error("Empty character literal"); -+ yylval.integer = 0; -+ return DT_CHAR_LITERAL; -+ } -+ -+ yylval.integer = (unsigned char)d.val[0]; -+ -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ - return DT_CHAR_LITERAL; - } - -@@ -164,7 +197,7 @@ static int pop_input_file(void); - return DT_REF; - } - --<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ -+<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); -@@ -238,13 +271,24 @@ static void push_input_file(const char *filename) - } - - --static int pop_input_file(void) -+static bool pop_input_file(void) - { - if (srcfile_pop() == 0) -- return 0; -+ return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - -- return 1; -+ return true; -+} -+ -+static void lexical_error(const char *fmt, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, fmt); -+ srcpos_verror(&yylloc, "Lexical error", fmt, ap); -+ va_end(ap); -+ -+ treesource_error = true; - } -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 2d30f41..1518525 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -372,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -381,25 +381,26 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[161] = -+static yyconst flex_int16_t yy_accept[166] = - { 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 31, 29, 18, 18, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 29, 29, 15, 16, -- 16, 29, 16, 10, 10, 18, 26, 0, 3, 0, -- 27, 12, 0, 0, 11, 0, 0, 0, 0, 0, -- 0, 0, 21, 23, 25, 24, 22, 0, 9, 28, -- 0, 0, 0, 14, 14, 16, 16, 16, 10, 10, -- 10, 0, 12, 0, 11, 0, 0, 0, 20, 0, -- 0, 0, 0, 0, 0, 0, 0, 16, 10, 10, -- 10, 0, 19, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 16, 13, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 16, 6, 0, 0, 0, 0, 0, -- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, -- 4, 17, 0, 0, 2, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -- 0, 0, 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - - static yyconst flex_int32_t yy_ec[256] = -@@ -415,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -434,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static yyconst flex_int32_t yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 1 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[175] = -+static yyconst flex_int16_t yy_base[180] = - { 0, -- 0, 385, 378, 40, 41, 383, 72, 382, 34, 44, -- 388, 393, 61, 117, 368, 116, 115, 115, 115, 48, -- 367, 107, 368, 339, 127, 120, 0, 147, 393, 0, -- 127, 0, 133, 156, 168, 153, 393, 125, 393, 380, -- 393, 0, 369, 127, 393, 160, 371, 377, 347, 21, -- 343, 346, 393, 393, 393, 393, 393, 359, 393, 393, -- 183, 343, 339, 393, 356, 0, 183, 340, 187, 348, -- 347, 0, 0, 0, 178, 359, 195, 365, 354, 326, -- 332, 325, 334, 328, 204, 326, 331, 324, 393, 335, -- 150, 311, 343, 342, 315, 322, 340, 179, 313, 207, -- -- 319, 316, 317, 393, 337, 333, 305, 302, 311, 301, -- 310, 190, 338, 337, 393, 307, 322, 301, 305, 277, -- 208, 311, 307, 278, 271, 270, 248, 246, 213, 130, -- 393, 393, 263, 235, 207, 221, 218, 229, 213, 213, -- 206, 234, 218, 210, 208, 193, 219, 393, 223, 204, -- 176, 157, 393, 393, 120, 106, 97, 119, 393, 393, -- 245, 251, 259, 263, 267, 273, 280, 284, 292, 300, -- 304, 310, 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[175] = -+static yyconst flex_int16_t yy_def[180] = - { 0, -- 160, 1, 1, 1, 1, 5, 160, 7, 1, 1, -- 160, 160, 160, 160, 160, 161, 162, 163, 160, 160, -- 160, 160, 164, 160, 160, 160, 165, 164, 160, 166, -- 167, 166, 166, 160, 160, 160, 160, 161, 160, 161, -- 160, 168, 160, 163, 160, 163, 169, 170, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 164, 160, 160, -- 160, 160, 160, 160, 164, 166, 167, 166, 160, 160, -- 160, 171, 168, 172, 163, 169, 169, 170, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 166, 160, 160, -- 171, 172, 160, 160, 160, 160, 160, 160, 160, 160, -- -- 160, 160, 166, 160, 160, 160, 160, 160, 160, 160, -- 160, 173, 160, 166, 160, 160, 160, 160, 160, 160, -- 173, 160, 173, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 174, 160, 160, 160, 174, 160, 174, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 0, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[440] = -+static yyconst flex_int16_t yy_nxt[449] = - { 0, -- 12, 13, 14, 13, 15, 16, 12, 17, 18, 12, -- 12, 12, 19, 12, 12, 12, 12, 20, 21, 22, -- 23, 23, 23, 23, 23, 12, 12, 23, 23, 23, -- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -- 23, 23, 23, 12, 24, 12, 25, 34, 35, 35, -- 25, 81, 26, 26, 27, 27, 27, 34, 35, 35, -- 82, 28, 36, 36, 36, 53, 54, 29, 28, 28, -- 28, 28, 12, 13, 14, 13, 15, 16, 30, 17, -- 18, 30, 30, 30, 26, 30, 30, 30, 12, 20, -- 21, 22, 31, 31, 31, 31, 31, 32, 12, 31, -- -- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -- 31, 31, 31, 31, 31, 12, 24, 12, 36, 36, -- 36, 39, 41, 45, 47, 56, 57, 48, 61, 47, -- 39, 159, 48, 66, 61, 45, 66, 66, 66, 158, -- 46, 40, 49, 59, 50, 157, 51, 49, 52, 50, -- 40, 63, 46, 52, 36, 36, 36, 156, 43, 62, -- 65, 65, 65, 59, 136, 68, 137, 65, 75, 69, -- 69, 69, 70, 71, 65, 65, 65, 65, 70, 71, -- 72, 69, 69, 69, 61, 46, 45, 155, 154, 66, -- 70, 71, 66, 66, 66, 122, 85, 85, 85, 59, -- -- 69, 69, 69, 46, 77, 100, 109, 93, 100, 70, -- 71, 110, 112, 122, 129, 123, 153, 85, 85, 85, -- 135, 135, 135, 148, 148, 160, 135, 135, 135, 152, -- 142, 142, 142, 123, 143, 142, 142, 142, 151, 143, -- 150, 146, 145, 149, 149, 38, 38, 38, 38, 38, -- 38, 38, 38, 42, 144, 141, 140, 42, 42, 44, -- 44, 44, 44, 44, 44, 44, 44, 58, 58, 58, -- 58, 64, 139, 64, 66, 138, 134, 66, 133, 66, -- 66, 67, 132, 131, 67, 67, 67, 67, 73, 130, -- 73, 73, 76, 76, 76, 76, 76, 76, 76, 76, -- -- 78, 78, 78, 78, 78, 78, 78, 78, 91, 160, -- 91, 92, 129, 92, 92, 128, 92, 92, 121, 121, -- 121, 121, 121, 121, 121, 121, 147, 147, 147, 147, -- 147, 147, 147, 147, 127, 126, 125, 124, 61, 61, -- 120, 119, 118, 117, 116, 115, 47, 114, 110, 113, -- 111, 108, 107, 106, 48, 105, 104, 89, 103, 102, -- 101, 99, 98, 97, 96, 95, 94, 79, 77, 90, -- 89, 88, 59, 87, 86, 59, 84, 83, 80, 79, -- 77, 74, 160, 60, 59, 55, 37, 160, 33, 25, -- 26, 25, 11, 160, 160, 160, 160, 160, 160, 160, -- -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160 -+ 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, -+ 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, -+ 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, -+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[440] = -+static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 4, 9, 9, 9, -- 10, 50, 4, 5, 5, 5, 5, 10, 10, 10, -- 50, 5, 13, 13, 13, 20, 20, 5, 5, 5, -- 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- -- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, -- 14, 16, 17, 18, 19, 22, 22, 19, 25, 26, -- 38, 158, 26, 31, 33, 44, 31, 31, 31, 157, -- 18, 16, 19, 31, 19, 156, 19, 26, 19, 26, -- 38, 26, 44, 26, 36, 36, 36, 155, 17, 25, -- 28, 28, 28, 28, 130, 33, 130, 28, 46, 34, -- 34, 34, 91, 91, 28, 28, 28, 28, 34, 34, -- 34, 35, 35, 35, 61, 46, 75, 152, 151, 67, -- 35, 35, 67, 67, 67, 112, 61, 61, 61, 67, -- -- 69, 69, 69, 75, 77, 85, 98, 77, 100, 69, -- 69, 98, 100, 121, 129, 112, 150, 85, 85, 85, -- 135, 135, 135, 143, 147, 149, 129, 129, 129, 146, -- 138, 138, 138, 121, 138, 142, 142, 142, 145, 142, -- 144, 141, 140, 143, 147, 161, 161, 161, 161, 161, -- 161, 161, 161, 162, 139, 137, 136, 162, 162, 163, -- 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, -- 164, 165, 134, 165, 166, 133, 128, 166, 127, 166, -- 166, 167, 126, 125, 167, 167, 167, 167, 168, 124, -- 168, 168, 169, 169, 169, 169, 169, 169, 169, 169, -- -- 170, 170, 170, 170, 170, 170, 170, 170, 171, 123, -- 171, 172, 122, 172, 172, 120, 172, 172, 173, 173, -- 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, -- 174, 174, 174, 174, 119, 118, 117, 116, 114, 113, -- 111, 110, 109, 108, 107, 106, 105, 103, 102, 101, -- 99, 97, 96, 95, 94, 93, 92, 90, 88, 87, -- 86, 84, 83, 82, 81, 80, 79, 78, 76, 71, -- 70, 68, 65, 63, 62, 58, 52, 51, 49, 48, -- 47, 43, 40, 24, 23, 21, 15, 11, 8, 6, -- 3, 2, 160, 160, 160, 160, 160, 160, 160, 160, -- -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -- 160, 160, 160, 160, 160, 160, 160, 160, 160 -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ -+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, -+ 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -+ -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -631,13 +634,13 @@ char *yytext; - - - -- --#line 38 "dtc-lexer.l" -+#line 37 "dtc-lexer.l" - #include "dtc.h" - #include "srcpos.h" - #include "dtc-parser.tab.h" - - YYLTYPE yylloc; -+extern bool treesource_error; - - /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ - #define YY_USER_ACTION \ -@@ -659,14 +662,14 @@ static int dts_version = 1; - BEGIN(V1); \ - - static void push_input_file(const char *filename); --static int pop_input_file(void); --#line 664 "dtc-lexer.lex.c" -+static bool pop_input_file(void); -+static void lexical_error(const char *fmt, ...); -+#line 668 "dtc-lexer.lex.c" - - #define INITIAL 0 --#define INCLUDE 1 --#define BYTESTRING 2 --#define PROPNODENAME 3 --#define V1 4 -+#define BYTESTRING 1 -+#define PROPNODENAME 2 -+#define V1 3 - - #ifndef YY_NO_UNISTD_H - /* Special case for "unistd.h", since it is non-ANSI. We include it way -@@ -852,9 +855,9 @@ YY_DECL - register char *yy_cp, *yy_bp; - register int yy_act; - --#line 67 "dtc-lexer.l" -+#line 68 "dtc-lexer.l" - --#line 858 "dtc-lexer.lex.c" -+#line 861 "dtc-lexer.lex.c" - - if ( !(yy_init) ) - { -@@ -908,13 +911,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 161 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 160 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -937,7 +940,7 @@ do_action: /* This label is used only to access EOF actions. */ - case 1: - /* rule 1 can match eol */ - YY_RULE_SETUP --#line 68 "dtc-lexer.l" -+#line 69 "dtc-lexer.l" - { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; -@@ -947,16 +950,16 @@ YY_RULE_SETUP - case 2: - /* rule 2 can match eol */ - YY_RULE_SETUP --#line 74 "dtc-lexer.l" -+#line 75 "dtc-lexer.l" - { - char *line, *tmp, *fn; - /* skip text before line # */ - line = yytext; -- while (!isdigit(*line)) -+ while (!isdigit((unsigned char)*line)) - line++; - /* skip digits in line # */ - tmp = line; -- while (!isspace(*tmp)) -+ while (!isspace((unsigned char)*tmp)) - tmp++; - /* "NULL"-terminate line # */ - *tmp = '\0'; -@@ -970,11 +973,10 @@ YY_RULE_SETUP - } - YY_BREAK - case YY_STATE_EOF(INITIAL): --case YY_STATE_EOF(INCLUDE): - case YY_STATE_EOF(BYTESTRING): - case YY_STATE_EOF(PROPNODENAME): - case YY_STATE_EOF(V1): --#line 95 "dtc-lexer.l" -+#line 96 "dtc-lexer.l" - { - if (!pop_input_file()) { - yyterminate(); -@@ -984,7 +986,7 @@ case YY_STATE_EOF(V1): - case 3: - /* rule 3 can match eol */ - YY_RULE_SETUP --#line 101 "dtc-lexer.l" -+#line 102 "dtc-lexer.l" - { - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, -@@ -994,7 +996,7 @@ YY_RULE_SETUP - YY_BREAK - case 4: - YY_RULE_SETUP --#line 108 "dtc-lexer.l" -+#line 109 "dtc-lexer.l" - { - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; -@@ -1004,25 +1006,33 @@ YY_RULE_SETUP - YY_BREAK - case 5: - YY_RULE_SETUP --#line 115 "dtc-lexer.l" -+#line 116 "dtc-lexer.l" -+{ -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 121 "dtc-lexer.l" - { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 121 "dtc-lexer.l" -+#line 127 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 127 "dtc-lexer.l" -+#line 133 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1030,9 +1040,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 134 "dtc-lexer.l" -+#line 140 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1040,9 +1050,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 141 "dtc-lexer.l" -+#line 147 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1050,38 +1060,65 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 148 "dtc-lexer.l" -+#line 154 "dtc-lexer.l" - { -- yylval.literal = xstrdup(yytext); -- DPRINT("Literal: '%s'\n", yylval.literal); -+ char *e; -+ DPRINT("Integer Literal: '%s'\n", yytext); -+ -+ errno = 0; -+ yylval.integer = strtoull(yytext, &e, 0); -+ -+ assert(!(*e) || !e[strspn(e, "UL")]); -+ -+ if (errno == ERANGE) -+ lexical_error("Integer literal '%s' out of range", -+ yytext); -+ else -+ /* ERANGE is the only strtoull error triggerable -+ * by strings matching the pattern */ -+ assert(errno == 0); - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 154 "dtc-lexer.l" -+#line 173 "dtc-lexer.l" - { -- yytext[yyleng-1] = '\0'; -- yylval.literal = xstrdup(yytext+1); -- DPRINT("Character literal: %s\n", yylval.literal); -+ struct data d; -+ DPRINT("Character literal: %s\n", yytext); -+ -+ d = data_copy_escape_string(yytext+1, yyleng-2); -+ if (d.len == 1) { -+ lexical_error("Empty character literal"); -+ yylval.integer = 0; -+ return DT_CHAR_LITERAL; -+ } -+ -+ yylval.integer = (unsigned char)d.val[0]; -+ -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 161 "dtc-lexer.l" -+#line 194 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 167 "dtc-lexer.l" -+#line 200 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1089,27 +1126,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 174 "dtc-lexer.l" -+#line 207 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 180 "dtc-lexer.l" -+#line 213 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 186 "dtc-lexer.l" -+#line 219 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1118,75 +1155,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 194 "dtc-lexer.l" -+#line 227 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 199 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 200 "dtc-lexer.l" --/* eat C-style comments */ -+#line 232 "dtc-lexer.l" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 201 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 233 "dtc-lexer.l" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 203 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 234 "dtc-lexer.l" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 204 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 236 "dtc-lexer.l" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 205 "dtc-lexer.l" --{ return DT_LE; }; -+#line 237 "dtc-lexer.l" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 206 "dtc-lexer.l" --{ return DT_GE; }; -+#line 238 "dtc-lexer.l" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 207 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 239 "dtc-lexer.l" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 208 "dtc-lexer.l" --{ return DT_NE; }; -+#line 240 "dtc-lexer.l" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 209 "dtc-lexer.l" --{ return DT_AND; }; -+#line 241 "dtc-lexer.l" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 210 "dtc-lexer.l" --{ return DT_OR; }; -+#line 242 "dtc-lexer.l" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 212 "dtc-lexer.l" -+#line 243 "dtc-lexer.l" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 245 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1202,12 +1239,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 227 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1211 "dtc-lexer.lex.c" -+#line 1248 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1499,7 +1536,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 161 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1527,11 +1564,11 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 161 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 160); -+ yy_is_jam = (yy_current_state == 165); - - return yy_is_jam ? 0 : yy_current_state; - } -@@ -2166,7 +2203,7 @@ void yyfree (void * ptr ) - - #define YYTABLES_NAME "yytables" - --#line 227 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - - - -@@ -2182,14 +2219,25 @@ static void push_input_file(const char *filename) - } - - --static int pop_input_file(void) -+static bool pop_input_file(void) - { - if (srcfile_pop() == 0) -- return 0; -+ return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - -- return 1; -+ return true; -+} -+ -+static void lexical_error(const char *fmt, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, fmt); -+ srcpos_verror(&yylloc, "Lexical error", fmt, ap); -+ va_end(ap); -+ -+ treesource_error = true; - } - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index c8769d5..1938d20 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.7.12-4996. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison implementation for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,7 +26,7 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "2.7.12-4996" -+#define YYBISON_VERSION "3.0.2" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -62,34 +62,32 @@ - - - /* Copy the first part of user declarations. */ --/* Line 371 of yacc.c */ --#line 21 "dtc-parser.y" -+#line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include -+#include - - #include "dtc.h" - #include "srcpos.h" - --YYLTYPE yylloc; -- - extern int yylex(void); --extern void print_error(char const *fmt, ...); - extern void yyerror(char const *s); -+#define ERROR(loc, ...) \ -+ do { \ -+ srcpos_error((loc), "Error", __VA_ARGS__); \ -+ treesource_error = true; \ -+ } while (0) - - extern struct boot_info *the_boot_info; --extern int treesource_error; -- --static unsigned long long eval_literal(const char *s, int base, int bits); --static unsigned char eval_char_literal(const char *s); -+extern bool treesource_error; - --/* Line 371 of yacc.c */ --#line 87 "dtc-parser.tab.c" -+#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ - --# ifndef YY_NULL -+# ifndef YY_NULLPTR - # if defined __cplusplus && 201103L <= __cplusplus --# define YY_NULL nullptr -+# define YY_NULLPTR nullptr - # else --# define YY_NULL 0 -+# define YY_NULLPTR 0 - # endif - # endif - -@@ -105,7 +103,7 @@ static unsigned char eval_char_literal(const char *s); - by #include "dtc-parser.tab.h". */ - #ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED - # define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Enabling traces. */ -+/* Debug traces. */ - #ifndef YYDEBUG - # define YYDEBUG 0 - #endif -@@ -113,48 +111,45 @@ static unsigned char eval_char_literal(const char *s); - extern int yydebug; - #endif - --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BASE = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { --/* Line 387 of yacc.c */ --#line 40 "dtc-parser.y" -+#line 39 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; -- char *literal; - char *labelref; -- unsigned int cbase; - uint8_t byte; - struct data data; - -@@ -169,38 +164,38 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - -- --/* Line 387 of yacc.c */ --#line 176 "dtc-parser.tab.c" --} YYSTYPE; -+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --extern YYSTYPE yylval; -- --#ifdef YYPARSE_PARAM --#if defined __STDC__ || defined __cplusplus --int yyparse (void *YYPARSE_PARAM); --#else --int yyparse (); -+/* Location type. */ -+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE -+{ -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+}; -+# define YYLTYPE_IS_DECLARED 1 -+# define YYLTYPE_IS_TRIVIAL 1 - #endif --#else /* ! YYPARSE_PARAM */ --#if defined __STDC__ || defined __cplusplus -+ -+ -+extern YYSTYPE yylval; -+extern YYLTYPE yylloc; - int yyparse (void); --#else --int yyparse (); --#endif --#endif /* ! YYPARSE_PARAM */ - - #endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ - - /* Copy the second part of user declarations. */ - --/* Line 390 of yacc.c */ --#line 204 "dtc-parser.tab.c" -+#line 199 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -214,11 +209,8 @@ typedef unsigned char yytype_uint8; - - #ifdef YYTYPE_INT8 - typedef YYTYPE_INT8 yytype_int8; --#elif (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --typedef signed char yytype_int8; - #else --typedef short int yytype_int8; -+typedef signed char yytype_int8; - #endif - - #ifdef YYTYPE_UINT16 -@@ -238,8 +230,7 @@ typedef short int yytype_int16; - # define YYSIZE_T __SIZE_TYPE__ - # elif defined size_t - # define YYSIZE_T size_t --# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# elif ! defined YYSIZE_T - # include /* INFRINGES ON USER NAME SPACE */ - # define YYSIZE_T size_t - # else -@@ -261,11 +252,30 @@ typedef short int yytype_int16; - # endif - #endif - --#ifndef __attribute__ --/* This feature is available in gcc versions 2.5 and later. */ --# if (! defined __GNUC__ || __GNUC__ < 2 \ -- || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) --# define __attribute__(Spec) /* empty */ -+#ifndef YY_ATTRIBUTE -+# if (defined __GNUC__ \ -+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ -+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -+# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -+# else -+# define YY_ATTRIBUTE(Spec) /* empty */ -+# endif -+#endif -+ -+#ifndef YY_ATTRIBUTE_PURE -+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -+#endif -+ -+#ifndef YY_ATTRIBUTE_UNUSED -+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -+#endif -+ -+#if !defined _Noreturn \ -+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -+# if defined _MSC_VER && 1200 <= _MSC_VER -+# define _Noreturn __declspec (noreturn) -+# else -+# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) - # endif - #endif - -@@ -276,25 +286,26 @@ typedef short int yytype_int16; - # define YYUSE(E) /* empty */ - #endif - -- --/* Identity function, used to suppress warnings about constant conditions. */ --#ifndef lint --# define YYID(N) (N) --#else --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static int --YYID (int yyi) -+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -+/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ -+ _Pragma ("GCC diagnostic push") \ -+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ -+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ -+ _Pragma ("GCC diagnostic pop") - #else --static int --YYID (yyi) -- int yyi; -+# define YY_INITIAL_VALUE(Value) Value - #endif --{ -- return yyi; --} -+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END -+#endif -+#ifndef YY_INITIAL_VALUE -+# define YY_INITIAL_VALUE(Value) /* Nothing. */ - #endif - -+ - #if ! defined yyoverflow || YYERROR_VERBOSE - - /* The parser invokes alloca or malloc; define the necessary symbols. */ -@@ -312,8 +323,7 @@ YYID (yyi) - # define alloca _alloca - # else - # define YYSTACK_ALLOC alloca --# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS - # include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ - # ifndef EXIT_SUCCESS -@@ -325,8 +335,8 @@ YYID (yyi) - # endif - - # ifdef YYSTACK_ALLOC -- /* Pacify GCC's `empty if-body' warning. */ --# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -+ /* Pacify GCC's 'empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) - # ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely -@@ -342,7 +352,7 @@ YYID (yyi) - # endif - # if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ -- && (defined YYFREE || defined free))) -+ && (defined YYFREE || defined free))) - # include /* INFRINGES ON USER NAME SPACE */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 -@@ -350,15 +360,13 @@ YYID (yyi) - # endif - # ifndef YYMALLOC - # define YYMALLOC malloc --# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined malloc && ! defined EXIT_SUCCESS - void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif - # ifndef YYFREE - # define YYFREE free --# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined free && ! defined EXIT_SUCCESS - void free (void *); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif -@@ -368,13 +376,15 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ - - #if (! defined yyoverflow \ - && (! defined __cplusplus \ -- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - - /* A type that is properly aligned for any stack member. */ - union yyalloc - { - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -+ YYLTYPE yyls_alloc; - }; - - /* The size of the maximum gap between one aligned stack and the next. */ -@@ -383,8 +393,8 @@ union yyalloc - /* The size of an array large to enough to hold all stacks, each with - N elements. */ - # define YYSTACK_BYTES(N) \ -- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ -- + YYSTACK_GAP_MAXIMUM) -+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ -+ + 2 * YYSTACK_GAP_MAXIMUM) - - # define YYCOPY_NEEDED 1 - -@@ -393,16 +403,16 @@ union yyalloc - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ --# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -- do \ -- { \ -- YYSIZE_T yynewbytes; \ -- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -- Stack = &yyptr->Stack_alloc; \ -- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -- yyptr += yynewbytes / sizeof (*yyptr); \ -- } \ -- while (YYID (0)) -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) - - #endif - -@@ -421,7 +431,7 @@ union yyalloc - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ -- while (YYID (0)) -+ while (0) - # endif - # endif - #endif /* !YYCOPY_NEEDED */ -@@ -429,25 +439,27 @@ union yyalloc - /* YYFINAL -- State number of the termination state. */ - #define YYFINAL 4 - /* YYLAST -- Last index in YYTABLE. */ --#define YYLAST 133 -+#define YYLAST 135 - - /* YYNTOKENS -- Number of terminals. */ - #define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 29 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 79 --/* YYNRULES -- Number of states. */ --#define YYNSTATES 141 -+#define YYNRULES 81 -+/* YYNSTATES -- Number of states. */ -+#define YYNSTATES 144 - --/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned -+ by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 - #define YYMAXUTOK 279 - --#define YYTRANSLATE(YYX) \ -+#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - --/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM -+ as returned by yylex, without out-of-bounds checking. */ - static const yytype_uint8 yytranslate[] = - { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -481,63 +493,18 @@ static const yytype_uint8 yytranslate[] = - }; - - #if YYDEBUG --/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -- YYRHS. */ --static const yytype_uint16 yyprhs[] = --{ -- 0, 0, 3, 8, 9, 12, 17, 20, 23, 27, -- 31, 36, 42, 43, 46, 51, 54, 58, 61, 64, -- 68, 73, 76, 86, 92, 95, 96, 99, 102, 106, -- 108, 111, 114, 117, 119, 121, 125, 127, 129, 135, -- 137, 141, 143, 147, 149, 153, 155, 159, 161, 165, -- 167, 171, 175, 177, 181, 185, 189, 193, 197, 201, -- 203, 207, 211, 213, 217, 221, 225, 227, 229, 232, -- 235, 238, 239, 242, 245, 246, 249, 252, 255, 259 --}; -- --/* YYRHS -- A `-1'-separated list of the rules' RHS. */ --static const yytype_int8 yyrhs[] = --{ -- 49, 0, -1, 3, 25, 50, 52, -1, -1, 51, -- 50, -1, 4, 59, 59, 25, -1, 22, 51, -1, -- 26, 53, -1, 52, 26, 53, -1, 52, 23, 53, -- -1, 52, 15, 23, 25, -1, 27, 54, 74, 28, -- 25, -1, -1, 54, 55, -1, 16, 29, 56, 25, -- -1, 16, 25, -1, 14, 16, 25, -1, 22, 55, -- -1, 57, 21, -1, 57, 58, 30, -1, 57, 31, -- 73, 32, -1, 57, 23, -1, 57, 24, 33, 21, -- 34, 59, 34, 59, 35, -1, 57, 24, 33, 21, -- 35, -1, 56, 22, -1, -1, 56, 34, -1, 57, -- 22, -1, 13, 17, 36, -1, 36, -1, 58, 59, -- -1, 58, 23, -1, 58, 22, -1, 17, -1, 18, -- -1, 33, 60, 35, -1, 61, -1, 62, -1, 62, -- 37, 60, 38, 61, -1, 63, -1, 62, 12, 63, -- -1, 64, -1, 63, 11, 64, -1, 65, -1, 64, -- 39, 65, -1, 66, -1, 65, 40, 66, -1, 67, -- -1, 66, 41, 67, -1, 68, -1, 67, 9, 68, -- -1, 67, 10, 68, -1, 69, -1, 68, 36, 69, -- -1, 68, 30, 69, -1, 68, 7, 69, -1, 68, -- 8, 69, -1, 69, 5, 70, -1, 69, 6, 70, -- -1, 70, -1, 70, 42, 71, -1, 70, 43, 71, -- -1, 71, -1, 71, 44, 72, -1, 71, 26, 72, -- -1, 71, 45, 72, -1, 72, -1, 59, -1, 43, -- 72, -1, 46, 72, -1, 47, 72, -1, -1, 73, -- 20, -1, 73, 22, -1, -1, 75, 74, -1, 75, -- 55, -1, 16, 53, -1, 15, 16, 25, -1, 22, -- 75, -1 --}; -- --/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 109, 109, 118, 121, 128, 132, 140, 144, 148, -- 158, 172, 180, 183, 190, 194, 198, 202, 210, 214, -- 218, 222, 226, 243, 253, 261, 264, 268, 275, 290, -- 295, 315, 329, 336, 340, 344, 351, 355, 356, 360, -- 361, 365, 366, 370, 371, 375, 376, 380, 381, 385, -- 386, 387, 391, 392, 393, 394, 395, 399, 400, 401, -- 405, 406, 407, 411, 412, 413, 414, 418, 419, 420, -- 421, 426, 429, 433, 441, 444, 448, 456, 460, 464 -+ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, -+ 156, 160, 170, 185, 193, 196, 203, 207, 211, 215, -+ 223, 227, 231, 235, 239, 255, 265, 273, 276, 280, -+ 287, 303, 308, 327, 341, 348, 349, 350, 357, 361, -+ 362, 366, 367, 371, 372, 376, 377, 381, 382, 386, -+ 387, 391, 392, 393, 397, 398, 399, 400, 401, 405, -+ 406, 407, 411, 412, 413, 417, 418, 419, 420, 424, -+ 425, 426, 427, 432, 435, 439, 447, 450, 454, 462, -+ 466, 470 - }; - #endif - -@@ -546,25 +513,25 @@ static const yytype_uint16 yyrline[] = - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", - "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", - "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", - "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULL -+ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -+ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -+ "integer_prim", "integer_expr", "integer_trinary", "integer_or", -+ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -+ "integer_eq", "integer_rela", "integer_shift", "integer_add", -+ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR - }; - #endif - - # ifdef YYPRINT --/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -- token YYLEX-NUM. */ -+/* YYTOKNUM[NUM] -- (External) token number corresponding to the -+ (internal) symbol number NUM (which must be that of a token). */ - static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -@@ -575,183 +542,173 @@ static const yytype_uint16 yytoknum[] = - }; - # endif - --/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ --static const yytype_uint8 yyr1[] = --{ -- 0, 48, 49, 50, 50, 51, 51, 52, 52, 52, -- 52, 53, 54, 54, 55, 55, 55, 55, 56, 56, -- 56, 56, 56, 56, 56, 57, 57, 57, 58, 58, -- 58, 58, 58, 59, 59, 59, 60, 61, 61, 62, -- 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, -- 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, -- 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, -- 72, 73, 73, 73, 74, 74, 74, 75, 75, 75 --}; -+#define YYPACT_NINF -41 - --/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ --static const yytype_uint8 yyr2[] = -+#define yypact_value_is_default(Yystate) \ -+ (!!((Yystate) == (-41))) -+ -+#define YYTABLE_NINF -1 -+ -+#define yytable_value_is_error(Yytable_value) \ -+ 0 -+ -+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+static const yytype_int8 yypact[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 3, -- 4, 5, 0, 2, 4, 2, 3, 2, 2, 3, -- 4, 2, 9, 5, 2, 0, 2, 2, 3, 1, -- 2, 2, 2, 1, 1, 3, 1, 1, 5, 1, -- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, -- 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, -- 3, 3, 1, 3, 3, 3, 1, 1, 2, 2, -- 2, 0, 2, 2, 0, 2, 2, 2, 3, 2 -+ 37, 10, 24, 78, -41, 20, 9, -41, 8, 9, -+ 59, 9, -41, -41, -10, 8, -41, 60, 39, -41, -+ -10, -10, -10, -41, 51, -41, -7, 76, 50, 52, -+ 53, 49, 2, 65, 32, -1, -41, 66, -41, -41, -+ 67, 60, 60, -41, -41, -41, -41, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -41, 41, 68, -41, -+ -41, 76, 57, 50, 52, 53, 49, 2, 2, 65, -+ 65, 65, 65, 32, 32, -1, -1, -41, -41, -41, -+ 79, 80, -12, 41, -41, 70, 41, -41, -10, 74, -+ 75, -41, -41, -41, -41, -41, 77, -41, -41, -41, -+ -41, -41, 17, -2, -41, -41, -41, -41, 83, -41, -+ -41, -41, 71, -41, -41, 31, 69, 82, -4, -41, -+ -41, -41, -41, -41, 42, -41, -41, -41, 8, -41, -+ 72, 8, 73, -41 - }; - --/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -- Performed when YYTABLE doesn't specify something else to do. Zero -- means the default is an error. */ -+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE does not specify something else to do. Zero -+ means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 33, -- 34, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 67, 0, 36, 37, 39, 41, 43, 45, 47, 49, -- 52, 59, 62, 66, 0, 12, 7, 0, 0, 0, -- 68, 69, 70, 35, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -+ 0, 5, 35, 36, 0, 0, 8, 0, 2, 6, -+ 0, 0, 0, 69, 0, 38, 39, 41, 43, 45, -+ 47, 49, 51, 54, 61, 64, 68, 0, 14, 9, -+ 0, 0, 0, 70, 71, 72, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 5, 74, 0, 9, 8, 40, 0, -- 42, 44, 46, 48, 50, 51, 55, 56, 54, 53, -- 57, 58, 60, 61, 64, 63, 65, 0, 0, 0, -- 0, 13, 0, 74, 10, 0, 0, 0, 15, 25, -- 77, 17, 79, 0, 76, 75, 38, 16, 78, 0, -- 0, 11, 24, 14, 26, 0, 18, 27, 21, 0, -- 71, 29, 0, 0, 0, 0, 32, 31, 19, 30, -- 28, 0, 72, 73, 20, 0, 23, 0, 0, 0, -- 22 -+ 0, 0, 0, 0, 0, 0, 7, 76, 0, 11, -+ 10, 42, 0, 44, 46, 48, 50, 52, 53, 57, -+ 58, 56, 55, 59, 60, 62, 63, 66, 65, 67, -+ 0, 0, 0, 0, 15, 0, 76, 12, 0, 0, -+ 0, 17, 27, 79, 19, 81, 0, 78, 77, 40, -+ 18, 80, 0, 0, 13, 26, 16, 28, 0, 20, -+ 29, 23, 0, 73, 31, 0, 0, 0, 0, 34, -+ 33, 21, 32, 30, 0, 74, 75, 22, 0, 25, -+ 0, 0, 0, 24 - }; - --/* YYDEFGOTO[NTERM-NUM]. */ --static const yytype_int8 yydefgoto[] = -+ /* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = - { -- -1, 2, 7, 8, 15, 36, 64, 91, 109, 110, -- 122, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 125, 92, 93 -+ -41, -41, -41, 96, 100, -41, -40, -41, -23, -41, -+ -41, -41, -8, 62, 13, -41, 81, 63, 64, 84, -+ 61, 25, 11, 21, 22, -17, -41, 19, 23 - }; - --/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -- STATE-NUM. */ --#define YYPACT_NINF -78 --static const yytype_int8 yypact[] = -+ /* YYDEFGOTO[NTERM-NUM]. */ -+static const yytype_int16 yydefgoto[] = - { -- 22, 11, 51, 10, -78, 23, 10, 2, 10, -78, -- -78, -9, 23, -78, 30, 38, -78, -9, -9, -9, -- -78, 35, -78, -6, 52, 29, 48, 49, 33, 3, -- 71, 36, 0, -78, 64, -78, -78, 68, 30, 30, -- -78, -78, -78, -78, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -78, 44, 67, -78, -78, 52, 55, -- 29, 48, 49, 33, 3, 3, 71, 71, 71, 71, -- 36, 36, 0, 0, -78, -78, -78, 78, 79, 42, -- 44, -78, 69, 44, -78, -9, 73, 74, -78, -78, -- -78, -78, -78, 75, -78, -78, -78, -78, -78, -7, -- -1, -78, -78, -78, -78, 84, -78, -78, -78, 63, -- -78, -78, 32, 66, 82, -3, -78, -78, -78, -78, -- -78, 46, -78, -78, -78, 23, -78, 70, 23, 72, -- -78 -+ -1, 2, 6, 10, 11, 18, 39, 67, 94, 112, -+ 113, 125, 23, 24, 25, 26, 27, 28, 29, 30, -+ 31, 32, 33, 34, 35, 36, 128, 95, 96 - }; - --/* YYPGOTO[NTERM-NUM]. */ --static const yytype_int8 yypgoto[] = -+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule whose -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+static const yytype_uint8 yytable[] = - { -- -78, -78, 97, 100, -78, -37, -78, -77, -78, -78, -- -78, -5, 65, 13, -78, 76, 77, 62, 80, 83, -- 34, 20, 26, 28, -14, -78, 18, 24 -+ 15, 69, 70, 43, 44, 45, 47, 37, 12, 13, -+ 55, 56, 118, 101, 8, 38, 135, 102, 136, 119, -+ 120, 121, 122, 14, 4, 63, 12, 13, 137, 123, -+ 48, 9, 57, 20, 124, 3, 21, 22, 58, 115, -+ 1, 14, 116, 64, 65, 7, 87, 88, 89, 12, -+ 13, 117, 103, 129, 130, 40, 90, 91, 92, 53, -+ 54, 131, 41, 93, 14, 42, 79, 80, 81, 82, -+ 104, 59, 60, 107, 61, 62, 138, 139, 77, 78, -+ 83, 84, 5, 85, 86, 17, 46, 38, 49, 50, -+ 68, 66, 51, 97, 52, 98, 99, 100, 106, 110, -+ 111, 126, 114, 134, 127, 133, 141, 19, 143, 16, -+ 72, 109, 73, 76, 74, 108, 105, 132, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, -+ 140, 0, 0, 142, 0, 75 - }; - --/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -- positive, shift that token. If negative, reduce the rule which -- number is the opposite. If YYTABLE_NINF, syntax error. */ --#define YYTABLE_NINF -1 --static const yytype_uint8 yytable[] = -+static const yytype_int16 yycheck[] = - { -- 12, 66, 67, 40, 41, 42, 44, 34, 9, 10, -- 52, 53, 115, 101, 5, 112, 104, 132, 113, 133, -- 116, 117, 118, 119, 11, 1, 60, 114, 14, 134, -- 120, 45, 6, 54, 17, 121, 3, 18, 19, 55, -- 9, 10, 50, 51, 61, 62, 84, 85, 86, 9, -- 10, 4, 100, 37, 126, 127, 11, 35, 87, 88, -- 89, 38, 128, 46, 39, 11, 90, 98, 47, 35, -- 43, 99, 76, 77, 78, 79, 56, 57, 58, 59, -- 135, 136, 80, 81, 74, 75, 82, 83, 48, 63, -- 49, 65, 94, 95, 96, 97, 124, 103, 107, 108, -- 111, 123, 130, 131, 138, 16, 13, 140, 106, 71, -- 69, 105, 0, 0, 102, 0, 0, 129, 0, 0, -- 68, 0, 0, 70, 0, 0, 0, 0, 72, 0, -- 137, 0, 73, 139 -+ 8, 41, 42, 20, 21, 22, 13, 15, 18, 19, -+ 8, 9, 14, 25, 5, 27, 20, 29, 22, 21, -+ 22, 23, 24, 33, 0, 26, 18, 19, 32, 31, -+ 37, 22, 30, 43, 36, 25, 46, 47, 36, 22, -+ 3, 33, 25, 44, 45, 25, 63, 64, 65, 18, -+ 19, 34, 92, 22, 23, 16, 15, 16, 17, 10, -+ 11, 30, 23, 22, 33, 26, 55, 56, 57, 58, -+ 93, 6, 7, 96, 42, 43, 34, 35, 53, 54, -+ 59, 60, 4, 61, 62, 26, 35, 27, 12, 39, -+ 23, 25, 40, 25, 41, 38, 17, 17, 28, 25, -+ 25, 18, 25, 21, 33, 36, 34, 11, 35, 9, -+ 48, 98, 49, 52, 50, 96, 93, 125, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1, 47, -1, -+ 138, -1, -1, 141, -1, 51 - }; - --#define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-78))) -- --#define yytable_value_is_error(Yytable_value) \ -- YYID (0) -+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = -+{ -+ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -+ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -+ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -+ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -+ 16, 23, 26, 73, 73, 73, 35, 13, 37, 12, -+ 39, 40, 41, 10, 11, 8, 9, 30, 36, 6, -+ 7, 42, 43, 26, 44, 45, 25, 55, 23, 54, -+ 54, 64, 61, 65, 66, 67, 68, 69, 69, 70, -+ 70, 70, 70, 71, 71, 72, 72, 73, 73, 73, -+ 15, 16, 17, 22, 56, 75, 76, 25, 38, 17, -+ 17, 25, 29, 54, 56, 76, 28, 56, 75, 62, -+ 25, 25, 57, 58, 25, 22, 25, 34, 14, 21, -+ 22, 23, 24, 31, 36, 59, 18, 33, 74, 22, -+ 23, 30, 60, 36, 21, 20, 22, 32, 34, 35, -+ 60, 34, 60, 35 -+}; - --static const yytype_int16 yycheck[] = -+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = - { -- 5, 38, 39, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 13, 90, 4, 22, 93, 20, 25, 22, -- 21, 22, 23, 24, 33, 3, 26, 34, 26, 32, -- 31, 37, 22, 30, 43, 36, 25, 46, 47, 36, -- 17, 18, 9, 10, 44, 45, 60, 61, 62, 17, -- 18, 0, 89, 15, 22, 23, 33, 27, 14, 15, -- 16, 23, 30, 11, 26, 33, 22, 25, 39, 27, -- 35, 29, 52, 53, 54, 55, 5, 6, 42, 43, -- 34, 35, 56, 57, 50, 51, 58, 59, 40, 25, -- 41, 23, 25, 38, 16, 16, 33, 28, 25, 25, -- 25, 17, 36, 21, 34, 8, 6, 35, 95, 47, -- 45, 93, -1, -1, 90, -1, -1, 122, -1, -1, -- 44, -1, -1, 46, -1, -1, -1, -1, 48, -1, -- 135, -1, 49, 138 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 53, 53, 54, 55, 55, 56, 56, 56, 56, -+ 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, -+ 59, 59, 59, 59, 59, 60, 60, 60, 61, 62, -+ 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, -+ 67, 68, 68, 68, 69, 69, 69, 69, 69, 70, -+ 70, 70, 71, 71, 71, 72, 72, 72, 72, 73, -+ 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, -+ 76, 76 - }; - --/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -- symbol of state STATE-NUM. */ --static const yytype_uint8 yystos[] = -+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = - { -- 0, 3, 49, 25, 0, 4, 22, 50, 51, 17, -- 18, 33, 59, 51, 26, 52, 50, 43, 46, 47, -- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, -- 69, 70, 71, 72, 59, 27, 53, 15, 23, 26, -- 72, 72, 72, 35, 12, 37, 11, 39, 40, 41, -- 9, 10, 7, 8, 30, 36, 5, 6, 42, 43, -- 26, 44, 45, 25, 54, 23, 53, 53, 63, 60, -- 64, 65, 66, 67, 68, 68, 69, 69, 69, 69, -- 70, 70, 71, 71, 72, 72, 72, 14, 15, 16, -- 22, 55, 74, 75, 25, 38, 16, 16, 25, 29, -- 53, 55, 75, 28, 55, 74, 61, 25, 25, 56, -- 57, 25, 22, 25, 34, 13, 21, 22, 23, 24, -- 31, 36, 58, 17, 33, 73, 22, 23, 30, 59, -- 36, 21, 20, 22, 32, 34, 35, 59, 34, 59, -- 35 -+ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -+ 3, 3, 4, 5, 0, 2, 4, 2, 3, 2, -+ 2, 3, 4, 2, 9, 5, 2, 0, 2, 2, -+ 3, 1, 2, 2, 2, 1, 1, 3, 1, 1, -+ 5, 1, 3, 1, 3, 1, 3, 1, 3, 1, -+ 3, 1, 3, 3, 1, 3, 3, 3, 3, 3, -+ 3, 1, 3, 3, 1, 3, 3, 3, 1, 1, -+ 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, -+ 3, 2 - }; - --#define yyerrok (yyerrstatus = 0) --#define yyclearin (yychar = YYEMPTY) --#define YYEMPTY (-2) --#define YYEOF 0 -- --#define YYACCEPT goto yyacceptlab --#define YYABORT goto yyabortlab --#define YYERROR goto yyerrorlab -- -- --/* Like YYERROR except do call yyerror. This remains here temporarily -- to ease the transition to the new meaning of YYERROR, for GCC. -- Once GCC version 2 has supplanted version 1, this can go. However, -- YYFAIL appears to be in use. Nevertheless, it is formally deprecated -- in Bison 2.4.2's NEWS entry, where a plan to phase it out is -- discussed. */ -- --#define YYFAIL goto yyerrlab --#if defined YYFAIL -- /* This is here to suppress warnings from the GCC cpp's -- -Wunused-macros. Normally we don't worry about that warning, but -- some users do, and we want to make it easy for users to remove -- YYFAIL uses, which will produce warnings from Bison 2.5. */ --#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ - - #define YYRECOVERING() (!!yyerrstatus) - -@@ -768,27 +725,41 @@ do \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ -- YYERROR; \ -- } \ --while (YYID (0)) -+ YYERROR; \ -+ } \ -+while (0) - - /* Error token number */ --#define YYTERROR 1 --#define YYERRCODE 256 -- -- --/* This macro is provided for backward compatibility. */ --#ifndef YY_LOCATION_PRINT --# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) - #endif - -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - --/* YYLEX -- calling `yylex' with the right arguments. */ --#ifdef YYLEX_PARAM --# define YYLEX yylex (YYLEX_PARAM) --#else --# define YYLEX yylex () --#endif - - /* Enable debugging if requested. */ - #if YYDEBUG -@@ -798,50 +769,84 @@ while (YYID (0)) - # define YYFPRINTF fprintf - # endif - --# define YYDPRINTF(Args) \ --do { \ -- if (yydebug) \ -- YYFPRINTF Args; \ --} while (YYID (0)) -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) - --# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ --do { \ -- if (yydebug) \ -- { \ -- YYFPRINTF (stderr, "%s ", Title); \ -- yy_symbol_print (stderr, \ -- Type, Value); \ -- YYFPRINTF (stderr, "\n"); \ -- } \ --} while (YYID (0)) - -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ - --/*--------------------------------. --| Print this symbol on YYOUTPUT. | --`--------------------------------*/ -+#ifndef YY_LOCATION_PRINT -+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static void --yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) --#else --static void --yy_symbol_value_print (yyoutput, yytype, yyvaluep) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; -+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ -+ -+YY_ATTRIBUTE_UNUSED -+static unsigned -+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -+{ -+ unsigned res = 0; -+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; -+ if (0 <= yylocp->first_line) -+ { -+ res += YYFPRINTF (yyo, "%d", yylocp->first_line); -+ if (0 <= yylocp->first_column) -+ res += YYFPRINTF (yyo, ".%d", yylocp->first_column); -+ } -+ if (0 <= yylocp->last_line) -+ { -+ if (yylocp->first_line < yylocp->last_line) -+ { -+ res += YYFPRINTF (yyo, "-%d", yylocp->last_line); -+ if (0 <= end_col) -+ res += YYFPRINTF (yyo, ".%d", end_col); -+ } -+ else if (0 <= end_col && yylocp->first_column < end_col) -+ res += YYFPRINTF (yyo, "-%d", end_col); -+ } -+ return res; -+ } -+ -+# define YY_LOCATION_PRINT(File, Loc) \ -+ yy_location_print_ (File, &(Loc)) -+ -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif - #endif -+ -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+ -+/*----------------------------------------. -+| Print this symbol's value on YYOUTPUT. | -+`----------------------------------------*/ -+ -+static void -+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) - { - FILE *yyo = yyoutput; - YYUSE (yyo); -+ YYUSE (yylocationp); - if (!yyvaluep) - return; - # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); --# else -- YYUSE (yyoutput); - # endif - YYUSE (yytype); - } -@@ -851,24 +856,15 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static void --yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) --#else - static void --yy_symbol_print (yyoutput, yytype, yyvaluep) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; --#endif -+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) - { -- if (yytype < YYNTOKENS) -- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -- else -- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ YYFPRINTF (yyoutput, "%s %s (", -+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - -- yy_symbol_value_print (yyoutput, yytype, yyvaluep); -+ YY_LOCATION_PRINT (yyoutput, *yylocationp); -+ YYFPRINTF (yyoutput, ": "); -+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); - YYFPRINTF (yyoutput, ")"); - } - -@@ -877,16 +873,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) - | TOP (included). | - `------------------------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) --#else --static void --yy_stack_print (yybottom, yytop) -- yytype_int16 *yybottom; -- yytype_int16 *yytop; --#endif - { - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) -@@ -897,49 +885,42 @@ yy_stack_print (yybottom, yytop) - YYFPRINTF (stderr, "\n"); - } - --# define YY_STACK_PRINT(Bottom, Top) \ --do { \ -- if (yydebug) \ -- yy_stack_print ((Bottom), (Top)); \ --} while (YYID (0)) -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) - - - /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - `------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void --yy_reduce_print (YYSTYPE *yyvsp, int yyrule) --#else --static void --yy_reduce_print (yyvsp, yyrule) -- YYSTYPE *yyvsp; -- int yyrule; --#endif -+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) - { -+ unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; -- unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -- yyrule - 1, yylno); -+ yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); -- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -- &(yyvsp[(yyi + 1) - (yynrhs)]) -- ); -+ yy_symbol_print (stderr, -+ yystos[yyssp[yyi + 1 - yynrhs]], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } - } - --# define YY_REDUCE_PRINT(Rule) \ --do { \ -- if (yydebug) \ -- yy_reduce_print (yyvsp, Rule); \ --} while (YYID (0)) -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ -+} while (0) - - /* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -@@ -953,7 +934,7 @@ int yydebug; - - - /* YYINITDEPTH -- initial size of the parser's stacks. */ --#ifndef YYINITDEPTH -+#ifndef YYINITDEPTH - # define YYINITDEPTH 200 - #endif - -@@ -976,15 +957,8 @@ int yydebug; - # define yystrlen strlen - # else - /* Return the length of YYSTR. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static YYSIZE_T - yystrlen (const char *yystr) --#else --static YYSIZE_T --yystrlen (yystr) -- const char *yystr; --#endif - { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) -@@ -1000,16 +974,8 @@ yystrlen (yystr) - # else - /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static char * - yystpcpy (char *yydest, const char *yysrc) --#else --static char * --yystpcpy (yydest, yysrc) -- char *yydest; -- const char *yysrc; --#endif - { - char *yyd = yydest; - const char *yys = yysrc; -@@ -1039,27 +1005,27 @@ yytnamerr (char *yyres, const char *yystr) - char const *yyp = yystr; - - for (;;) -- switch (*++yyp) -- { -- case '\'': -- case ',': -- goto do_not_strip_quotes; -- -- case '\\': -- if (*++yyp != '\\') -- goto do_not_strip_quotes; -- /* Fall through. */ -- default: -- if (yyres) -- yyres[yyn] = *yyp; -- yyn++; -- break; -- -- case '"': -- if (yyres) -- yyres[yyn] = '\0'; -- return yyn; -- } -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } - do_not_strip_quotes: ; - } - -@@ -1082,11 +1048,11 @@ static int - yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) - { -- YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); -+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ -- const char *yyformat = YY_NULL; -+ const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per -@@ -1094,10 +1060,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - int yycount = 0; - - /* There are many possibilities here to consider: -- - Assume YYFAIL is not used. It's too flawed to consider. See -- -- for details. YYERROR is fine as it does not invoke this -- function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected -@@ -1147,7 +1109,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - } - yyarg[yycount++] = yytname[yyx]; - { -- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); -+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; -@@ -1214,26 +1176,18 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - | Release the memory associated to this symbol. | - `-----------------------------------------------*/ - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void --yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) --#else --static void --yydestruct (yymsg, yytype, yyvaluep) -- const char *yymsg; -- int yytype; -- YYSTYPE *yyvaluep; --#endif -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) - { - YYUSE (yyvaluep); -- -+ YYUSE (yylocationp); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - } - - -@@ -1242,18 +1196,14 @@ yydestruct (yymsg, yytype, yyvaluep) - /* The lookahead symbol. */ - int yychar; - -- --#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_END --#endif --#ifndef YY_INITIAL_VALUE --# define YY_INITIAL_VALUE(Value) /* Nothing. */ --#endif -- - /* The semantic value of the lookahead symbol. */ --YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); -- -+YYSTYPE yylval; -+/* Location data for the lookahead symbol. */ -+YYLTYPE yylloc -+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+ = { 1, 1, 1, 1 } -+# endif -+; - /* Number of syntax errors so far. */ - int yynerrs; - -@@ -1262,35 +1212,17 @@ int yynerrs; - | yyparse. | - `----------*/ - --#ifdef YYPARSE_PARAM --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --int --yyparse (void *YYPARSE_PARAM) --#else --int --yyparse (YYPARSE_PARAM) -- void *YYPARSE_PARAM; --#endif --#else /* ! YYPARSE_PARAM */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - int - yyparse (void) --#else --int --yyparse () -- --#endif --#endif - { - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: -- `yyss': related to states. -- `yyvs': related to semantic values. -+ 'yyss': related to states. -+ 'yyvs': related to semantic values. -+ 'yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ -@@ -1305,6 +1237,14 @@ yyparse () - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - -+ /* The location stack. */ -+ YYLTYPE yylsa[YYINITDEPTH]; -+ YYLTYPE *yyls; -+ YYLTYPE *yylsp; -+ -+ /* The locations where the error started and ended. */ -+ YYLTYPE yyerror_range[3]; -+ - YYSIZE_T yystacksize; - - int yyn; -@@ -1314,6 +1254,7 @@ yyparse () - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -+ YYLTYPE yyloc; - - #if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ -@@ -1322,7 +1263,7 @@ yyparse () - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; - #endif - --#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) -+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ -@@ -1330,6 +1271,7 @@ yyparse () - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; -+ yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); -@@ -1338,6 +1280,7 @@ yyparse () - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ -+ yylsp[0] = yylloc; - goto yysetstate; - - /*------------------------------------------------------------. -@@ -1358,23 +1301,26 @@ yyparse () - - #ifdef yyoverflow - { -- /* Give user a chance to reallocate the stack. Use copies of -- these so that the &'s don't force the real ones into -- memory. */ -- YYSTYPE *yyvs1 = yyvs; -- yytype_int16 *yyss1 = yyss; -- -- /* Each stack pointer address is followed by the size of the -- data in use in that stack, in bytes. This used to be a -- conditional around just the two extra args, but that might -- be undefined if yyoverflow is a macro. */ -- yyoverflow (YY_("memory exhausted"), -- &yyss1, yysize * sizeof (*yyssp), -- &yyvs1, yysize * sizeof (*yyvsp), -- &yystacksize); -- -- yyss = yyss1; -- yyvs = yyvs1; -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; - } - #else /* no yyoverflow */ - # ifndef YYSTACK_RELOCATE -@@ -1382,34 +1328,36 @@ yyparse () - # else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) -- goto yyexhaustedlab; -+ goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) -- yystacksize = YYMAXDEPTH; -+ yystacksize = YYMAXDEPTH; - - { -- yytype_int16 *yyss1 = yyss; -- union yyalloc *yyptr = -- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -- if (! yyptr) -- goto yyexhaustedlab; -- YYSTACK_RELOCATE (yyss_alloc, yyss); -- YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ YYSTACK_RELOCATE (yyls_alloc, yyls); - # undef YYSTACK_RELOCATE -- if (yyss1 != yyssa) -- YYSTACK_FREE (yyss1); -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); - } - # endif - #endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; -+ yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", -- (unsigned long int) yystacksize)); -+ (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) -- YYABORT; -+ YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -@@ -1438,7 +1386,7 @@ yybackup: - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); -- yychar = YYLEX; -+ yychar = yylex (); - } - - if (yychar <= YYEOF) -@@ -1481,7 +1429,7 @@ yybackup: - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END -- -+ *++yylsp = yylloc; - goto yynewstate; - - -@@ -1503,7 +1451,7 @@ yyreduce: - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: -- `$$ = $1'. -+ '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison -@@ -1512,287 +1460,306 @@ yyreduce: - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - -- -+ /* Default location. */ -+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: --/* Line 1787 of yacc.c */ --#line 110 "dtc-parser.y" -+#line 109 "dtc-parser.y" /* yacc.c:1646 */ - { -- the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), -- guess_boot_cpuid((yyvsp[(4) - (4)].node))); -+ (yyvsp[0].node)->is_plugin = (yyvsp[-2].is_plugin); -+ (yyvsp[0].node)->is_root = 1; -+ the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -+ guess_boot_cpuid((yyvsp[0].node))); - } -+#line 1477 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --/* Line 1787 of yacc.c */ --#line 118 "dtc-parser.y" -+#line 119 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.is_plugin) = 0; - } -+#line 1485 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --/* Line 1787 of yacc.c */ --#line 122 "dtc-parser.y" -+#line 123 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); -+ (yyval.is_plugin) = 1; - } -+#line 1493 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: --/* Line 1787 of yacc.c */ --#line 129 "dtc-parser.y" -+#line 130 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); -+ (yyval.re) = NULL; - } -+#line 1501 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: --/* Line 1787 of yacc.c */ --#line 133 "dtc-parser.y" -+#line 134 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.re) = (yyvsp[(2) - (2)].re); -+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } -+#line 1509 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: --/* Line 1787 of yacc.c */ --#line 141 "dtc-parser.y" -+#line 141 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); -+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } -+#line 1517 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: --/* Line 1787 of yacc.c */ --#line 145 "dtc-parser.y" -+#line 145 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); -+ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); -+ (yyval.re) = (yyvsp[0].re); - } -+#line 1526 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: --/* Line 1787 of yacc.c */ --#line 149 "dtc-parser.y" -+#line 153 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); -- -- if (target) -- merge_nodes(target, (yyvsp[(3) - (3)].node)); -- else -- print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); -- (yyval.node) = (yyvsp[(1) - (3)].node); -+ (yyval.node) = name_node((yyvsp[0].node), ""); - } -+#line 1534 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: --/* Line 1787 of yacc.c */ --#line 159 "dtc-parser.y" -+#line 157 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -- -- if (!target) -- print_error("label or path, '%s', not found", (yyvsp[(3) - (4)].labelref)); -- else -- delete_node(target); -- -- (yyval.node) = (yyvsp[(1) - (4)].node); -+ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } -+#line 1542 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: --/* Line 1787 of yacc.c */ --#line 173 "dtc-parser.y" -+#line 161 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); -+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); -+ -+ if (target) -+ merge_nodes(target, (yyvsp[0].node)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-2].node); - } -+#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: --/* Line 1787 of yacc.c */ --#line 180 "dtc-parser.y" -+#line 171 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = NULL; -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ -+ if (target) -+ delete_node(target); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ -+ -+ (yyval.node) = (yyvsp[-3].node); - } -+#line 1572 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: --/* Line 1787 of yacc.c */ --#line 184 "dtc-parser.y" -+#line 186 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); -+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } -+#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: --/* Line 1787 of yacc.c */ --#line 191 "dtc-parser.y" -+#line 193 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); -+ (yyval.proplist) = NULL; - } -+#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: --/* Line 1787 of yacc.c */ --#line 195 "dtc-parser.y" -+#line 197 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); -+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } -+#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: --/* Line 1787 of yacc.c */ --#line 199 "dtc-parser.y" -+#line 204 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); -+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } -+#line 1604 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: --/* Line 1787 of yacc.c */ --#line 203 "dtc-parser.y" -+#line 208 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.prop) = (yyvsp[(2) - (2)].prop); -+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } -+#line 1612 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: --/* Line 1787 of yacc.c */ --#line 211 "dtc-parser.y" -+#line 212 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); -+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } -+#line 1620 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: --/* Line 1787 of yacc.c */ --#line 215 "dtc-parser.y" -+#line 216 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); -+ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); -+ (yyval.prop) = (yyvsp[0].prop); - } -+#line 1629 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: --/* Line 1787 of yacc.c */ --#line 219 "dtc-parser.y" -+#line 224 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -+ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } -+#line 1637 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: --/* Line 1787 of yacc.c */ --#line 223 "dtc-parser.y" -+#line 228 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } -+#line 1645 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: --/* Line 1787 of yacc.c */ --#line 227 "dtc-parser.y" -+#line 232 "dtc-parser.y" /* yacc.c:1646 */ - { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); -+ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); -+ } -+#line 1653 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 23: -+#line 236 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); -+ } -+#line 1661 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 24: -+#line 240 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; - -- if ((yyvsp[(6) - (9)].integer) != 0) -- if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) -- print_error("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)(yyvsp[(6) - (9)].integer), -- (yyvsp[(4) - (9)].data).val, -- strerror(errno)); -+ if ((yyvsp[-3].integer) != 0) -+ if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) -+ die("Couldn't seek to offset %llu in \"%s\": %s", -+ (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, -+ strerror(errno)); - -- d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); -+ d = data_copy_file(f, (yyvsp[-1].integer)); - -- (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); -+ (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } -+#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 23: --/* Line 1787 of yacc.c */ --#line 244 "dtc-parser.y" -+ case 25: -+#line 256 "dtc-parser.y" /* yacc.c:1646 */ - { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - -- (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); -+ (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } -+#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --/* Line 1787 of yacc.c */ --#line 254 "dtc-parser.y" -+ case 26: -+#line 266 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1703 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --/* Line 1787 of yacc.c */ --#line 261 "dtc-parser.y" -+ case 27: -+#line 273 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } -+#line 1711 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --/* Line 1787 of yacc.c */ --#line 265 "dtc-parser.y" -+ case 28: -+#line 277 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = (yyvsp[(1) - (2)].data); -+ (yyval.data) = (yyvsp[-1].data); - } -+#line 1719 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --/* Line 1787 of yacc.c */ --#line 269 "dtc-parser.y" -+ case 29: -+#line 281 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1727 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --/* Line 1787 of yacc.c */ --#line 276 "dtc-parser.y" -+ case 30: -+#line 288 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.array).data = empty_data; -- (yyval.array).bits = eval_literal((yyvsp[(2) - (3)].literal), 0, 7); -- -- if (((yyval.array).bits != 8) && -- ((yyval.array).bits != 16) && -- ((yyval.array).bits != 32) && -- ((yyval.array).bits != 64)) -- { -- print_error("Only 8, 16, 32 and 64-bit elements" -- " are currently supported"); -- (yyval.array).bits = 32; -+ unsigned long long bits; -+ -+ bits = (yyvsp[-1].integer); -+ -+ if ((bits != 8) && (bits != 16) && -+ (bits != 32) && (bits != 64)) { -+ ERROR(&(yylsp[-1]), "Array elements must be" -+ " 8, 16, 32 or 64-bits"); -+ bits = 32; - } -+ -+ (yyval.array).data = empty_data; -+ (yyval.array).bits = bits; - } -+#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --/* Line 1787 of yacc.c */ --#line 291 "dtc-parser.y" -+ case 31: -+#line 304 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } -+#line 1756 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --/* Line 1787 of yacc.c */ --#line 296 "dtc-parser.y" -+ case 32: -+#line 309 "dtc-parser.y" /* yacc.c:1646 */ - { -- if ((yyvsp[(1) - (2)].array).bits < 64) { -- uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; -+ if ((yyvsp[-1].array).bits < 64) { -+ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one -@@ -1801,275 +1768,258 @@ yyreduce: - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ -- if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) -- print_error( -- "integer value out of range " -- "%016lx (%d bits)", (yyvsp[(1) - (2)].array).bits); -+ if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) -+ ERROR(&(yylsp[0]), "Value out of range for" -+ " %d-bit array element", (yyvsp[-1].array).bits); - } - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } -+#line 1779 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --/* Line 1787 of yacc.c */ --#line 316 "dtc-parser.y" -+ case 33: -+#line 328 "dtc-parser.y" /* yacc.c:1646 */ - { -- uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); -+ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -- if ((yyvsp[(1) - (2)].array).bits == 32) -- (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, -+ if ((yyvsp[-1].array).bits == 32) -+ (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, - REF_PHANDLE, -- (yyvsp[(2) - (2)].labelref)); -+ (yyvsp[0].labelref)); - else -- print_error("References are only allowed in " -+ ERROR(&(yylsp[0]), "References are only allowed in " - "arrays with 32-bit elements."); - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); -- } -- break; -- -- case 32: --/* Line 1787 of yacc.c */ --#line 330 "dtc-parser.y" -- { -- (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); -- } -- break; -- -- case 33: --/* Line 1787 of yacc.c */ --#line 337 "dtc-parser.y" -- { -- (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } -+#line 1797 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 34: --/* Line 1787 of yacc.c */ --#line 341 "dtc-parser.y" -+#line 342 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal)); -+ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } -+#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 35: --/* Line 1787 of yacc.c */ --#line 345 "dtc-parser.y" -+ case 37: -+#line 351 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.integer) = (yyvsp[(2) - (3)].integer); -+ (yyval.integer) = (yyvsp[-1].integer); - } -- break; -- -- case 38: --/* Line 1787 of yacc.c */ --#line 356 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } -+#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 40: --/* Line 1787 of yacc.c */ --#line 361 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } -+#line 362 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } -+#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 42: --/* Line 1787 of yacc.c */ --#line 366 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } -+#line 367 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } -+#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 44: --/* Line 1787 of yacc.c */ --#line 371 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } -+#line 372 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } -+#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 46: --/* Line 1787 of yacc.c */ --#line 376 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } -+#line 377 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } -+#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 48: --/* Line 1787 of yacc.c */ --#line 381 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } -+#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } -+#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 50: --/* Line 1787 of yacc.c */ --#line 386 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } -+#line 387 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } -+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 51: --/* Line 1787 of yacc.c */ --#line 387 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } -+ case 52: -+#line 392 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } -+#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 53: --/* Line 1787 of yacc.c */ --#line 392 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } -- break; -- -- case 54: --/* Line 1787 of yacc.c */ --#line 393 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } -+#line 393 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } -+#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 55: --/* Line 1787 of yacc.c */ --#line 394 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } -+#line 398 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } -+#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 56: --/* Line 1787 of yacc.c */ --#line 395 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } -+#line 399 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } -+#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 57: --/* Line 1787 of yacc.c */ --#line 399 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } -+#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } -+#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 58: --/* Line 1787 of yacc.c */ --#line 400 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } -+#line 401 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } -+#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 60: --/* Line 1787 of yacc.c */ --#line 405 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } -+ case 59: -+#line 405 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } -+#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 61: --/* Line 1787 of yacc.c */ --#line 406 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } -+ case 60: -+#line 406 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } -+#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 63: --/* Line 1787 of yacc.c */ --#line 411 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } -+ case 62: -+#line 411 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } -+#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 64: --/* Line 1787 of yacc.c */ --#line 412 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } -+ case 63: -+#line 412 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } -+#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 65: --/* Line 1787 of yacc.c */ --#line 413 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } -+#line 417 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } -+#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 68: --/* Line 1787 of yacc.c */ --#line 419 "dtc-parser.y" -- { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } -+ case 66: -+#line 418 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } -+#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 69: --/* Line 1787 of yacc.c */ --#line 420 "dtc-parser.y" -- { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } -+ case 67: -+#line 419 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } -+#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 70: --/* Line 1787 of yacc.c */ --#line 421 "dtc-parser.y" -- { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } -+#line 425 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = -(yyvsp[0].integer); } -+#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 71: --/* Line 1787 of yacc.c */ --#line 426 "dtc-parser.y" -- { -- (yyval.data) = empty_data; -- } -+#line 426 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = ~(yyvsp[0].integer); } -+#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 72: --/* Line 1787 of yacc.c */ --#line 430 "dtc-parser.y" -- { -- (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); -- } -+#line 427 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = !(yyvsp[0].integer); } -+#line 1945 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 73: --/* Line 1787 of yacc.c */ --#line 434 "dtc-parser.y" -+#line 432 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = empty_data; - } -+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 74: --/* Line 1787 of yacc.c */ --#line 441 "dtc-parser.y" -+#line 436 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = NULL; -+ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); - } -+#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: --/* Line 1787 of yacc.c */ --#line 445 "dtc-parser.y" -+#line 440 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: --/* Line 1787 of yacc.c */ --#line 449 "dtc-parser.y" -+#line 447 "dtc-parser.y" /* yacc.c:1646 */ - { -- print_error("syntax error: properties must precede subnodes"); -- YYERROR; -+ (yyval.nodelist) = NULL; - } -+#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: --/* Line 1787 of yacc.c */ --#line 457 "dtc-parser.y" -+#line 451 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); -+ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } -+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: --/* Line 1787 of yacc.c */ --#line 461 "dtc-parser.y" -+#line 455 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); -+ ERROR(&(yylsp[0]), "Properties must precede subnodes"); -+ YYERROR; - } -+#line 1994 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: --/* Line 1787 of yacc.c */ --#line 465 "dtc-parser.y" -+#line 463 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.node) = (yyvsp[(2) - (2)].node); -+ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } -+#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -+ case 80: -+#line 467 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); -+ } -+#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1787 of yacc.c */ --#line 2073 "dtc-parser.tab.c" -+ case 81: -+#line 471 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[0].node); -+ } -+#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ -+#line 2023 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2090,8 +2040,9 @@ yyreduce: - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; -+ *++yylsp = yyloc; - -- /* Now `shift' the result of the reduction. Determine what state -+ /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - -@@ -2106,9 +2057,9 @@ yyreduce: - goto yynewstate; - - --/*------------------------------------. --| yyerrlab -- here on detecting error | --`------------------------------------*/ -+/*--------------------------------------. -+| yyerrlab -- here on detecting error. | -+`--------------------------------------*/ - yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ -@@ -2154,25 +2105,25 @@ yyerrlab: - #endif - } - -- -+ yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an -- error, discard it. */ -+ error, discard it. */ - - if (yychar <= YYEOF) -- { -- /* Return failure if at end of input. */ -- if (yychar == YYEOF) -- YYABORT; -- } -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } - else -- { -- yydestruct ("Error: discarding", -- yytoken, &yylval); -- yychar = YYEMPTY; -- } -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } - } - - /* Else will try to reuse lookahead token after shifting the error -@@ -2191,7 +2142,8 @@ yyerrorlab: - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - -- /* Do not reclaim the symbols of the rule which action triggered -+ yyerror_range[1] = yylsp[1-yylen]; -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; -@@ -2204,29 +2156,29 @@ yyerrorlab: - | yyerrlab1 -- common code for both syntax error and YYERROR. | - `-------------------------------------------------------------*/ - yyerrlab1: -- yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) -- { -- yyn += YYTERROR; -- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -- { -- yyn = yytable[yyn]; -- if (0 < yyn) -- break; -- } -- } -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) -- YYABORT; -- -+ YYABORT; - -+ yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", -- yystos[yystate], yyvsp); -+ yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); -@@ -2236,6 +2188,11 @@ yyerrlab1: - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - -+ yyerror_range[2] = yylloc; -+ /* Using YYLLOC is tempting, but would change the location of -+ the lookahead. YYLOC is available though. */ -+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2); -+ *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -@@ -2275,16 +2232,16 @@ yyreturn: - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", -- yytoken, &yylval); -+ yytoken, &yylval, &yylloc); - } -- /* Do not reclaim the symbols of the rule which action triggered -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", -- yystos[*yyssp], yyvsp); -+ yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } - #ifndef yyoverflow -@@ -2295,72 +2252,12 @@ yyreturn: - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - #endif -- /* Make sure YYID is used. */ -- return YYID (yyresult); -+ return yyresult; - } -+#line 477 "dtc-parser.y" /* yacc.c:1906 */ - - --/* Line 2050 of yacc.c */ --#line 471 "dtc-parser.y" -- -- --void print_error(char const *fmt, ...) --{ -- va_list va; -- -- va_start(va, fmt); -- srcpos_verror(&yylloc, fmt, va); -- va_end(va); -- -- treesource_error = 1; --} -- --void yyerror(char const *s) { -- print_error("%s", s); --} -- --static unsigned long long eval_literal(const char *s, int base, int bits) --{ -- unsigned long long val; -- char *e; -- -- errno = 0; -- val = strtoull(s, &e, base); -- if (*e) { -- size_t uls = strspn(e, "UL"); -- if (e[uls]) -- print_error("bad characters in literal"); -- } -- if ((errno == ERANGE) -- || ((bits < 64) && (val >= (1ULL << bits)))) -- print_error("literal out of range"); -- else if (errno != 0) -- print_error("bad literal"); -- return val; --} -- --static unsigned char eval_char_literal(const char *s) -+void yyerror(char const *s) - { -- int i = 1; -- char c = s[0]; -- -- if (c == '\0') -- { -- print_error("empty character literal"); -- return 0; -- } -- -- /* -- * If the first character in the character literal is a \ then process -- * the remaining characters as an escape encoding. If the first -- * character is neither an escape or a terminator it should be the only -- * character in the literal and will be returned. -- */ -- if (c == '\\') -- c = get_escape_char(s, &i); -- -- if (s[i] != '\0') -- print_error("malformed character literal"); -- -- return c; -+ ERROR(&yylloc, "%s", s); - } -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index b2e7a86..b497956 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.7.12-4996. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison interface for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,13 +26,13 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - #ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED - # define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Enabling traces. */ -+/* Debug traces. */ - #ifndef YYDEBUG - # define YYDEBUG 0 - #endif -@@ -40,48 +40,45 @@ - extern int yydebug; - #endif - --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BASE = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { --/* Line 2053 of yacc.c */ --#line 40 "dtc-parser.y" -+#line 39 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; -- char *literal; - char *labelref; -- unsigned int cbase; - uint8_t byte; - struct data data; - -@@ -96,30 +93,31 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - -- --/* Line 2053 of yacc.c */ --#line 103 "dtc-parser.tab.h" --} YYSTYPE; -+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --extern YYSTYPE yylval; -- --#ifdef YYPARSE_PARAM --#if defined __STDC__ || defined __cplusplus --int yyparse (void *YYPARSE_PARAM); --#else --int yyparse (); -+/* Location type. */ -+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE -+{ -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+}; -+# define YYLTYPE_IS_DECLARED 1 -+# define YYLTYPE_IS_TRIVIAL 1 - #endif --#else /* ! YYPARSE_PARAM */ --#if defined __STDC__ || defined __cplusplus -+ -+ -+extern YYSTYPE yylval; -+extern YYLTYPE yylloc; - int yyparse (void); --#else --int yyparse (); --#endif --#endif /* ! YYPARSE_PARAM */ - - #endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index f412460..687ccad 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -17,31 +17,28 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -- - %{ - #include -+#include - - #include "dtc.h" - #include "srcpos.h" - --YYLTYPE yylloc; -- - extern int yylex(void); --extern void print_error(char const *fmt, ...); - extern void yyerror(char const *s); -+#define ERROR(loc, ...) \ -+ do { \ -+ srcpos_error((loc), "Error", __VA_ARGS__); \ -+ treesource_error = true; \ -+ } while (0) - - extern struct boot_info *the_boot_info; --extern int treesource_error; -- --static unsigned long long eval_literal(const char *s, int base, int bits); --static unsigned char eval_char_literal(const char *s); -+extern bool treesource_error; - %} - - %union { - char *propnodename; -- char *literal; - char *labelref; -- unsigned int cbase; - uint8_t byte; - struct data data; - -@@ -56,18 +53,19 @@ static unsigned char eval_char_literal(const char *s); - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS - %token DT_DEL_PROP - %token DT_DEL_NODE - %token DT_PROPNODENAME --%token DT_LITERAL --%token DT_CHAR_LITERAL --%token DT_BASE -+%token DT_LITERAL -+%token DT_CHAR_LITERAL - %token DT_BYTE - %token DT_STRING - %token DT_LABEL -@@ -76,6 +74,7 @@ static unsigned char eval_char_literal(const char *s); - - %type propdata - %type propdataprefix -+%type plugindecl - %type memreserve - %type memreserves - %type arrayprefix -@@ -106,10 +105,23 @@ static unsigned char eval_char_literal(const char *s); - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ DT_V1 ';' plugindecl memreserves devicetree -+ { -+ $5->is_plugin = $3; -+ $5->is_root = 1; -+ the_boot_info = build_boot_info($4, $5, -+ guess_boot_cpuid($5)); -+ } -+ ; -+ -+plugindecl: -+ /* empty */ -+ { -+ $$ = 0; -+ } -+ | DT_PLUGIN ';' - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ $$ = 1; - } - ; - -@@ -152,17 +164,18 @@ devicetree: - if (target) - merge_nodes(target, $3); - else -- print_error("label or path, '%s', not found", $2); -+ ERROR(&@2, "Label or path %s not found", $2); - $$ = $1; - } - | devicetree DT_DEL_NODE DT_REF ';' - { - struct node *target = get_node_by_ref($1, $3); - -- if (!target) -- print_error("label or path, '%s', not found", $3); -- else -+ if (target) - delete_node(target); -+ else -+ ERROR(&@3, "Label or path %s not found", $3); -+ - - $$ = $1; - } -@@ -230,10 +243,9 @@ propdata: - - if ($6 != 0) - if (fseek(f, $6, SEEK_SET) != 0) -- print_error("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)$6, -- $4.val, -- strerror(errno)); -+ die("Couldn't seek to offset %llu in \"%s\": %s", -+ (unsigned long long)$6, $4.val, -+ strerror(errno)); - - d = data_copy_file(f, $8); - -@@ -274,18 +286,19 @@ propdataprefix: - arrayprefix: - DT_BITS DT_LITERAL '<' - { -- $$.data = empty_data; -- $$.bits = eval_literal($2, 0, 7); -- -- if (($$.bits != 8) && -- ($$.bits != 16) && -- ($$.bits != 32) && -- ($$.bits != 64)) -- { -- print_error("Only 8, 16, 32 and 64-bit elements" -- " are currently supported"); -- $$.bits = 32; -+ unsigned long long bits; -+ -+ bits = $2; -+ -+ if ((bits != 8) && (bits != 16) && -+ (bits != 32) && (bits != 64)) { -+ ERROR(&@2, "Array elements must be" -+ " 8, 16, 32 or 64-bits"); -+ bits = 32; - } -+ -+ $$.data = empty_data; -+ $$.bits = bits; - } - | '<' - { -@@ -305,9 +318,8 @@ arrayprefix: - * mask), all bits are one. - */ - if (($2 > mask) && (($2 | mask) != -1ULL)) -- print_error( -- "integer value out of range " -- "%016lx (%d bits)", $1.bits); -+ ERROR(&@2, "Value out of range for" -+ " %d-bit array element", $1.bits); - } - - $$.data = data_append_integer($1.data, $2, $1.bits); -@@ -321,7 +333,7 @@ arrayprefix: - REF_PHANDLE, - $2); - else -- print_error("References are only allowed in " -+ ERROR(&@2, "References are only allowed in " - "arrays with 32-bit elements."); - - $$.data = data_append_integer($1.data, val, $1.bits); -@@ -334,13 +346,7 @@ arrayprefix: - - integer_prim: - DT_LITERAL -- { -- $$ = eval_literal($1, 0, 64); -- } - | DT_CHAR_LITERAL -- { -- $$ = eval_char_literal($1); -- } - | '(' integer_expr ')' - { - $$ = $2; -@@ -447,7 +453,7 @@ subnodes: - } - | subnode propdef - { -- print_error("syntax error: properties must precede subnodes"); -+ ERROR(&@2, "Properties must precede subnodes"); - YYERROR; - } - ; -@@ -470,63 +476,7 @@ subnode: - - %% - --void print_error(char const *fmt, ...) --{ -- va_list va; -- -- va_start(va, fmt); -- srcpos_verror(&yylloc, fmt, va); -- va_end(va); -- -- treesource_error = 1; --} -- --void yyerror(char const *s) { -- print_error("%s", s); --} -- --static unsigned long long eval_literal(const char *s, int base, int bits) --{ -- unsigned long long val; -- char *e; -- -- errno = 0; -- val = strtoull(s, &e, base); -- if (*e) { -- size_t uls = strspn(e, "UL"); -- if (e[uls]) -- print_error("bad characters in literal"); -- } -- if ((errno == ERANGE) -- || ((bits < 64) && (val >= (1ULL << bits)))) -- print_error("literal out of range"); -- else if (errno != 0) -- print_error("bad literal"); -- return val; --} -- --static unsigned char eval_char_literal(const char *s) -+void yyerror(char const *s) - { -- int i = 1; -- char c = s[0]; -- -- if (c == '\0') -- { -- print_error("empty character literal"); -- return 0; -- } -- -- /* -- * If the first character in the character literal is a \ then process -- * the remaining characters as an escape encoding. If the first -- * character is neither an escape or a terminator it should be the only -- * character in the literal and will be returned. -- */ -- if (c == '\\') -- c = get_escape_char(s, &i); -- -- if (s[i] != '\0') -- print_error("malformed character literal"); -- -- return c; -+ ERROR(&yylloc, "%s", s); - } -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index e3c9653..0cbb14c 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -48,8 +49,10 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - } - - /* Usage related data. */ -+#define FDT_VERSION(version) _FDT_VERSION(version) -+#define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -67,6 +70,7 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", a_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -82,9 +86,9 @@ static const char * const usage_opts_help[] = { - "\t\tdts - device tree source text\n" - "\t\tdtb - device tree blob\n" - "\t\tasm - assembler source", -- "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); -+ "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", - "\n\tOutput dependency file", -- "\n\ttMake space for reserve map entries (for dtb and asm output)", -+ "\n\tMake space for reserve map entries (for dtb and asm output)", - "\n\tMake the blob at least long (extra space)", - "\n\tAdd padding to the blob of long (extra space)", - "\n\tSet the physical boot cpu", -@@ -97,6 +101,7 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tSymbols and Fixups support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -109,7 +114,7 @@ int main(int argc, char *argv[]) - const char *outform = "dts"; - const char *outname = "-"; - const char *depname = NULL; -- int force = 0, sort = 0; -+ bool force = false, sort = false; - const char *arg; - int opt; - FILE *outf = NULL; -@@ -148,7 +153,7 @@ int main(int argc, char *argv[]) - padsize = strtol(optarg, NULL, 0); - break; - case 'f': -- force = 1; -+ force = true; - break; - case 'q': - quiet++; -@@ -174,7 +179,7 @@ int main(int argc, char *argv[]) - break; - - case 's': -- sort = 1; -+ sort = true; - break; - - case 'W': -@@ -184,7 +189,9 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- -+ case '@': -+ symbol_fixup_support = 1; -+ break; - case 'h': - usage(NULL); - default: -@@ -237,7 +244,7 @@ int main(int argc, char *argv[]) - if (streq(outname, "-")) { - outf = stdout; - } else { -- outf = fopen(outname, "w"); -+ outf = fopen(outname, "wb"); - if (! outf) - die("Couldn't open output file %s: %s\n", - outname, strerror(errno)); -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 264a20c..fe45748 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -38,9 +38,9 @@ - #include "util.h" - - #ifdef DEBUG --#define debug(fmt,args...) printf(fmt, ##args) -+#define debug(...) printf(__VA_ARGS__) - #else --#define debug(fmt,args...) -+#define debug(...) - #endif - - -@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -88,7 +89,7 @@ struct data { - }; - - --#define empty_data ((struct data){ /* all .members = 0 or NULL */ }) -+#define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ }) - - #define for_each_marker(m) \ - for (; (m); (m) = (m)->next) -@@ -118,7 +119,7 @@ struct data data_append_align(struct data d, int align); - - struct data data_add_marker(struct data d, enum markertype type, char *ref); - --int data_is_one_string(struct data d); -+bool data_is_one_string(struct data d); - - /* DT constraints */ - -@@ -127,13 +128,32 @@ int data_is_one_string(struct data d); - - /* Live trees */ - struct label { -- int deleted; -+ bool deleted; - char *label; - struct label *next; - }; - -+struct fixup_entry { -+ int offset; -+ struct node *node; -+ struct property *prop; -+ struct fixup_entry *next; -+}; -+ -+struct fixup { -+ char *ref; -+ struct fixup_entry *entries; -+ struct fixup *next; -+}; -+ -+struct symbol { -+ struct label *label; -+ struct node *node; -+ struct symbol *next; -+}; -+ - struct property { -- int deleted; -+ bool deleted; - char *name; - struct data val; - -@@ -143,7 +163,7 @@ struct property { - }; - - struct node { -- int deleted; -+ bool deleted; - char *name; - struct property *proplist; - struct node *children; -@@ -158,6 +178,12 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -+ -+ int is_root; -+ int is_plugin; -+ struct fixup *fixups; -+ struct symbol *symbols; -+ struct fixup_entry *local_fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -181,6 +207,18 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - -+#define for_each_fixup(n, f) \ -+ for ((f) = (n)->fixups; (f); (f) = (f)->next) -+ -+#define for_each_fixup_entry(f, fe) \ -+ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -+ -+#define for_each_symbol(n, s) \ -+ for ((s) = (n)->symbols; (s); (s) = (s)->next) -+ -+#define for_each_local_fixup_entry(n, fe) \ -+ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -+ - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -@@ -247,8 +285,8 @@ void sort_tree(struct boot_info *bi); - - /* Checks */ - --void parse_checks_option(bool warn, bool error, const char *optarg); --void process_checks(int force, struct boot_info *bi); -+void parse_checks_option(bool warn, bool error, const char *arg); -+void process_checks(bool force, struct boot_info *bi); - - /* Flattened trees */ - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index 665dad7..f439b40 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -261,7 +261,13 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - { - struct property *prop; - struct node *child; -- int seen_name_prop = 0; -+ bool seen_name_prop = false; -+ struct symbol *sym; -+ struct fixup *f; -+ struct fixup_entry *fe; -+ char *name, *s; -+ const char *fullpath; -+ int namesz, nameoff, vallen; - - if (tree->deleted) - return; -@@ -276,10 +282,8 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - emit->align(etarget, sizeof(cell_t)); - - for_each_property(tree, prop) { -- int nameoff; -- - if (streq(prop->name, "name")) -- seen_name_prop = 1; -+ seen_name_prop = true; - - nameoff = stringtable_insert(strbuf, prop->name); - -@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -+ if (!symbol_fixup_support) -+ goto no_symbols; -+ -+ /* add the symbol nodes (if any) */ -+ if (tree->symbols) { -+ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__symbols__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_symbol(tree, sym) { -+ -+ vallen = strlen(sym->node->fullpath); -+ -+ nameoff = stringtable_insert(strbuf, sym->label->label); -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, sym->node->fullpath, -+ strlen(sym->node->fullpath)); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ emit->endnode(etarget, NULL); -+ } -+ -+ /* add the fixup nodes */ -+ if (tree->fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_fixup(tree, f) { -+ -+ namesz = 0; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, -+ fe->prop->name, fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, f->ref); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ } -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+ /* add the local fixup property */ -+ if (tree->local_fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__local_fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ namesz = 0; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, fe->prop->name, -+ fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, "fixup"); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+no_symbols: - emit->endnode(etarget, tree->labels); - } - -diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c -index e464727c..6e5878a 100644 ---- a/scripts/dtc/fstree.c -+++ b/scripts/dtc/fstree.c -@@ -37,26 +37,26 @@ static struct node *read_fstree(const char *dirname) - tree = build_node(NULL, NULL); - - while ((de = readdir(d)) != NULL) { -- char *tmpnam; -+ char *tmpname; - - if (streq(de->d_name, ".") - || streq(de->d_name, "..")) - continue; - -- tmpnam = join_path(dirname, de->d_name); -+ tmpname = join_path(dirname, de->d_name); - -- if (lstat(tmpnam, &st) < 0) -- die("stat(%s): %s\n", tmpnam, strerror(errno)); -+ if (lstat(tmpname, &st) < 0) -+ die("stat(%s): %s\n", tmpname, strerror(errno)); - - if (S_ISREG(st.st_mode)) { - struct property *prop; - FILE *pfile; - -- pfile = fopen(tmpnam, "r"); -+ pfile = fopen(tmpname, "rb"); - if (! pfile) { - fprintf(stderr, - "WARNING: Cannot open %s: %s\n", -- tmpnam, strerror(errno)); -+ tmpname, strerror(errno)); - } else { - prop = build_property(xstrdup(de->d_name), - data_copy_file(pfile, -@@ -67,12 +67,12 @@ static struct node *read_fstree(const char *dirname) - } else if (S_ISDIR(st.st_mode)) { - struct node *newchild; - -- newchild = read_fstree(tmpnam); -+ newchild = read_fstree(tmpname); - newchild = name_node(newchild, xstrdup(de->d_name)); - add_child(tree, newchild); - } - -- free(tmpnam); -+ free(tmpname); - } - - closedir(d); -diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c -index b61465f..e229b84 100644 ---- a/scripts/dtc/livetree.c -+++ b/scripts/dtc/livetree.c -@@ -511,7 +511,9 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) - - struct node *get_node_by_ref(struct node *tree, const char *ref) - { -- if (ref[0] == '/') -+ if (streq(ref, "/")) -+ return tree; -+ else if (ref[0] == '/') - return get_node_by_path(tree, ref); - else - return get_node_by_label(tree, ref); -diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c -index c20bc531..f534c22 100644 ---- a/scripts/dtc/srcpos.c -+++ b/scripts/dtc/srcpos.c -@@ -34,7 +34,7 @@ struct search_path { - static struct search_path *search_path_head, **search_path_tail; - - --static char *dirname(const char *path) -+static char *get_dirname(const char *path) - { - const char *slash = strrchr(path, '/'); - -@@ -77,7 +77,7 @@ static char *try_open(const char *dirname, const char *fname, FILE **fp) - else - fullname = join_path(dirname, fname); - -- *fp = fopen(fullname, "r"); -+ *fp = fopen(fullname, "rb"); - if (!*fp) { - free(fullname); - fullname = NULL; -@@ -150,7 +150,7 @@ void srcfile_push(const char *fname) - srcfile = xmalloc(sizeof(*srcfile)); - - srcfile->f = srcfile_relative_open(fname, &srcfile->name); -- srcfile->dir = dirname(srcfile->name); -+ srcfile->dir = get_dirname(srcfile->name); - srcfile->prev = current_srcfile; - - srcfile->lineno = 1; -@@ -159,7 +159,7 @@ void srcfile_push(const char *fname) - current_srcfile = srcfile; - } - --int srcfile_pop(void) -+bool srcfile_pop(void) - { - struct srcfile_state *srcfile = current_srcfile; - -@@ -177,7 +177,7 @@ int srcfile_pop(void) - * fix this we could either allocate all the files from a - * table, or use a pool allocator. */ - -- return current_srcfile ? 1 : 0; -+ return current_srcfile ? true : false; - } - - void srcfile_add_search_path(const char *dirname) -@@ -290,42 +290,27 @@ srcpos_string(struct srcpos *pos) - return pos_str; - } - --void --srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) -+void srcpos_verror(struct srcpos *pos, const char *prefix, -+ const char *fmt, va_list va) - { -- const char *srcstr; -- -- srcstr = srcpos_string(pos); -+ char *srcstr; - -- fprintf(stderr, "Error: %s ", srcstr); -- vfprintf(stderr, fmt, va); -- fprintf(stderr, "\n"); --} -+ srcstr = srcpos_string(pos); - --void --srcpos_error(struct srcpos *pos, char const *fmt, ...) --{ -- va_list va; -+ fprintf(stderr, "%s: %s ", prefix, srcstr); -+ vfprintf(stderr, fmt, va); -+ fprintf(stderr, "\n"); - -- va_start(va, fmt); -- srcpos_verror(pos, fmt, va); -- va_end(va); -+ free(srcstr); - } - -- --void --srcpos_warn(struct srcpos *pos, char const *fmt, ...) -+void srcpos_error(struct srcpos *pos, const char *prefix, -+ const char *fmt, ...) - { -- const char *srcstr; - va_list va; -- va_start(va, fmt); -- -- srcstr = srcpos_string(pos); -- -- fprintf(stderr, "Warning: %s ", srcstr); -- vfprintf(stderr, fmt, va); -- fprintf(stderr, "\n"); - -+ va_start(va, fmt); -+ srcpos_verror(pos, prefix, fmt, va); - va_end(va); - } - -diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h -index 93a2712..f81827b 100644 ---- a/scripts/dtc/srcpos.h -+++ b/scripts/dtc/srcpos.h -@@ -21,6 +21,7 @@ - #define _SRCPOS_H_ - - #include -+#include - - struct srcfile_state { - FILE *f; -@@ -55,7 +56,7 @@ extern struct srcfile_state *current_srcfile; /* = NULL */ - FILE *srcfile_relative_open(const char *fname, char **fullnamep); - - void srcfile_push(const char *fname); --int srcfile_pop(void); -+bool srcfile_pop(void); - - /** - * Add a new directory to the search path for input files -@@ -106,12 +107,12 @@ extern struct srcpos *srcpos_copy(struct srcpos *pos); - extern char *srcpos_string(struct srcpos *pos); - extern void srcpos_dump(struct srcpos *pos); - --extern void srcpos_verror(struct srcpos *pos, char const *, va_list va) -- __attribute__((format(printf, 2, 0))); --extern void srcpos_error(struct srcpos *pos, char const *, ...) -- __attribute__((format(printf, 2, 3))); --extern void srcpos_warn(struct srcpos *pos, char const *, ...) -- __attribute__((format(printf, 2, 3))); -+extern void srcpos_verror(struct srcpos *pos, const char *prefix, -+ const char *fmt, va_list va) -+ __attribute__((format(printf, 3, 0))); -+extern void srcpos_error(struct srcpos *pos, const char *prefix, -+ const char *fmt, ...) -+ __attribute__((format(printf, 3, 4))); - - extern void srcpos_set_line(char *f, int l); - -diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c -index 5740e69..a146f2d 100644 ---- a/scripts/dtc/treesource.c -+++ b/scripts/dtc/treesource.c -@@ -26,12 +26,12 @@ extern int yyparse(void); - extern YYLTYPE yylloc; - - struct boot_info *the_boot_info; --int treesource_error; -+bool treesource_error; - - struct boot_info *dt_from_source(const char *fname) - { - the_boot_info = NULL; -- treesource_error = 0; -+ treesource_error = false; - - srcfile_push(fname); - yyin = current_srcfile->f; -@@ -54,9 +54,9 @@ static void write_prefix(FILE *f, int level) - fputc('\t', f); - } - --static int isstring(char c) -+static bool isstring(char c) - { -- return (isprint(c) -+ return (isprint((unsigned char)c) - || (c == '\0') - || strchr("\a\b\t\n\v\f\r", c)); - } -@@ -109,7 +109,7 @@ static void write_propval_string(FILE *f, struct data val) - break; - case '\0': - fprintf(f, "\", "); -- while (m && (m->offset < i)) { -+ while (m && (m->offset <= (i + 1))) { - if (m->type == LABEL) { - assert(m->offset == (i+1)); - fprintf(f, "%s: ", m->ref); -@@ -119,7 +119,7 @@ static void write_propval_string(FILE *f, struct data val) - fprintf(f, "\""); - break; - default: -- if (isprint(c)) -+ if (isprint((unsigned char)c)) - fprintf(f, "%c", c); - else - fprintf(f, "\\x%02hhx", c); -@@ -178,7 +178,7 @@ static void write_propval_bytes(FILE *f, struct data val) - m = m->next; - } - -- fprintf(f, "%02hhx", *bp++); -+ fprintf(f, "%02hhx", (unsigned char)(*bp++)); - if ((const void *)bp >= propend) - break; - fprintf(f, " "); -diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c -index 3055c16..9d65226 100644 ---- a/scripts/dtc/util.c -+++ b/scripts/dtc/util.c -@@ -39,11 +39,11 @@ - char *xstrdup(const char *s) - { - int len = strlen(s) + 1; -- char *dup = xmalloc(len); -+ char *d = xmalloc(len); - -- memcpy(dup, s, len); -+ memcpy(d, s, len); - -- return dup; -+ return d; - } - - char *join_path(const char *path, const char *name) -@@ -70,7 +70,7 @@ char *join_path(const char *path, const char *name) - return str; - } - --int util_is_printable_string(const void *data, int len) -+bool util_is_printable_string(const void *data, int len) - { - const char *s = data; - const char *ss, *se; -@@ -87,7 +87,7 @@ int util_is_printable_string(const void *data, int len) - - while (s < se) { - ss = s; -- while (s < se && *s && isprint(*s)) -+ while (s < se && *s && isprint((unsigned char)*s)) - s++; - - /* not zero, or not done yet */ -@@ -219,10 +219,6 @@ int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len) - if (offset == bufsize) { - bufsize *= 2; - buf = xrealloc(buf, bufsize); -- if (!buf) { -- ret = ENOMEM; -- break; -- } - } - - ret = read(fd, &buf[offset], bufsize - offset); -@@ -375,9 +371,9 @@ void utilfdt_print_data(const char *data, int len) - const uint32_t *cell = (const uint32_t *)data; - - printf(" = <"); -- for (i = 0; i < len; i += 4) -+ for (i = 0, len /= 4; i < len; i++) - printf("0x%08x%s", fdt32_to_cpu(cell[i]), -- i < (len - 4) ? " " : ""); -+ i < (len - 1) ? " " : ""); - printf(">"); - } else { - printf(" = ["); -diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h -index 8f40b44..f800b60 100644 ---- a/scripts/dtc/util.h -+++ b/scripts/dtc/util.h -@@ -2,6 +2,7 @@ - #define _UTIL_H - - #include -+#include - #include - - /* -@@ -33,6 +34,7 @@ static inline void __attribute__((noreturn)) die(const char *str, ...) - va_start(ap, str); - fprintf(stderr, "FATAL ERROR: "); - vfprintf(stderr, str, ap); -+ va_end(ap); - exit(1); - } - -@@ -68,7 +70,7 @@ extern char *join_path(const char *path, const char *name); - * @param len The string length including terminator - * @return 1 if a valid printable string, 0 if not - */ --int util_is_printable_string(const void *data, int len); -+bool util_is_printable_string(const void *data, int len); - - /* - * Parse an escaped character starting at index i in string s. The resulting -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 54d4e904..d644002 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.0-dirty" -+#define DTC_VERSION "DTC 1.4.1-g36c70742" - -From 8bddbe464074570457bca032ebee779eb9814d13 Mon Sep 17 00:00:00 2001 +From fe1969c34a172ced7b6091b8d1870e0e69848a24 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 023/204] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 039/113] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to @@ -118008,20 +117166,20 @@ index 0000000..3dff948 + return (($val eq 'y') || ($val eq '1')); +} -From febe480850daa451009a87a3b86278f3d7dbaa10 Mon Sep 17 00:00:00 2001 +From 227f14d8caaaab948771eaafbce7b7f1427f0fe1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 024/204] fdt: Add support for the CONFIG_CMDLINE_EXTEND option +Subject: [PATCH 040/113] fdt: Add support for the CONFIG_CMDLINE_EXTEND option --- drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index d91f721..02feb00 100644 +index 6e82bc42..9d65291 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c -@@ -933,19 +933,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, +@@ -945,19 +945,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, /* Retrieve command line */ p = of_get_flat_dt_prop(node, "bootargs", &l); @@ -118066,10 +117224,10 @@ index d91f721..02feb00 100644 pr_debug("Command line is: %s\n", (char*)data); -From 35658cc32f834e0bad12e6206b7ffb6af9eddbe6 Mon Sep 17 00:00:00 2001 +From 72bc21bd8680d70ebb7bd48303e035bf2b2a63d0 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 025/204] BCM2708: Add core Device Tree support +Subject: [PATCH 041/113] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. @@ -118084,53 +117242,71 @@ but since this is part of an upstreaming effort, the name is changed. Signed-off-by: Noralf Tronnes notro@tronnes.org BCM2708_DT: Correct length of the peripheral space + +Use dts-dirs feature for overlays. + +The kernel makefiles have a dts-dirs target that is for vendor subdirectories. + +Using this fixes the install_dtbs target, which previously did not install the overlays. --- - arch/arm/boot/dts/Makefile | 27 ++ - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 140 ++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 130 ++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 18 + - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 51 +++ - arch/arm/boot/dts/bcm2708.dtsi | 19 + - arch/arm/boot/dts/bcm2708_common.dtsi | 230 ++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 140 ++++++ - arch/arm/boot/dts/bcm2709.dtsi | 70 +++ - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 45 +- - arch/arm/boot/dts/bcm2835-rpi-b.dts | 29 +- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 97 +++- - arch/arm/boot/dts/bcm2835.dtsi | 45 +- - arch/arm/boot/dts/overlays/Makefile | 57 +++ - arch/arm/boot/dts/overlays/README | 493 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 ++++ + arch/arm/boot/dts/Makefile | 30 + + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 134 +++++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 124 ++++ + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 98 +++ + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 30 + + arch/arm/boot/dts/bcm2708.dtsi | 36 ++ + arch/arm/boot/dts/bcm2708_common.dtsi | 321 ++++++++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 134 +++++ + arch/arm/boot/dts/bcm2709.dtsi | 76 +++ + arch/arm/boot/dts/bcm2835-rpi-cm.dts | 93 +++ + arch/arm/boot/dts/bcm2835-rpi-cm.dtsi | 30 + + arch/arm/boot/dts/overlays/Makefile | 71 +++ + arch/arm/boot/dts/overlays/README | 658 +++++++++++++++++++++ + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 +++ .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 +++ + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 ++ + .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 ++ .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 ++++ - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 ++++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 49 ++ + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 +++ + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 +++++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 55 ++ arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 +++ + arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 ++ .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 +++ + .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 69 +++ arch/arm/boot/dts/overlays/mmc-overlay.dts | 19 + - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 109 +++++ - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 ++++ - .../dts/overlays/pitft28-resistive-overlay.dts | 115 +++++ + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 111 ++++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 +++ + .../dts/overlays/pitft28-resistive-overlay.dts | 115 ++++ arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ + arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 46 ++ + arch/arm/boot/dts/overlays/pwm-overlay.dts | 42 ++ + arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++ arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 ++++ + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 +++ + arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 17 + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 78 ++++ - arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 18 + + arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 ++ + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 56 ++ + arch/arm/boot/dts/overlays/sdio-overlay.dts | 29 + + arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + + arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 +++ + arch/arm/boot/dts/overlays/smi-overlay.dts | 37 ++ + arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 25 + arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts | 18 + - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++++ + .../boot/dts/overlays/spi-gpio35-39-overlay.dts | 31 + + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++ + arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 ++ + arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ - 45 files changed, 3316 insertions(+), 54 deletions(-) + 57 files changed, 4159 insertions(+) create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -118139,12 +117315,15 @@ BCM2708_DT: Correct length of the peripheral space create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts create mode 100644 arch/arm/boot/dts/bcm2709.dtsi + create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dts + create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dtsi create mode 100644 arch/arm/boot/dts/overlays/Makefile create mode 100644 arch/arm/boot/dts/overlays/README create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts @@ -118157,31 +117336,45 @@ BCM2708_DT: Correct length of the peripheral space create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 992736b..12de305 100644 +index bb8fa02..68b2c74 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,21 @@ +@@ -1,5 +1,25 @@ ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-cm.dtb +dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb + +# Raspberry Pi @@ -118194,14 +117387,17 @@ index 992736b..12de305 100644 +ifeq ($(CONFIG_ARCH_BCM2835),y) + RPI_DT_OVERLAYS=y +endif ++ifeq ($(RPI_DT_OVERLAYS),y) ++ dts-dirs += overlays ++endif + dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb dtb-$(CONFIG_MACH_ASM9260) += \ -@@ -660,7 +676,18 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt6592-evb.dtb \ +@@ -738,7 +758,17 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8127-moose.dtb \ mt8135-evbp1.dtb + dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb + +targets += dtbs dtbs_install +targets += $(dtb-y) @@ -118209,20 +117405,19 @@ index 992736b..12de305 100644 endif always := $(dtb-y) ++subdir-y := $(dts-dirs) clean-files := *.dtb + +# Enable fixups to support overlays on BCM2708 platforms +ifeq ($(RPI_DT_OVERLAYS),y) + DTC_FLAGS ?= -@ +endif -+ -+subdir-y += overlays diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts new file mode 100644 -index 0000000..0fa2210 +index 0000000..ffb7596 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -0,0 +1,140 @@ +@@ -0,0 +1,134 @@ +/dts-v1/; + +/include/ "bcm2708.dtsi" @@ -118230,33 +117425,19 @@ index 0000000..0fa2210 +/ { + compatible = "brcm,bcm2708"; + model = "Raspberry Pi Model B+"; -+ -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; +}; + +&gpio { + spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; ++ brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; @@ -118288,7 +117469,8 @@ index 0000000..0fa2210 + +&spi0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev@0{ + compatible = "spidev"; @@ -118319,6 +117501,10 @@ index 0000000..0fa2210 + clock-frequency = <100000>; +}; + ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; @@ -118347,8 +117533,11 @@ index 0000000..0fa2210 + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -118365,10 +117554,10 @@ index 0000000..0fa2210 +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts new file mode 100644 -index 0000000..3fd49d0 +index 0000000..8551159 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -0,0 +1,130 @@ +@@ -0,0 +1,124 @@ +/dts-v1/; + +/include/ "bcm2708.dtsi" @@ -118376,33 +117565,19 @@ index 0000000..3fd49d0 +/ { + compatible = "brcm,bcm2708"; + model = "Raspberry Pi Model B"; -+ -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; +}; + +&gpio { + spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; ++ brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; @@ -118415,7 +117590,7 @@ index 0000000..3fd49d0 + + i2s_pins: i2s { + brcm,pins = <28 29 30 31>; -+ brcm,function = <4>; /* alt0 */ ++ brcm,function = <6>; /* alt2 */ + }; +}; + @@ -118434,7 +117609,8 @@ index 0000000..3fd49d0 + +&spi0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev@0{ + compatible = "spidev"; @@ -118465,6 +117641,10 @@ index 0000000..3fd49d0 + clock-frequency = <100000>; +}; + ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; @@ -118487,8 +117667,11 @@ index 0000000..3fd49d0 + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -118501,10 +117684,10 @@ index 0000000..3fd49d0 +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts new file mode 100755 -index 0000000..238bd65 +index 0000000..1f7ec88 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -0,0 +1,18 @@ +@@ -0,0 +1,98 @@ +/dts-v1/; + +/include/ "bcm2708-rpi-cm.dtsi" @@ -118517,41 +117700,100 @@ index 0000000..238bd65 + status = "okay"; +}; + ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ +/ { + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi new file mode 100644 -index 0000000..3da7d3b +index 0000000..713e5a2 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -0,0 +1,51 @@ +@@ -0,0 +1,30 @@ +/include/ "bcm2708.dtsi" + -+/ { -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ +&leds { + act_led: act { + label = "led0"; @@ -118569,23 +117811,23 @@ index 0000000..3da7d3b + status = "okay"; +}; + -+&audio { -+ status = "okay"; -+}; -+ +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi new file mode 100644 -index 0000000..0d47427 +index 0000000..0bea715 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -0,0 +1,19 @@ +@@ -0,0 +1,36 @@ +/include/ "bcm2708_common.dtsi" + +/ { @@ -118600,22 +117842,65 @@ index 0000000..0d47427 + soc { + ranges = <0x7e000000 0x20000000 0x01000000>; + ++ timer@7e003000 { ++ compatible = "brcm,bcm2835-system-timer"; ++ reg = <0x7e003000 0x1000>; ++ interrupts = <1 0>, <1 1>, <1 2>, <1 3>; ++ clock-frequency = <1000000>; ++ }; ++ + arm-pmu { + compatible = "arm,arm1176-pmu"; + }; ++ ++ gpiomem { ++ compatible = "brcm,bcm2835-gpiomem"; ++ reg = <0x7e200000 0x1000>; ++ status = "okay"; ++ }; + }; +}; ++ ++&intc { ++ compatible = "brcm,bcm2835-armctrl-ic"; ++}; diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi new file mode 100644 -index 0000000..8caa234 +index 0000000..5d9081a --- /dev/null +++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -0,0 +1,230 @@ +@@ -0,0 +1,321 @@ +/include/ "skeleton.dtsi" + +/ { + interrupt-parent = <&intc>; + ++ aliases { ++ audio = &audio; ++ sound = &sound; ++ soc = &soc; ++ dma = &dma; ++ intc = &intc; ++ watchdog = &watchdog; ++ random = &random; ++ mailbox = &mailbox; ++ gpio = &gpio; ++ uart0 = &uart0; ++ i2s = &i2s; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ uart1 = &uart1; ++ mmc = &mmc; ++ i2c1 = &i2c1; ++ i2c2 = &i2c2; ++ usb = &usb; ++ leds = &leds; ++ fb = &fb; ++ vchiq = &vchiq; ++ thermal = &thermal; ++ clocks = &clocks; ++ }; ++ + /* Onboard audio */ + audio: audio { + compatible = "brcm,bcm2835-audio"; @@ -118623,6 +117908,10 @@ index 0000000..8caa234 + status = "disabled"; + }; + ++ /* External sound card */ ++ sound: sound { ++ }; ++ + soc: soc { + compatible = "simple-bus"; + #address-cells = <1>; @@ -118642,20 +117931,26 @@ index 0000000..8caa234 + <1 24>, + <1 25>, + <1 26>, -+ <1 27>, -+ <1 28>; ++ <1 27>; + + #dma-cells = <1>; -+ brcm,dma-channel-mask = <0x7f35>; ++ brcm,dma-channel-mask = <0x0f35>; + }; + -+ intc: interrupt-controller { ++ intc: interrupt-controller@7e00b200 { + compatible = "brcm,bcm2708-armctrl-ic"; + reg = <0x7e00b200 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2835-mbox"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ #mbox-cells = <0>; ++ }; ++ + watchdog: watchdog@7e100000 { + compatible = "brcm,bcm2835-pm-wdt"; + reg = <0x7e100000 0x28>; @@ -118668,13 +117963,7 @@ index 0000000..8caa234 + status = "disabled"; + }; + -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ -+ gpio: gpio { ++ gpio: gpio@7e200000 { + compatible = "brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; + interrupts = <2 17>, <2 18>; @@ -118686,17 +117975,6 @@ index 0000000..8caa234 + #interrupt-cells = <2>; + }; + -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ + uart0: uart@7e201000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201000 0x1000>; @@ -118710,8 +117988,8 @@ index 0000000..8caa234 + + i2s: i2s@7e203000 { + compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; ++ reg = <0x7e203000 0x24>, ++ <0x7e101098 0x08>; + + //dmas = <&dma 2>, + // <&dma 3>; @@ -118723,7 +118001,7 @@ index 0000000..8caa234 + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x1000>; + interrupts = <2 22>; -+ clocks = <&clk_spi>; ++ clocks = <&clk_core>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; @@ -118747,16 +118025,35 @@ index 0000000..8caa234 + status = "disabled"; + }; + ++ pwm: pwm@7e20c000 { ++ compatible = "brcm,bcm2835-pwm"; ++ reg = <0x7e20c000 0x28>; ++ clocks = <&clk_pwm>; ++ #pwm-cells = <2>; ++ status = "disabled"; ++ }; ++ + uart1: uart@7e215040 { + compatible = "brcm,bcm2835-aux-uart", "ns16550"; + reg = <0x7e215040 0x40>; + interrupts = <1 29>; -+ clock-frequency = <500000000>; ++ clocks = <&clk_uart1>; + reg-shift = <2>; + no-loopback-test; + status = "disabled"; + }; + ++ mmc: mmc@7e300000 { ++ compatible = "brcm,bcm2835-mmc"; ++ reg = <0x7e300000 0x100>; ++ interrupts = <2 30>; ++ clocks = <&clk_mmc>; ++ dmas = <&dma 11>, ++ <&dma 11>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ + i2c1: i2c@7e804000 { + compatible = "brcm,bcm2708-i2c"; + reg = <0x7e804000 0x1000>; @@ -118767,6 +118064,30 @@ index 0000000..8caa234 + status = "disabled"; + }; + ++ i2c2: i2c@7e805000 { ++ // Beware - this is shared with the HDMI module. ++ // Careless use may break (really) your display. ++ // Caveat emptor. ++ compatible = "brcm,bcm2708-i2c"; ++ reg = <0x7e805000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clk_i2c>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ smi: smi@7e600000 { ++ compatible = "brcm,bcm2835-smi"; ++ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; ++ interrupts = <2 16>; ++ brcm,smi-clock-source = <6>; ++ brcm,smi-clock-divisor = <4>; ++ dmas = <&dma 4>; ++ dma-names = "rx-tx"; ++ status = "disabled"; ++ }; ++ + usb: usb@7e980000 { + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000>, @@ -118775,12 +118096,18 @@ index 0000000..8caa234 + <1 9>; + }; + ++ firmware: firmware { ++ compatible = "raspberrypi,bcm2835-firmware"; ++ mboxes = <&mailbox>; ++ }; ++ + leds: leds { + compatible = "gpio-leds"; + }; + + fb: fb { + compatible = "brcm,bcm2708-fb"; ++ firmware = <&firmware>; + status = "disabled"; + }; + @@ -118788,10 +118115,13 @@ index 0000000..8caa234 + compatible = "brcm,bcm2835-vchiq"; + reg = <0x7e00b840 0xf>; + interrupts = <0 2>; ++ cache-line-size = <32>; ++ firmware = <&firmware>; + }; + + thermal: thermal { + compatible = "brcm,bcm2835-thermal"; ++ firmware = <&firmware>; + }; + }; + @@ -118816,11 +118146,11 @@ index 0000000..8caa234 + clock-frequency = <250000000>; + }; + -+ clk_spi: clock@2 { ++ clk_core: clock@2 { + compatible = "fixed-clock"; + reg = <2>; + #clock-cells = <0>; -+ clock-output-names = "spi"; ++ clock-output-names = "core"; + clock-frequency = <250000000>; + }; + @@ -118839,14 +118169,34 @@ index 0000000..8caa234 + clock-output-names = "apb_pclk"; + clock-frequency = <126000000>; + }; ++ ++ clk_pwm: clock@5 { ++ compatible = "fixed-clock"; ++ reg = <3>; ++ #clock-cells = <0>; ++ clock-output-names = "pwm"; ++ clock-frequency = <100000000>; ++ }; ++ ++ clk_uart1: clock@6 { ++ compatible = "fixed-factor-clock"; ++ clocks = <&clk_core>; ++ #clock-cells = <0>; ++ clock-div = <1>; ++ clock-mult = <2>; ++ }; ++ }; ++ ++ __overrides__ { ++ cache_line_size = <&vchiq>, "cache-line-size:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts new file mode 100644 -index 0000000..8aaaf1f +index 0000000..7a05dab5 --- /dev/null +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -0,0 +1,140 @@ +@@ -0,0 +1,134 @@ +/dts-v1/; + +/include/ "bcm2709.dtsi" @@ -118854,33 +118204,19 @@ index 0000000..8aaaf1f +/ { + compatible = "brcm,bcm2709"; + model = "Raspberry Pi 2 Model B"; -+ -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ audio = &audio; -+ sound = &sound; -+ uart0 = &uart0; -+ uart1 = &uart1; -+ clocks = &clocks; -+ }; -+ -+ sound: sound { -+ }; +}; + +&gpio { + spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; ++ brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; @@ -118912,7 +118248,8 @@ index 0000000..8aaaf1f + +&spi0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev@0{ + compatible = "spidev"; @@ -118943,6 +118280,10 @@ index 0000000..8aaaf1f + clock-frequency = <100000>; +}; + ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; @@ -118971,8 +118312,11 @@ index 0000000..8aaaf1f + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -118989,10 +118333,10 @@ index 0000000..8aaaf1f +}; diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi new file mode 100644 -index 0000000..5e0b935 +index 0000000..811d825 --- /dev/null +++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -0,0 +1,70 @@ +@@ -0,0 +1,76 @@ +/include/ "bcm2708_common.dtsi" + +/ { @@ -119011,6 +118355,12 @@ index 0000000..5e0b935 + compatible = "arm,cortex-a7-pmu"; + interrupts = <3 9>; + }; ++ ++ gpiomem { ++ compatible = "brcm,bcm2835-gpiomem"; ++ reg = <0x7e200000 0x1000>; ++ status = "okay"; ++ }; + }; + + timer { @@ -119063,183 +118413,44 @@ index 0000000..5e0b935 + <&v7_cpu3>, "clock-frequency:0"; + }; +}; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index e479515..b0fb0e8 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -4,27 +4,40 @@ - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; - model = "Raspberry Pi Model B+"; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm.dts b/arch/arm/boot/dts/bcm2835-rpi-cm.dts +new file mode 100644 +index 0000000..c6e6860a +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2835-rpi-cm.dts +@@ -0,0 +1,93 @@ ++/dts-v1/; ++ ++#include "bcm2835-rpi-cm.dtsi" ++ ++/ { ++ model = "Raspberry Pi Compute Module"; ++}; ++ ++&uart0 { ++ status = "okay"; +}; + +&gpio { -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; - -- leds { -- act { -- gpios = <&gpio 47 0>; -- }; -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 47 0>; -+}; - -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; -+&leds { -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; - }; - }; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - -- /* I2S interface */ -- i2s_alt0: i2s_alt0 { -- brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index bafa46f..b867224 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -5,19 +5,28 @@ - compatible = "raspberrypi,model-b", "brcm,bcm2835"; - model = "Raspberry Pi Model B"; - -- leds { -- act { -- gpios = <&gpio 16 1>; -- }; -- }; - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; -- -- /* I2S interface */ -- i2s_alt2: i2s_alt2 { -+ i2s_pins: i2s { - brcm,pins = <28 29 30 31>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 16 1>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index c706448..466f02b 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -1,51 +1,112 @@ - /include/ "bcm2835.dtsi" - - / { -+ /* This is left here in case u-boot needs it */ - memory { - reg = <0 0x10000000>; - }; - -- leds { -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ sound = &sound; -+ }; -+ -+ leds: leds { - compatible = "gpio-leds"; - -- act { -- label = "ACT"; -- default-state = "keep"; -- linux,default-trigger = "heartbeat"; -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; - }; - }; -+ -+ /* Onboard audio */ -+ audio: audio { -+ compatible = "brcm,bcm2835-audio"; -+ brcm,pwm-channels = <8>; -+ status = "disabled"; -+ }; -+ -+ /* External sound card */ -+ sound: sound { -+ }; - }; - - &gpio { -- pinctrl-names = "default"; + spi0_pins: spi0_pins { + brcm,pins = <7 8 9 10 11>; + brcm,function = <4>; /* alt0 */ + }; - -- gpioout: gpioout { -- brcm,pins = <6>; -- brcm,function = <1>; /* GPIO out */ ++ + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; - }; - -- alt0: alt0 { -- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; -- brcm,function = <4>; /* alt0 */ ++ }; ++ + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; +}; + +&spi0 { @@ -119252,39 +118463,75 @@ index c706448..466f02b 100644 + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <500000>; - }; - -- alt3: alt3 { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <7>; /* alt3 */ ++ }; ++ + spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <500000>; - }; - }; - - &i2c0 { -- status = "okay"; ++ }; ++}; ++ ++&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; - clock-frequency = <100000>; - }; - - &i2c1 { -- status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; - clock-frequency = <100000>; - }; - --&sdhci { ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1_clkrate = <&uart1>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm.dtsi +new file mode 100644 +index 0000000..9c4000f +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2835-rpi-cm.dtsi +@@ -0,0 +1,30 @@ ++#include "bcm2835.dtsi" ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++}; ++ +&mmc { - status = "okay"; - bus-width = <4>; - }; ++ status = "okay"; ++ bus-width = <4>; ++}; + +&fb { + status = "okay"; @@ -119292,144 +118539,21 @@ index c706448..466f02b 100644 + +/ { + __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; ++ + audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; +}; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 3342cb1..4b6dd65f 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -6,14 +6,15 @@ - interrupt-parent = <&intc>; - - chosen { -- bootargs = "earlyprintk console=ttyAMA0"; -+ bootargs = ""; - }; - -- soc { -+ soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x7e000000 0x20000000 0x02000000>; -+ dma-ranges = <0x40000000 0x00000000 0x20000000>; - - timer@7e003000 { - compatible = "brcm,bcm2835-system-timer"; -@@ -50,16 +51,22 @@ - #interrupt-cells = <2>; - }; - -- watchdog@7e100000 { -+ watchdog: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm-wdt"; - reg = <0x7e100000 0x28>; - }; - -- rng@7e104000 { -+ random: rng@7e104000 { - compatible = "brcm,bcm2835-rng"; - reg = <0x7e104000 0x10>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - gpio: gpio@7e200000 { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; -@@ -83,7 +90,7 @@ - #interrupt-cells = <2>; - }; - -- uart@7e201000 { -+ uart0: uart@7e201000 { - compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; - interrupts = <2 25>; -@@ -102,7 +109,7 @@ - status = "disabled"; - }; - -- spi: spi@7e204000 { -+ spi0: spi@7e204000 { - compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; -@@ -122,11 +129,14 @@ - status = "disabled"; - }; - -- sdhci: sdhci@7e300000 { -- compatible = "brcm,bcm2835-sdhci"; -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; - reg = <0x7e300000 0x100>; - interrupts = <2 30>; - clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; - status = "disabled"; - }; - -@@ -140,7 +150,7 @@ - status = "disabled"; - }; - -- usb@7e980000 { -+ usb: usb@7e980000 { - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; -@@ -149,6 +159,21 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ status = "disabled"; -+ }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ }; - }; - - clocks { -@@ -161,7 +186,7 @@ - reg = <0>; - #clock-cells = <0>; - clock-output-names = "mmc"; -- clock-frequency = <100000000>; -+ clock-frequency = <250000000>; - }; - - clk_i2c: clock@1 { diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile new file mode 100644 -index 0000000..6947556 +index 0000000..9411ec8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,57 @@ +@@ -0,0 +1,71 @@ +ifeq ($(CONFIG_OF),y) + +# Overlays for the Raspberry Pi platform @@ -119448,6 +118572,7 @@ index 0000000..6947556 +dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb @@ -119460,18 +118585,31 @@ index 0000000..6947556 +dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb +dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb + @@ -119489,10 +118627,10 @@ index 0000000..6947556 +endif diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README new file mode 100644 -index 0000000..3e08f98 +index 0000000..6a9b270 --- /dev/null +++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,493 @@ +@@ -0,0 +1,658 @@ +Introduction +============ + @@ -119569,11 +118707,15 @@ index 0000000..3e08f98 +The Overlay and Parameter Reference +=================================== + ++N.B. When editing this file, please preserve the indentation levels to make it simple to parse ++programmatically. NO HARD TABS. ++ ++ +Name: +Info: Configures the base Raspberry Pi hardware +Load: +Params: -+ audio Set to "on" to disable the onboard ALSA audio ++ audio Set to "on" to enable the onboard ALSA audio + interface (default "off") + + i2c_arm Set to "on" to enable the ARM's i2c interface @@ -119668,6 +118810,14 @@ index 0000000..3e08f98 +Params: + + ++Name: dht11 ++Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors ++ Also sometimes found with the part number(s) AM230x. ++Load: dtoverlay=dht11,= ++Params: gpiopin GPIO connected to the sensor's DATA output. ++ (default 4) ++ ++ +[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] + + @@ -119679,6 +118829,19 @@ index 0000000..3e08f98 + speed SPI bus speed (default 12000000) + + ++Name: gpio-poweroff ++Info: Drives a GPIO high or low on reboot ++Load: gpio-poweroff,= ++Params: gpiopin GPIO for signalling (default 26) ++ ++ active_low Set if the power control device requires a ++ high->low transition to trigger a power-down. ++ Note that this will require the support of a ++ custom dt-blob.bin to prevent a power-down ++ during the boot process, and that a reboot ++ will also cause the pin to go low. ++ ++ +Name: hifiberry-amp +Info: Configures the HifiBerry Amp and Amp+ audio cards +Load: dtoverlay=hifiberry-amp @@ -119748,6 +118911,8 @@ index 0000000..3e08f98 + + ds3231 Select the DS3231 device + ++ mcp7941x Select the MCP7941x device ++ + pcf2127 Select the PCF2127 device + + pcf8523 Select the PCF8523 device @@ -119755,6 +118920,12 @@ index 0000000..3e08f98 + pcf8563 Select the PCF8563 device + + ++Name: i2s-mmap ++Info: Enables mmap support in the bcm2708-i2s driver ++Load: dtoverlay=i2s-mmap ++Params: ++ ++ +Name: iqaudio-dac +Info: Configures the IQaudio DAC audio card +Load: dtoverlay=iqaudio-dac @@ -119779,8 +118950,8 @@ index 0000000..3e08f98 + (default "down") + + sense Override the IR receive auto-detection logic: -+ "1" = force active high -+ "0" = force active low ++ "0" = force active-high ++ "1" = force active-low + "-1" = use auto-detection + (default "-1") + @@ -119794,7 +118965,7 @@ index 0000000..3e08f98 + + +Name: mcp2515-can0 -+Info: Configures the MCP2515 CAN controller ++Info: Configures the MCP2515 CAN controller on spi0.0 +Load: dtoverlay=mcp2515-can0,= +Params: oscillator Clock frequency for the CAN controller (Hz) + @@ -119803,6 +118974,16 @@ index 0000000..3e08f98 + interrupt GPIO for interrupt signal + + ++Name: mcp2515-can1 ++Info: Configures the MCP2515 CAN controller on spi0.1 ++Load: dtoverlay=mcp2515-can1,= ++Params: oscillator Clock frequency for the CAN controller (Hz) ++ ++ spimaxfrequency Maximum SPI frequence (Hz) ++ ++ interrupt GPIO for interrupt signal ++ ++ +Name: mmc +Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock +Load: dtoverlay=mmc,= @@ -119820,6 +119001,8 @@ index 0000000..3e08f98 + + fps Delay between frame updates + ++ txbuflen Transmit buffer length (default 32768) ++ + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) @@ -119866,6 +119049,53 @@ index 0000000..3e08f98 +Params: gpiopin Input GPIO (default "18") + + ++Name: pwm ++Info: Configures a single PWM channel ++ Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++ 4) Currently the clock must have been enabled and configured ++ by other means. ++Load: dtoverlay=pwm-2chan,= ++Load: dtoverlay=pwm,= ++Params: pin Output pin (default 18) - see table ++ func Pin function (default 2 = Alt5) - see above ++ clock PWM clock frequency (informational) ++ ++ ++Name: pwm-2chan ++Info: Configures both PWM channels ++ Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++ 4) Currently the clock must have been enabled and configured ++ by other means. ++Load: dtoverlay=pwm-2chan,= ++Params: pin Output pin (default 18) - see table ++ pin2 Output pin for other channel (default 19) ++ func Pin function (default 2 = Alt5) - see above ++ func2 Function for pin2 (default 2 = Alt5) ++ clock PWM clock frequency (informational) ++ ++ ++Name: raspidac3 ++Info: Configures the RaspiDAV Rev.3x audio card ++Load: dtoverlay=raspidac3 ++Params: ++ ++ +Name: rpi-dac +Info: Configures the RPi DAC audio card +Load: dtoverlay=rpi-dac @@ -119886,18 +119116,69 @@ index 0000000..3e08f98 + xohms Touchpanel sensitivity (X-plate resistance) + + ++Name: rpi-ft5406 ++Info: Official Raspberry Pi display touchscreen ++Load: dtoverlay=rpi-ft5406 ++Params: ++ ++ +Name: rpi-proto +Info: Configures the RPi Proto audio card +Load: dtoverlay=rpi-proto +Params: + + ++Name: rpi-sense ++Info: Raspberry Pi Sense HAT ++Load: dtoverlay=rpi-sense ++Params: ++ ++ +Name: sdhost +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock +Load: dtoverlay=sdhost,= +Params: overclock_50 Clock (in MHz) to use when the MMC framework + requests 50MHz -+ force_pio Disable DMA support ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) ++ ++ ++Name: sdio ++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, ++ and enables SDIO via GPIOs 22-27. ++Load: dtoverlay=sdio,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) ++ ++ ++Name: smi ++Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! ++Load: dtoverlay=smi ++Params: ++ ++ ++Name: smi-dev ++Info: Enables the userspace interface for the SMI driver ++Load: dtoverlay=smi-dev ++Params: ++ ++ ++Name: smi-nand ++Info: Enables access to NAND flash via the SMI interface ++Load: dtoverlay=smi-nand ++Params: + + +Name: spi-bcm2708 @@ -119912,6 +119193,12 @@ index 0000000..3e08f98 +Params: + + ++Name: spi-gpio35-39 ++Info: move SPI function block to GPIO 35 to 39 ++Load: dtoverlay=spi-gpio35-39 ++Params: ++ ++ +Name: tinylcd35 +Info: 3.5" Color TFT Display by www.tinylcd.com + Options: Touch, RTC, keypad @@ -119943,6 +119230,22 @@ index 0000000..3e08f98 + dtoverlay=tinylcd35,touch,touchgpio=3 + + ++Name: uart1 ++Info: Enable uart1 in place of uart0 ++Load: dtoverlay=uart1,= ++Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) ++ ++ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) ++ ++ ++Name: vga666 ++Info: Overlay for the Fen Logic VGA666 board ++ This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds ++ after the kernel has started. ++Load: dtoverlay=vga666 ++Params: ++ ++ +Name: w1-gpio +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *don't* need a GPIO to drive an external pullup. @@ -120077,7 +119380,7 @@ index 0000000..6a92cd1 +}; diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts new file mode 100644 -index 0000000..b830bf2 +index 0000000..782b171 --- /dev/null +++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts @@ -0,0 +1,23 @@ @@ -120089,7 +119392,7 @@ index 0000000..b830bf2 + compatible = "brcm,bcm2708"; + + fragment@0 { -+ target = <&i2c1>; ++ target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; @@ -120205,6 +119508,46 @@ index 0000000..8fae869 + speed = <ð1>, "spi-max-frequency:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts +new file mode 100644 +index 0000000..ff8cb36 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts +@@ -0,0 +1,34 @@ ++// Definitions for gpio-poweroff module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ power_ctrl: power_ctrl { ++ compatible = "gpio-poweroff"; ++ gpios = <&gpio 26 0>; ++ force; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ power_ctrl_pins: power_ctrl_pins { ++ brcm,pins = <26>; ++ brcm,function = <1>; // out ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&power_ctrl>,"gpios:4", ++ <&power_ctrl_pins>,"brcm,pins:0"; ++ active_low = <&power_ctrl>,"gpios:8"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts new file mode 100644 index 0000000..2c81448 @@ -120623,10 +119966,10 @@ index 0000000..f774c4a +}; diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts new file mode 100644 -index 0000000..6bccfdc +index 0000000..fed4bd8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -0,0 +1,49 @@ +@@ -0,0 +1,55 @@ +// Definitions for several I2C based Real Time Clocks +/dts-v1/; +/plugin/; @@ -120635,7 +119978,7 @@ index 0000000..6bccfdc + compatible = "brcm,bcm2708"; + + fragment@0 { -+ target = <&i2c1>; ++ target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; @@ -120646,6 +119989,11 @@ index 0000000..6bccfdc + reg = <0x68>; + status = "disable"; + }; ++ mcp7941x: mcp7941x@6f { ++ compatible = "microchip,mcp7941x"; ++ reg = <0x6f>; ++ status = "disable"; ++ }; + ds3231: ds3231@68 { + compatible = "maxim,ds3231"; + reg = <0x68>; @@ -120671,6 +120019,7 @@ index 0000000..6bccfdc + __overrides__ { + ds1307 = <&ds1307>,"status"; + ds3231 = <&ds3231>,"status"; ++ mcp7941x = <&mcp7941x>,"status"; + pcf2127 = <&pcf2127>,"status"; + pcf8523 = <&pcf8523>,"status"; + pcf8563 = <&pcf8563>,"status"; @@ -120923,6 +120272,81 @@ index 0000000..398d59c + interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts +new file mode 100644 +index 0000000..6bef9ae +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts +@@ -0,0 +1,69 @@ ++/* ++ * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* disable spi-dev for spi0.1 */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ can1_pins: can1_pins { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* input */ ++ }; ++ }; ++ }; ++ ++ /* the clock/oscillator of the can-controller */ ++ fragment@2 { ++ target-path = "/clocks"; ++ __overlay__ { ++ /* external oscillator of mcp2515 on spi0.1 */ ++ can1_osc: can1_osc { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <16000000>; ++ }; ++ }; ++ }; ++ ++ /* the spi config of the can-controller itself binding everything together */ ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ can1: mcp2515@1 { ++ reg = <1>; ++ compatible = "microchip,mcp2515"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can1_pins>; ++ spi-max-frequency = <10000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 0x2>; ++ clocks = <&can1_osc>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ oscillator = <&can1_osc>,"clock-frequency:0"; ++ spimaxfrequency = <&can1>,"spi-max-frequency:0"; ++ interrupt = <&can1_pins>,"brcm,pins:0",<&can1>,"interrupts:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts new file mode 100644 index 0000000..0a37cf4 @@ -120950,10 +120374,10 @@ index 0000000..0a37cf4 +}; diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts new file mode 100644 -index 0000000..c06fe12 +index 0000000..9242a6e --- /dev/null +++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -0,0 +1,109 @@ +@@ -0,0 +1,111 @@ +/* + * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec + * @@ -121013,6 +120437,7 @@ index 0000000..c06fe12 + bgr; + fps = <30>; + buswidth = <8>; ++ txbuflen = <32768>; + + reset-gpios = <&gpio 15 0>; + dc-gpios = <&gpio 25 0>; @@ -121059,6 +120484,7 @@ index 0000000..c06fe12 + speed = <&mz61581>, "spi-max-frequency:0"; + rotate = <&mz61581>, "rotate:0"; + fps = <&mz61581>, "fps:0"; ++ txbuflen = <&mz61581>, "txbuflen:0"; + debug = <&mz61581>, "debug:0"; + xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; + }; @@ -121326,6 +120752,157 @@ index 0000000..40bf0e1 + <&pps_pins>,"brcm,pins:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts +new file mode 100644 +index 0000000..957e1a4 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts +@@ -0,0 +1,46 @@ ++/dts-v1/; ++/plugin/; ++ ++/* ++This is the 2-channel overlay - only use it if you need both channels. ++ ++Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ ++N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++*/ ++ ++/ { ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ pwm_pins: pwm_pins { ++ brcm,pins = <18 19>; ++ brcm,function = <2 2>; /* Alt5 */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ pin = <&pwm_pins>,"brcm,pins:0"; ++ pin2 = <&pwm_pins>,"brcm,pins:4"; ++ func = <&pwm_pins>,"brcm,function:0"; ++ func2 = <&pwm_pins>,"brcm,function:4"; ++ clock = <&clk_pwm>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts +new file mode 100644 +index 0000000..ddd67ff +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/* ++Legal pin,function combinations for each channel: ++ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) ++ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) ++ ++N.B.: ++ 1) Pin 18 is the only one available on all platforms, and ++ it is the one used by the I2S audio interface. ++ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. ++ 2) The onboard analogue audio output uses both PWM channels. ++ 3) So be careful mixing audio and PWM. ++*/ ++ ++/ { ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ pwm_pins: pwm_pins { ++ brcm,pins = <18>; ++ brcm,function = <2>; /* Alt5 */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ pin = <&pwm_pins>,"brcm,pins:0"; ++ func = <&pwm_pins>,"brcm,function:0"; ++ clock = <&clk_pwm>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts +new file mode 100644 +index 0000000..1bd8054 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts +@@ -0,0 +1,45 @@ ++// Definitions for RaspiDACv3 ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "jg,raspidacv3"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ status = "okay"; ++ }; ++ ++ tpa6130a2: tpa6130a2@60 { ++ compatible = "ti,tpa6130a2"; ++ reg = <0x60>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts new file mode 100644 index 0000000..7fc6ac9 @@ -121454,6 +121031,29 @@ index 0000000..a8fa974 + xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts +new file mode 100644 +index 0000000..2e53a17 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts +@@ -0,0 +1,17 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ rpi_ft5406: rpi_ft5406 { ++ compatible = "rpi,rpi-ft5406"; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts new file mode 100644 index 0000000..2029930 @@ -121499,12 +121099,65 @@ index 0000000..2029930 + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +new file mode 100644 +index 0000000..2715324 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +@@ -0,0 +1,47 @@ ++// rpi-sense HAT ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ rpi-sense@46 { ++ compatible = "rpi,rpi-sense"; ++ reg = <0x46>; ++ keys-int-gpios = <&gpio 23 1>; ++ status = "okay"; ++ }; ++ ++ lsm9ds1-magn@1c { ++ compatible = "st,lsm9ds1-magn"; ++ reg = <0x1c>; ++ status = "okay"; ++ }; ++ ++ lsm9ds1-accel6a { ++ compatible = "st,lsm9ds1-accel"; ++ reg = <0x6a>; ++ status = "okay"; ++ }; ++ ++ lps25h-press@5c { ++ compatible = "st,lps25h-press"; ++ reg = <0x5c>; ++ status = "okay"; ++ }; ++ ++ hts221-humid@5f { ++ compatible = "st,hts221-humid"; ++ reg = <0x5f>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts new file mode 100644 -index 0000000..8fb28e9 +index 0000000..2da14a4 --- /dev/null +++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -0,0 +1,78 @@ +@@ -0,0 +1,56 @@ +/dts-v1/; +/plugin/; + @@ -121523,34 +121176,19 @@ index 0000000..8fb28e9 + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_pins>; + interrupts = <2 24>; -+ clocks = <&clk_sdhost>; ++ clocks = <&clk_core>; + dmas = <&dma 13>, + <&dma 13>; + dma-names = "tx", "rx"; + brcm,delay-after-stop = <0>; + brcm,overclock-50 = <0>; ++ brcm,pio-limit = <1>; + status = "okay"; + }; + }; + }; + + fragment@1 { -+ target = <&clocks>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_sdhost: sdhost { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { + target = <&gpio>; + __overlay__ { + sdhost_pins: sdhost_pins { @@ -121560,7 +121198,7 @@ index 0000000..8fb28e9 + }; + }; + -+ fragment@3 { ++ fragment@2 { + target = <&mmc>; + __overlay__ { + /* Find a way to disable the other driver */ @@ -121569,28 +121207,198 @@ index 0000000..8fb28e9 + }; + }; + -+ fragment@4 { -+ target-path = "/__overrides__"; ++ __overrides__ { ++ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; ++ force_pio = <&sdhost>,"brcm,force-pio?"; ++ pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ debug = <&sdhost>,"brcm,debug?"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts +new file mode 100644 +index 0000000..164f269 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts +@@ -0,0 +1,29 @@ ++/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ ++ ++/include/ "sdhost-overlay.dts" ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@3 { ++ target = <&mmc>; + __overlay__ { -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ compatible = "brcm,bcm2835-mmc"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ status = "okay"; + }; + }; + -+ __overrides__ { -+ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; -+ force_pio = <&sdhost>,"brcm,force-pio?"; -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ sdio_pins: sdio_pins { ++ brcm,pins = <22 23 24 25 26 27>; ++ brcm,function = <7 7 7 7 7 7>; /* ALT3 = SD1 */ ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/smi-dev-overlay.dts b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts +new file mode 100644 +index 0000000..b610d82 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts +@@ -0,0 +1,18 @@ ++// Description: Overlay to enable character device interface for SMI. ++// Author: Luke Wren ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ fragment@0 { ++ target = <&soc>; ++ __overlay__ { ++ smi_dev { ++ compatible = "brcm,bcm2835-smi-dev"; ++ smi_handle = <&smi>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/smi-nand-overlay.dts b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts +new file mode 100644 +index 0000000..13ce0b7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts +@@ -0,0 +1,69 @@ ++// Description: Overlay to enable NAND flash through ++// the secondary memory interface ++// Author: Luke Wren ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&smi>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&smi_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&soc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ nand: flash@0 { ++ compatible = "brcm,bcm2835-smi-nand"; ++ smi_handle = <&smi>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "okay"; ++ ++ partition@0 { ++ label = "stage2"; ++ // 128k ++ reg = <0 0x20000>; ++ read-only; ++ }; ++ partition@1 { ++ label = "firmware"; ++ // 16M ++ reg = <0x20000 0x1000000>; ++ read-only; ++ }; ++ partition@2 { ++ label = "root"; ++ // 2G (will need to use 64 bit for >=4G) ++ reg = <0x1020000 0x80000000>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ smi_pins: smi_pins { ++ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 ++ 12 13 14 15>; ++ /* Alt 1: SMI */ ++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 ++ 5 5 5 5 5>; ++ /* /CS, /WE and /OE are pulled high, as they are ++ generally active low signals */ ++ brcm,pull = <2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/smi-overlay.dts b/arch/arm/boot/dts/overlays/smi-overlay.dts +new file mode 100644 +index 0000000..095f52c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/smi-overlay.dts +@@ -0,0 +1,37 @@ ++// Description: Overlay to enable the secondary memory interface peripheral ++// Author: Luke Wren ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&smi>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&smi_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ smi_pins: smi_pins { ++ /* Don't configure the top two address bits, as ++ these are already used as ID_SD and ID_SC */ ++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 ++ 16 17 18 19 20 21 22 23 24 25>; ++ /* Alt 0: SMI */ ++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 ++ 5 5 5 5 5 5 5 5 5>; ++ /* /CS, /WE and /OE are pulled high, as they are ++ generally active low signals */ ++ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0>; ++ }; ++ }; + }; +}; diff --git a/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts new file mode 100644 -index 0000000..e378ef1 +index 0000000..688163e --- /dev/null +++ b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts -@@ -0,0 +1,18 @@ +@@ -0,0 +1,25 @@ +/* -+ * Device tree overlay for spi-bcm2835 ++ * Device tree overlay to use spi-bcm2708 + */ + +/dts-v1/; @@ -121606,6 +121414,13 @@ index 0000000..e378ef1 + compatible = "brcm,bcm2708-spi"; + }; + }; ++ ++ fragment@1 { ++ target = <&spi0_cs_pins>; ++ __overlay__ { ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; +}; diff --git a/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts new file mode 100644 @@ -121631,6 +121446,43 @@ index 0000000..fc1e39b + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts b/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts +new file mode 100644 +index 0000000..9648063 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts +@@ -0,0 +1,31 @@ ++/* ++ * Device tree overlay to move spi0 to gpio 35 to 39 on CM ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ cs-gpios = <&gpio 36 1>, <&gpio 35 1>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0_cs_pins>; ++ __overlay__ { ++ bcrm,pins = <36 35>; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0_pins>; ++ __overlay__ { ++ bcrm,pins = <37 38 39>; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts new file mode 100644 index 0000000..f7102c8 @@ -121853,6 +121705,86 @@ index 0000000..f7102c8 + keypad = <&keypad>,"status"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/uart1-overlay.dts b/arch/arm/boot/dts/overlays/uart1-overlay.dts +new file mode 100644 +index 0000000..fa73e1f +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/uart1-overlay.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ uart1_pins: uart1_pins { ++ brcm,pins = <14 15>; ++ brcm,function = <2>; /* alt5 */ ++ brcm,pull = <0 2>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/chosen"; ++ __overlay__ { ++ bootargs = "8250.nr_uarts=1"; ++ }; ++ }; ++ ++ __overrides__ { ++ txd1_pin = <&uart1_pins>,"brcm,pins:0"; ++ rxd1_pin = <&uart1_pins>,"brcm,pins:4"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/vga666-overlay.dts b/arch/arm/boot/dts/overlays/vga666-overlay.dts +new file mode 100644 +index 0000000..7fcab96 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/vga666-overlay.dts +@@ -0,0 +1,30 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ // There is no VGA driver module, but we need a platform device ++ // node (that doesn't already use pinctrl) to hang the pinctrl ++ // reference on - leds will do ++ ++ fragment@0 { ++ target = <&leds>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vga666_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ vga666_pins: vga666_pins { ++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 ++ 13 14 15 16 17 18 19 20 21>; ++ brcm,function = <6>; /* alt2 */ ++ brcm,pull = <0>; /* no pull */ ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts new file mode 100644 index 0000000..29a3b48 @@ -121946,10 +121878,518 @@ index 0000000..66a98f6 + }; +}; -From 7c4a63015f03594469922e65ae613bbc4e54c4cf Mon Sep 17 00:00:00 2001 +From 541b02ecaaf01ae1750f67762a52caa30e182f0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:47:07 +0200 +Subject: [PATCH 042/113] bcm2835: Match with BCM2708 Device Trees +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 132 ++++++++++++++++++++--- + arch/arm/boot/dts/bcm2835-rpi-b.dts | 117 ++++++++++++++++++-- + arch/arm/boot/dts/bcm2835.dtsi | 179 +++---------------------------- + 3 files changed, 234 insertions(+), 194 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +index 668442b..17e2443 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +@@ -1,30 +1,128 @@ + /dts-v1/; +-#include "bcm2835-rpi.dtsi" ++#include "bcm2835.dtsi" + + / { + compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; + model = "Raspberry Pi Model B+"; ++}; + +- leds { +- act { +- gpios = <&gpio 47 0>; +- }; ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; + +- pwr { +- label = "PWR"; +- gpios = <&gpio 35 0>; +- default-state = "keep"; +- linux,default-trigger = "default-on"; +- }; ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; + }; +-}; + +-&gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; + +- /* I2S interface */ +- i2s_alt0: i2s_alt0 { ++ i2s_pins: i2s { + brcm,pins = <18 19 20 21>; +- brcm,function = ; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&gpio 35 0>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1_clkrate = <&uart1>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts +index ee89b79..221d252 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts +@@ -1,23 +1,118 @@ + /dts-v1/; +-#include "bcm2835-rpi.dtsi" ++#include "bcm2835.dtsi" + + / { + compatible = "raspberrypi,model-b", "brcm,bcm2835"; + model = "Raspberry Pi Model B"; +- +- leds { +- act { +- gpios = <&gpio 16 1>; +- }; +- }; + }; + + &gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; + +- /* I2S interface */ +- i2s_alt2: i2s_alt2 { ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { + brcm,pins = <28 29 30 31>; +- brcm,function = ; ++ brcm,function = <6>; /* alt2 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 16 1>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1_clkrate = <&uart1>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index 440717c..3256bff 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -1,20 +1,15 @@ +-#include +-#include "skeleton.dtsi" ++#include "bcm2708_common.dtsi" + + / { + compatible = "brcm,bcm2835"; + model = "BCM2835"; +- interrupt-parent = <&intc>; + + chosen { +- bootargs = "earlyprintk console=ttyAMA0"; ++ bootargs = ""; + }; + + soc { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <1>; +- ranges = <0x7e000000 0x20000000 0x02000000>; ++ ranges = <0x7e000000 0x20000000 0x01000000>; + dma-ranges = <0x40000000 0x00000000 0x20000000>; + + timer@7e003000 { +@@ -24,169 +19,21 @@ + clock-frequency = <1000000>; + }; + +- dma: dma@7e007000 { +- compatible = "brcm,bcm2835-dma"; +- reg = <0x7e007000 0xf00>; +- interrupts = <1 16>, +- <1 17>, +- <1 18>, +- <1 19>, +- <1 20>, +- <1 21>, +- <1 22>, +- <1 23>, +- <1 24>, +- <1 25>, +- <1 26>, +- <1 27>, +- <1 28>; +- +- #dma-cells = <1>; +- brcm,dma-channel-mask = <0x7f35>; +- }; +- +- intc: interrupt-controller@7e00b200 { +- compatible = "brcm,bcm2835-armctrl-ic"; +- reg = <0x7e00b200 0x200>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- watchdog@7e100000 { +- compatible = "brcm,bcm2835-pm-wdt"; +- reg = <0x7e100000 0x28>; +- }; +- +- rng@7e104000 { +- compatible = "brcm,bcm2835-rng"; +- reg = <0x7e104000 0x10>; +- }; +- +- mailbox: mailbox@7e00b800 { +- compatible = "brcm,bcm2835-mbox"; +- reg = <0x7e00b880 0x40>; +- interrupts = <0 1>; +- #mbox-cells = <0>; +- }; +- +- gpio: gpio@7e200000 { +- compatible = "brcm,bcm2835-gpio"; +- reg = <0x7e200000 0xb4>; +- /* +- * The GPIO IP block is designed for 3 banks of GPIOs. +- * Each bank has a GPIO interrupt for itself. +- * There is an overall "any bank" interrupt. +- * In order, these are GIC interrupts 17, 18, 19, 20. +- * Since the BCM2835 only has 2 banks, the 2nd bank +- * interrupt output appears to be mirrored onto the +- * 3rd bank's interrupt signal. +- * So, a bank0 interrupt shows up on 17, 20, and +- * a bank1 interrupt shows up on 18, 19, 20! +- */ +- interrupts = <2 17>, <2 18>, <2 19>, <2 20>; +- +- gpio-controller; +- #gpio-cells = <2>; +- +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- uart@7e201000 { +- compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; +- reg = <0x7e201000 0x1000>; +- interrupts = <2 25>; +- clock-frequency = <3000000>; +- arm,primecell-periphid = <0x00241011>; +- }; +- +- i2s: i2s@7e203000 { +- compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x24>, +- <0x7e101098 0x08>; +- +- dmas = <&dma 2>, +- <&dma 3>; +- dma-names = "tx", "rx"; +- status = "disabled"; +- }; +- +- spi: spi@7e204000 { +- compatible = "brcm,bcm2835-spi"; +- reg = <0x7e204000 0x1000>; +- interrupts = <2 22>; +- clocks = <&clk_spi>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c0: i2c@7e205000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e205000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clk_i2c>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- sdhci: sdhci@7e300000 { +- compatible = "brcm,bcm2835-sdhci"; +- reg = <0x7e300000 0x100>; +- interrupts = <2 30>; +- clocks = <&clk_mmc>; +- status = "disabled"; +- }; +- +- i2c1: i2c@7e804000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e804000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clk_i2c>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- usb@7e980000 { +- compatible = "brcm,bcm2835-usb"; +- reg = <0x7e980000 0x10000>; +- interrupts = <1 9>; +- }; +- + arm-pmu { + compatible = "arm,arm1176-pmu"; + }; +- }; +- +- clocks { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <0>; + +- clk_mmc: clock@0 { +- compatible = "fixed-clock"; +- reg = <0>; +- #clock-cells = <0>; +- clock-output-names = "mmc"; +- clock-frequency = <100000000>; ++ aux_enable: aux_enable@0x7e215004 { ++ compatible = "bcrm,bcm2835-aux-enable"; ++ reg = <0x7e215004 0x04>; + }; ++ }; ++}; + +- clk_i2c: clock@1 { +- compatible = "fixed-clock"; +- reg = <1>; +- #clock-cells = <0>; +- clock-output-names = "i2c"; +- clock-frequency = <250000000>; +- }; ++&intc { ++ compatible = "brcm,bcm2835-armctrl-ic"; ++}; + +- clk_spi: clock@2 { +- compatible = "fixed-clock"; +- reg = <2>; +- #clock-cells = <0>; +- clock-output-names = "spi"; +- clock-frequency = <250000000>; +- }; +- }; ++&watchdog { ++ status = "okay"; + }; + +From 8e5d720e6c22fbc27f237c408ca9b3db2f182642 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 026/204] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 043/113] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -122042,10 +122482,10 @@ index fb795c3..fa72af0 100644 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ -From 4f1485790c96ee05b7fd08c23905f8957c8f2b61 Mon Sep 17 00:00:00 2001 +From e436037ad20fd0ef86290ad974e05c97a386a749 Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 029/204] Speed up console framebuffer imageblit function +Subject: [PATCH 046/113] Speed up console framebuffer imageblit function Especially on platforms with a slower CPU but a relatively high framebuffer fill bandwidth, like current ARM devices, the existing @@ -122254,10 +122694,10 @@ index a2bb276..436494f 100644 start_index, pitch_index); } else -From efd2fa9ef6e7848d0494f1a66d46e9280d507f4e Mon Sep 17 00:00:00 2001 +From 400e3b5c2e9b41c1d5f10446e1dfa6e02941c637 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 030/204] Allow mac address to be set in smsc95xx +Subject: [PATCH 047/113] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -122265,7 +122705,7 @@ Signed-off-by: popcornmix 1 file changed, 56 insertions(+) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 26423ad..e29a323 100644 +index 477b9c7..08a8a8c 100755 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -59,6 +59,7 @@ @@ -122276,7 +122716,7 @@ index 26423ad..e29a323 100644 struct smsc95xx_priv { u32 mac_cr; -@@ -74,6 +75,10 @@ static bool turbo_mode = true; +@@ -74,6 +75,10 @@ static bool turbo_mode = false; module_param(turbo_mode, bool, 0644); MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); @@ -122348,10 +122788,10 @@ index 26423ad..e29a323 100644 if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -From 625c18792c5c8272af5237599d44d852e0996bdf Mon Sep 17 00:00:00 2001 +From ffc945ed1ba5066ef8298a21ee1ad24d58bb3aa4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 031/204] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 048/113] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -122381,10 +122821,10 @@ w1-gpio: Sort out the pullup/parasitic power tangle 7 files changed, 157 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 26be516..55d2889 100644 +index 7dc0cc7..239ac46 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -36,6 +36,7 @@ +@@ -37,6 +37,7 @@ #include #include #include @@ -122392,7 +122832,7 @@ index 26be516..55d2889 100644 #include #include -@@ -77,12 +78,19 @@ +@@ -78,12 +79,19 @@ */ #define DMA_MASK_BITS_COMMON 32 @@ -122412,7 +122852,7 @@ index 26be516..55d2889 100644 static bool vc_i2c_override = false; static unsigned use_dt = 0; -@@ -303,6 +311,20 @@ static struct platform_device bcm2708_dmaengine_device = { +@@ -307,6 +315,20 @@ static struct platform_device bcm2708_dmaengine_device = { .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), }; @@ -122433,7 +122873,7 @@ index 26be516..55d2889 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -729,6 +751,11 @@ void __init bcm2708_init(void) +@@ -717,6 +739,11 @@ void __init bcm2708_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -122445,7 +122885,7 @@ index 26be516..55d2889 100644 bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); -@@ -942,5 +969,7 @@ module_param(uart_clock, uint, 0644); +@@ -927,5 +954,7 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); @@ -122454,7 +122894,7 @@ index 26be516..55d2889 100644 module_param(vc_i2c_override, bool, 0644); MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 50843df..0a5e4188 100644 +index 7d70eeb..b0b2186 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -36,6 +36,7 @@ @@ -122506,7 +122946,7 @@ index 50843df..0a5e4188 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -749,6 +771,11 @@ void __init bcm2709_init(void) +@@ -734,6 +756,11 @@ void __init bcm2709_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -122518,7 +122958,7 @@ index 50843df..0a5e4188 100644 bcm_register_device_dt(&bcm2708_fb_device); bcm_register_device_dt(&bcm2708_usb_device); -@@ -1110,5 +1137,7 @@ module_param(uart_clock, uint, 0644); +@@ -1101,5 +1128,7 @@ module_param(uart_clock, uint, 0644); module_param(disk_led_gpio, uint, 0644); module_param(disk_led_active_low, uint, 0644); module_param(reboot_part, uint, 0644); @@ -122749,10 +123189,35 @@ index d58594a..feae942 100644 unsigned int ext_pullup_enable_pin; unsigned int pullup_duration; -From 8b7527453528e339a4586eec937857f1b994daae Mon Sep 17 00:00:00 2001 +From c46444a0debf11dffd3a986deec638126701a0c0 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 3 Jul 2013 00:54:08 +0100 +Subject: [PATCH 049/113] Added Device IDs for August DVB-T 205 + +--- + drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +index 197a4f2..9d1a3d7 100644 +--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c ++++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +@@ -1898,6 +1898,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = { + &rtl28xxu_props, "Compro VideoMate U620F", NULL) }, + { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394, + &rtl28xxu_props, "MaxMedia HU394-T", NULL) }, ++ { DVB_USB_DEVICE(USB_VID_GTEK, 0xb803 /*USB_PID_AUGUST_DVBT205*/, ++ &rtl28xxu_props, "August DVB-T 205", NULL) }, ++ { DVB_USB_DEVICE(USB_VID_GTEK, 0xa803 /*USB_PID_AUGUST_DVBT205*/, ++ &rtl28xxu_props, "August DVB-T 205", NULL) }, + { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03, + &rtl28xxu_props, "Leadtek WinFast DTV Dongle mini", NULL) }, + { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A, + +From d19297b133390e93cd127767466826e9a55a8c5d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 033/204] config: Enable CONFIG_MEMCG, but leave it disabled +Subject: [PATCH 050/113] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- @@ -122761,10 +123226,10 @@ Subject: [PATCH 033/204] config: Enable CONFIG_MEMCG, but leave it disabled 2 files changed, 24 insertions(+) diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index 4d65b66..dd258ff 100644 +index 2c9eae6..4253b1c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5394,6 +5394,29 @@ static int __init cgroup_disable(char *str) +@@ -5551,6 +5551,29 @@ static int __init cgroup_disable(char *str) } __setup("cgroup_disable=", cgroup_disable); @@ -122795,10 +123260,10 @@ index 4d65b66..dd258ff 100644 { printk("cgroup: using legacy files on the default hierarchy\n"); diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 68dea90..6fd0c4f 100644 +index c57c442..32afce5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c -@@ -5389,6 +5389,7 @@ struct cgroup_subsys memory_cgrp_subsys = { +@@ -5226,6 +5226,7 @@ struct cgroup_subsys memory_cgrp_subsys = { .dfl_cftypes = memory_files, .legacy_cftypes = mem_cgroup_legacy_files, .early_init = 0, @@ -122807,10 +123272,10 @@ index 68dea90..6fd0c4f 100644 /** -From 727594aaa8ab739ea1c22eca69bf5400948af0d1 Mon Sep 17 00:00:00 2001 +From 391a663c1fa4ca5c3be13b04fa1c9db147bd1d95 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:33:38 +0100 -Subject: [PATCH 034/204] ASoC: Add support for BCM2708 +Subject: [PATCH 051/113] ASoC: Add support for BCM2708 This driver adds support for digital audio (I2S) for the BCM2708 SoC that is used by the @@ -123953,60 +124418,61 @@ index 0000000..6fdcbc1 + +#endif -From c0c7b62d38423b62ad3223b79f7f60802c6c1e5c Mon Sep 17 00:00:00 2001 +From ff45c8f704d2377bfc82b461cdc9ea2e7ba3f367 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 035/204] ASoC: Add support for PCM5102A codec +Subject: [PATCH 052/113] ASoC: Add support for PCM5102A codec Some definitions to support the PCM5102A codec by Texas Instruments. Signed-off-by: Florian Meier --- - sound/soc/codecs/Kconfig | 4 +++ + sound/soc/codecs/Kconfig | 5 ++++ sound/soc/codecs/Makefile | 2 ++ sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 69 insertions(+) + 3 files changed, 70 insertions(+) create mode 100644 sound/soc/codecs/pcm5102a.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 061c465..a3d70f9 100644 +index 0c9733e..f0b3e31 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -83,6 +83,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_I2C if I2C +@@ -87,6 +87,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM512x_SPI if SPI_MASTER select SND_SOC_RT286 if I2C + select SND_SOC_RT298 if I2C + select SND_SOC_PCM5102A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -511,6 +512,9 @@ config SND_SOC_RT286 +@@ -540,6 +541,10 @@ config SND_SOC_RT298 tristate depends on I2C +config SND_SOC_PCM5102A + tristate ++ depends on I2C + config SND_SOC_RT5631 tristate "Realtek ALC5631/RT5631 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index abe2d7e..a0fda52 100644 +index 4a32077..03cf632 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o +@@ -83,6 +83,7 @@ snd-soc-rl6231-objs := rl6231.o + snd-soc-rl6347a-objs := rl6347a.o snd-soc-rt286-objs := rt286.o + snd-soc-rt298-objs := rt298.o +snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o -@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o +@@ -275,6 +276,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o + obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o +obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o @@ -124081,10 +124547,10 @@ index 0000000..126f1e9 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 0f2fff9145ec3742650115b422b3fa4983002668 Mon Sep 17 00:00:00 2001 +From 3462291b4f4cdb89a8b69b113dc141b1160e5cd0 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:04:54 +0100 -Subject: [PATCH 036/204] BCM2708: Add I2S support to board file +Subject: [PATCH 053/113] BCM2708: Add I2S support to board file Adds the required initializations for I2S to the board file of mach-bcm2708. @@ -124098,16 +124564,18 @@ when some problems were found. Add the ability to enable this feature through Device Tree, using the i2s-mmap overlay. See: #1004 + +bcm2708-i2s: Don't use static pin configuration with DT --- arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ - sound/soc/bcm/bcm2708-i2s.c | 7 ++++++- - 2 files changed, 32 insertions(+), 1 deletion(-) + sound/soc/bcm/bcm2708-i2s.c | 11 ++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 55d2889..01f2de7 100644 +index 239ac46..c8e2550 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -616,6 +616,28 @@ static struct platform_device bcm2835_thermal_device = { +@@ -605,6 +605,28 @@ static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; @@ -124136,7 +124604,7 @@ index 55d2889..01f2de7 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -780,6 +802,10 @@ void __init bcm2708_init(void) +@@ -774,6 +796,10 @@ void __init bcm2708_init(void) bcm_register_device_dt(&bcm2835_thermal_device); @@ -124148,9 +124616,20 @@ index 55d2889..01f2de7 100644 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c -index a3b65dc..a515992 100644 +index a3b65dc..5e93cd6 100644 --- a/sound/soc/bcm/bcm2708-i2s.c +++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -409,8 +409,8 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, + if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) + return 0; + +- +- bcm2708_i2s_setup_gpio(); ++ if (!dev->dev->of_node) ++ bcm2708_i2s_setup_gpio(); + + /* + * Adjust the data length according to the format. @@ -874,7 +874,7 @@ static const struct snd_soc_component_driver bcm2708_i2s_component = { .name = "bcm2708-i2s-comp", }; @@ -124173,10 +124652,10 @@ index a3b65dc..a515992 100644 for (i = 0; i <= 1; i++) { void __iomem *base; -From b7db156b7135bd8023bc2e553fa802f10b33df21 Mon Sep 17 00:00:00 2001 +From 741d8118e27ad41b7b3909a106417a16b53c51f0 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 037/204] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 054/113] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -124325,24 +124804,32 @@ index 0000000..4b70b45 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From c48e1b97199c72f611b2f0937d36bc98a7169bba Mon Sep 17 00:00:00 2001 +From d660417bd278c6c6aa2653b7871663b5c6dfd3fa Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 038/204] BCM2708: Add HifiBerry DAC to board file +Subject: [PATCH 055/113] BCM2708: Add HifiBerry DAC to board file This adds the initalization of the HifiBerry DAC to the mach-bcm2708 board file. Signed-off-by: Florian Meier --- - arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) + arch/arm/mach-bcm2708/bcm2708.c | 38 ++++++++++++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/Kconfig | 9 ++++ + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ + 7 files changed, 217 insertions(+) + create mode 100644 sound/soc/bcm/rpi-dac.c + create mode 100644 sound/soc/codecs/pcm1794a.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 01f2de7..1d9b788 100644 +index c8e2550..639a921 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -638,6 +638,20 @@ static struct platform_device bcm2708_i2s_device = { +@@ -627,6 +627,34 @@ static struct platform_device bcm2708_i2s_device = { }; #endif @@ -124360,50 +124847,6 @@ index 01f2de7..1d9b788 100644 +}; +#endif + - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -806,6 +820,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2708_i2s_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_dac_device); -+ bcm_register_device_dt(&snd_pcm5102a_codec_device); -+#endif -+ - if (!use_dt) { - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - -From 46355bc118b045051f833c56844bba4b71b6b666 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 6 Dec 2013 20:50:28 +0100 -Subject: [PATCH 039/204] ASoC: BCM2708: Add support for RPi-DAC - -This adds a machine driver for the RPi-DAC. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ - sound/soc/codecs/Kconfig | 4 ++ - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ - 7 files changed, 193 insertions(+) - create mode 100644 sound/soc/bcm/rpi-dac.c - create mode 100644 sound/soc/codecs/pcm1794a.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 1d9b788..6d53beb 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - +#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) +static struct platform_device snd_rpi_dac_device = { + .name = "snd-rpi-dac", @@ -124421,10 +124864,15 @@ index 1d9b788..6d53beb 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -825,6 +839,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); +@@ -800,6 +828,16 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&bcm2708_i2s_device); #endif ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); ++#endif ++ +#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + bcm_register_device_dt(&snd_rpi_dac_device); + bcm_register_device_dt(&snd_pcm1794a_codec_device); @@ -124564,43 +125012,48 @@ index 0000000..6d6e0ba +MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index a3d70f9..dc3df1a 100644 +index f0b3e31..26eb019 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -84,6 +84,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_SPI if SPI_MASTER +@@ -88,6 +88,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_RT286 if I2C + select SND_SOC_RT298 if I2C select SND_SOC_PCM5102A if I2C + select SND_SOC_PCM1794A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -512,6 +513,9 @@ config SND_SOC_RT286 +@@ -541,6 +542,14 @@ config SND_SOC_RT298 tristate depends on I2C ++config SND_SOC_RT298 ++ tristate ++ depends on I2C ++ +config SND_SOC_PCM1794A + tristate ++ depends on I2C + config SND_SOC_PCM5102A tristate - + depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index a0fda52..c1f6ba6 100644 +index 03cf632..4e3c82c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o +@@ -83,6 +83,7 @@ snd-soc-rl6231-objs := rl6231.o + snd-soc-rl6347a-objs := rl6347a.o snd-soc-rt286-objs := rt286.o + snd-soc-rt298-objs := rt298.o +snd-soc-pcm1794a-objs := pcm1794a.o snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o -@@ -264,6 +265,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o +@@ -276,6 +277,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o + obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o +obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o @@ -124674,10 +125127,10 @@ index 0000000..b4eaa44 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 81991e83d009ef30b23b0f7190042479293aa418 Mon Sep 17 00:00:00 2001 +From a230f7f4f62b82120df5020e601ba11bd8ef47db Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 040/204] ASoC: wm8804: Implement MCLK configuration options, +Subject: [PATCH 056/113] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -124696,7 +125149,7 @@ Signed-off-by: Daniel Matuschek 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index 1e403f6..d4efa85 100644 +index 8d91470..5795fb1 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -304,6 +304,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream, @@ -124717,10 +125170,10 @@ index 1e403f6..d4efa85 100644 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ -From bf20cf45c9c208ff4a47465f3297196806b95da7 Mon Sep 17 00:00:00 2001 +From 09c44630d974be667f45b436501546dfe4fbbe0e Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 041/204] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 057/113] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -124985,10 +125438,10 @@ index 0000000..92e9e46 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From ebfceb0a7d6a4854618c00339d571421b7a18b68 Mon Sep 17 00:00:00 2001 +From fb0efafb4fd008c9e727e73d94824638551b81ef Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:26:08 +0100 -Subject: [PATCH 042/204] BCM2708: Added support for HiFiBerry Digi board Board +Subject: [PATCH 058/113] BCM2708: Added support for HiFiBerry Digi board Board initalization by I2C Signed-off-by: Daniel Matuschek @@ -124997,10 +125450,10 @@ Signed-off-by: Daniel Matuschek 1 file changed, 20 insertions(+) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6d53beb..a062d7f 100644 +index 639a921..2310319 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -652,6 +652,21 @@ static struct platform_device snd_pcm5102a_codec_device = { +@@ -641,6 +641,21 @@ static struct platform_device snd_pcm5102a_codec_device = { }; #endif @@ -125022,7 +125475,7 @@ index 6d53beb..a062d7f 100644 #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) static struct platform_device snd_rpi_dac_device = { .name = "snd-rpi-dac", -@@ -839,6 +854,11 @@ void __init bcm2708_init(void) +@@ -833,6 +848,11 @@ void __init bcm2708_init(void) bcm_register_device_dt(&snd_pcm5102a_codec_device); #endif @@ -125035,10 +125488,10 @@ index 6d53beb..a062d7f 100644 bcm_register_device_dt(&snd_rpi_dac_device); bcm_register_device_dt(&snd_pcm1794a_codec_device); -From b9597317ed9afa6fe3712758c0ad5d1b11766d60 Mon Sep 17 00:00:00 2001 +From 15928fd3c8fbfe8a384a345f42c7b4cfdb698433 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 043/204] ASoC: wm8804: Set idle_bias_off to false Idle bias +Subject: [PATCH 059/113] ASoC: wm8804: Set idle_bias_off to false Idle bias has been change to remove warning on driver startup Signed-off-by: Daniel Matuschek @@ -125047,7 +125500,7 @@ Signed-off-by: Daniel Matuschek 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index d4efa85..f3f26a2 100644 +index 5795fb1..c846716 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -544,7 +544,7 @@ static struct snd_soc_dai_driver wm8804_dai = { @@ -125060,10 +125513,10 @@ index d4efa85..f3f26a2 100644 .dapm_widgets = wm8804_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), -From 098e66a4235451ad64c8bc1349496fc68a0e16fc Mon Sep 17 00:00:00 2001 +From 9325f6c5023801d4d5786f96e8472039ca1720e3 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 044/204] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 060/113] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control @@ -125080,10 +125533,10 @@ limit of 0dB for this control. create mode 100644 sound/soc/bcm/iqaudio-dac.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a062d7f..a51a6168 100644 +index 2310319..6ed7299 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -681,6 +681,22 @@ static struct platform_device snd_pcm1794a_codec_device = { +@@ -670,6 +670,22 @@ static struct platform_device snd_pcm1794a_codec_device = { }; #endif @@ -125106,7 +125559,7 @@ index a062d7f..a51a6168 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -864,6 +880,11 @@ void __init bcm2708_init(void) +@@ -858,6 +874,11 @@ void __init bcm2708_init(void) bcm_register_device_dt(&snd_pcm1794a_codec_device); #endif @@ -125271,40 +125724,10 @@ index 0000000..aff7377 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From a2878cc4a414348ab3b5be3ad44f04ae8e77e3ab Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 045/204] vmstat: Workaround for issue where dirty page count - goes negative - -See: -https://github.com/raspberrypi/linux/issues/617 -http://www.spinics.net/lists/linux-mm/msg72236.html ---- - include/linux/vmstat.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 82e7db7..f87d16d 100644 ---- a/include/linux/vmstat.h -+++ b/include/linux/vmstat.h -@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) - static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) - { - atomic_long_dec(&zone->vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) -+ atomic_long_set(&zone->vm_stat[item], 0); - atomic_long_dec(&vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) -+ atomic_long_set(&vm_stat[item], 0); - } - - static inline void __inc_zone_page_state(struct page *page, - -From 0fb0113068c3d68d396dff09129369bd7719bb41 Mon Sep 17 00:00:00 2001 +From 559a146d1da68a1e9683f63056cec7fed3f4da33 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 046/204] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 061/113] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -125312,7 +125735,7 @@ Reduces overhead when using X 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c -index eab5bd6..ca47de9 100644 +index 36712e9..910fa89 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -49,7 +49,7 @@ @@ -125324,7 +125747,7 @@ index eab5bd6..ca47de9 100644 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -@@ -1090,8 +1090,12 @@ static int usbhid_start(struct hid_device *hid) +@@ -1091,8 +1091,12 @@ static int usbhid_start(struct hid_device *hid) } /* Change the polling interval of mice. */ @@ -125340,10 +125763,10 @@ index eab5bd6..ca47de9 100644 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From b5950dd391670c2090ca047af33ba1f5b330b272 Mon Sep 17 00:00:00 2001 +From f0502b1601d05a391735161c83200f95ea52e20c Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 047/204] Added support for HiFiBerry DAC+ +Subject: [PATCH 062/113] Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. @@ -125356,10 +125779,10 @@ a different codec chip (PCM5122), therefore a new driver is necessary. create mode 100644 sound/soc/bcm/hifiberry_dacplus.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a51a6168..d421a89 100644 +index 6ed7299..6c60e73 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { +@@ -641,6 +641,20 @@ static struct platform_device snd_pcm5102a_codec_device = { }; #endif @@ -125380,7 +125803,7 @@ index a51a6168..d421a89 100644 #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) static struct platform_device snd_hifiberry_digi_device = { .name = "snd-hifiberry-digi", -@@ -870,6 +884,11 @@ void __init bcm2708_init(void) +@@ -864,6 +878,11 @@ void __init bcm2708_init(void) bcm_register_device_dt(&snd_pcm5102a_codec_device); #endif @@ -125554,10 +125977,10 @@ index 0000000..c63387b +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); +MODULE_LICENSE("GPL v2"); -From 83ead1b240ffde9c9c592533b4b116ae721e6893 Mon Sep 17 00:00:00 2001 +From fa5f1fc1410ed46d94108f38a4288adb2e9e37a7 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 048/204] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 063/113] Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. @@ -125587,10 +126010,10 @@ Some code to load the driver based on device-tree-overlays was missing. This is create mode 100644 sound/soc/codecs/tas5713.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index d421a89..363b9c5 100644 +index 6c60e73..f1d853f 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -681,6 +681,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { +@@ -670,6 +670,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { #endif @@ -125611,7 +126034,7 @@ index d421a89..363b9c5 100644 #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) static struct platform_device snd_rpi_dac_device = { .name = "snd-rpi-dac", -@@ -894,6 +908,11 @@ void __init bcm2708_init(void) +@@ -888,6 +902,11 @@ void __init bcm2708_init(void) i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); #endif @@ -125793,10 +126216,10 @@ index 0000000..5903915 +MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index dc3df1a..8a9f07c 100644 +index 26eb019..097f006 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -109,6 +109,7 @@ config SND_SOC_ALL_CODECS +@@ -115,6 +115,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TFA9879 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER @@ -125804,7 +126227,7 @@ index dc3df1a..8a9f07c 100644 select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC31XX if I2C select SND_SOC_TLV320AIC32X4 if I2C -@@ -623,6 +624,9 @@ config SND_SOC_TFA9879 +@@ -665,6 +666,9 @@ config SND_SOC_TFA9879 tristate "NXP Semiconductors TFA9879 amplifier" depends on I2C @@ -125815,20 +126238,20 @@ index dc3df1a..8a9f07c 100644 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index c1f6ba6..8ebf7f1 100644 +index 4e3c82c..dc731db 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -109,6 +109,7 @@ snd-soc-sta529-objs := sta529.o - snd-soc-stac9766-objs := stac9766.o +@@ -116,6 +116,7 @@ snd-soc-sti-sas-objs := sti-sas.o snd-soc-tas5086-objs := tas5086.o + snd-soc-tas571x-objs := tas571x.o snd-soc-tfa9879-objs := tfa9879.o +snd-soc-tas5713-objs := tas5713.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o -@@ -293,6 +294,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o - obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o +@@ -307,6 +308,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o + obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o +obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o @@ -126426,10 +126849,10 @@ index 0000000..8f019e0 + +#endif /* _TAS5713_H */ -From d78d9b666c8a7fb477945825a161505701e11b28 Mon Sep 17 00:00:00 2001 +From ffd6c106bad201223f5cefd49c0db215b6b3205c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Apr 2015 19:14:18 +0100 -Subject: [PATCH 049/204] bcm2708: Allow option card devices to be configured +Subject: [PATCH 064/113] bcm2708: Allow option card devices to be configured via DT If the kernel is built with Device Tree support, and if a DT blob @@ -126442,7 +126865,7 @@ support code with each new device. 1 file changed, 1 insertion(+) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 03fa1cb..c816526 100644 +index 8c435be..5a75f4b 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { @@ -126451,13 +126874,13 @@ index 03fa1cb..c816526 100644 }; +MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); - static struct platform_driver bcm2835_i2s_driver = { - .probe = bcm2835_i2s_probe, + MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); + -From 0cf6cbc05769deca2546837472623fc4e7b56c11 Mon Sep 17 00:00:00 2001 +From 946e47edf2f42b7dea5f19b618c4985eed389597 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 18:45:39 +0100 -Subject: [PATCH 050/204] Adding Device Tree support for some RPi audio cards +Subject: [PATCH 065/113] Adding Device Tree support for some RPi audio cards --- arch/arm/mach-bcm2709/bcm2709.c | 143 ++++++++++++++++++++++++++++++++++++++ @@ -126469,10 +126892,10 @@ Subject: [PATCH 050/204] Adding Device Tree support for some RPi audio cards 6 files changed, 232 insertions(+) diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 0a5e4188..57e1f3d 100644 +index b0b2186..184b6a1 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -636,6 +636,115 @@ static struct platform_device bcm2835_thermal_device = { +@@ -621,6 +621,115 @@ static struct platform_device bcm2835_thermal_device = { .name = "bcm2835_thermal", }; @@ -126588,7 +127011,7 @@ index 0a5e4188..57e1f3d 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -800,6 +909,40 @@ void __init bcm2709_init(void) +@@ -791,6 +900,40 @@ void __init bcm2709_init(void) bcm_register_device_dt(&bcm2835_thermal_device); @@ -126820,10 +127243,10 @@ index 126f1e9..7c6598e 100644 }; -From 1548b70b26d3607e2f51c46f98c09f704911e4ae Mon Sep 17 00:00:00 2001 +From 048b22df06862e17f9472e03385f6b83ba3238a8 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Wed, 29 Oct 2014 23:30:30 -0700 -Subject: [PATCH 051/204] Added support to reserve/enable a GPIO pin to be used +Subject: [PATCH 066/113] Added support to reserve/enable a GPIO pin to be used from pps-gpio module (LinuxPPS). Enable PPS modules in default config for RPi. @@ -126833,10 +127256,10 @@ Subject: [PATCH 051/204] Added support to reserve/enable a GPIO pin to be used 2 files changed, 54 insertions(+) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 363b9c5..74ec578 100644 +index f1d853f..df8cd0b 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -37,6 +37,7 @@ +@@ -38,6 +38,7 @@ #include #include #include @@ -126844,7 +127267,7 @@ index 363b9c5..74ec578 100644 #include #include -@@ -92,6 +93,7 @@ static unsigned reboot_part = 0; +@@ -93,6 +94,7 @@ static unsigned reboot_part = 0; static unsigned w1_gpio_pin = W1_GPIO; static unsigned w1_gpio_pullup = W1_PULLUP; static bool vc_i2c_override = false; @@ -126852,7 +127275,7 @@ index 363b9c5..74ec578 100644 static unsigned use_dt = 0; -@@ -325,6 +327,19 @@ static struct platform_device w1_device = { +@@ -329,6 +331,19 @@ static struct platform_device w1_device = { }; #endif @@ -126872,7 +127295,7 @@ index 363b9c5..74ec578 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -860,6 +875,16 @@ void __init bcm2708_init(void) +@@ -848,6 +863,16 @@ void __init bcm2708_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -126889,14 +127312,14 @@ index 363b9c5..74ec578 100644 #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) w1_gpio_pdata.pin = w1_gpio_pin; w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1116,3 +1141,5 @@ module_param(w1_gpio_pin, uint, 0644); +@@ -1101,3 +1126,5 @@ module_param(w1_gpio_pin, uint, 0644); module_param(w1_gpio_pullup, uint, 0644); module_param(vc_i2c_override, bool, 0644); MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +module_param(pps_gpio_pin, int, 0644); +MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 57e1f3d..721559b 100644 +index 184b6a1..ea3b689 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -37,6 +37,7 @@ @@ -126935,7 +127358,7 @@ index 57e1f3d..721559b 100644 static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -880,6 +895,16 @@ void __init bcm2709_init(void) +@@ -865,6 +880,16 @@ void __init bcm2709_init(void) #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); #endif @@ -126952,17 +127375,17 @@ index 57e1f3d..721559b 100644 #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) w1_gpio_pdata.pin = w1_gpio_pin; w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1284,3 +1309,5 @@ module_param(w1_gpio_pin, uint, 0644); +@@ -1275,3 +1300,5 @@ module_param(w1_gpio_pin, uint, 0644); module_param(w1_gpio_pullup, uint, 0644); module_param(vc_i2c_override, bool, 0644); MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +module_param(pps_gpio_pin, int, 0644); +MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -From c7e1fd615565779916e66d987595521dcefc691c Mon Sep 17 00:00:00 2001 +From ff740f0194549736ce50e6db372a3738df2c9cab Mon Sep 17 00:00:00 2001 From: Ryan Coe Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 052/204] Update ds1307 driver for device-tree support +Subject: [PATCH 067/113] Update ds1307 driver for device-tree support Signed-off-by: Ryan Coe --- @@ -126970,10 +127393,10 @@ Signed-off-by: Ryan Coe 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index 4ffabb3..c6789a7 100644 +index a705e64..c14c823 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c -@@ -1242,6 +1242,14 @@ static int ds1307_remove(struct i2c_client *client) +@@ -1235,6 +1235,14 @@ static int ds1307_remove(struct i2c_client *client) return 0; } @@ -126989,25 +127412,90 @@ index 4ffabb3..c6789a7 100644 .driver = { .name = "rtc-ds1307", -From 5d7ba67c43373946a8b3c8bed5f2e6e23090a09d Mon Sep 17 00:00:00 2001 +From c5999ebe205cbacdf554e871a53e53ac5875764d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 053/204] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 068/113] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support the Raspberry Pi PWR LED, which is driven by external hardware in normal use. N.B. pwr_led is not available on Model A or B boards. + +leds-gpio: Implement the brightness_get method + +The power LED uses some clever logic that means it is driven +by a voltage measuring circuit when configured as input, otherwise +it is driven by the GPIO output value. This patch wires up the +brightness_get method for leds-gpio so that user-space can monitor +the LED value via /sys/class/gpio/led1/brightness. Using the input +trigger this returns an indication of the system power health, +otherwise it is just whatever value the trigger has written most +recently. + +See: https://github.com/raspberrypi/linux/issues/1064 --- - drivers/leds/trigger/Kconfig | 7 ++++ + drivers/leds/leds-gpio.c | 18 +++++++++++- + drivers/leds/trigger/Kconfig | 7 +++++ drivers/leds/trigger/Makefile | 1 + - drivers/leds/trigger/ledtrig-input.c | 65 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 73 insertions(+) + drivers/leds/trigger/ledtrig-input.c | 54 ++++++++++++++++++++++++++++++++++++ + include/linux/leds.h | 3 ++ + 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 drivers/leds/trigger/ledtrig-input.c +diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c +index af1876a..7da6d05 100644 +--- a/drivers/leds/leds-gpio.c ++++ b/drivers/leds/leds-gpio.c +@@ -42,6 +42,13 @@ static void gpio_led_work(struct work_struct *work) + led_dat->platform_gpio_blink_set(led_dat->gpiod, + led_dat->new_level, NULL, NULL); + led_dat->blinking = 0; ++ } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { ++ gpiod_direction_input(led_dat->gpiod); ++ led_dat->cdev.flags &= ~SET_GPIO_INPUT; ++ } ++ else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { ++ gpiod_direction_output(led_dat->gpiod, led_dat->new_level); ++ led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; + } else + gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); + } +@@ -62,7 +69,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, + * seem to have a reliable way to know if we're already in one; so + * let's just assume the worst. + */ +- if (led_dat->can_sleep) { ++ if (led_dat->can_sleep || ++ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) { + led_dat->new_level = level; + schedule_work(&led_dat->work); + } else { +@@ -75,6 +83,13 @@ static void gpio_led_set(struct led_classdev *led_cdev, + } + } + ++static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) ++{ ++ struct gpio_led_data *led_dat = ++ container_of(led_cdev, struct gpio_led_data, cdev); ++ return gpiod_get_value_cansleep(led_dat->gpiod) ? LED_FULL : LED_OFF; ++} ++ + static int gpio_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, unsigned long *delay_off) + { +@@ -131,6 +146,7 @@ static int create_gpio_led(const struct gpio_led *template, + led_dat->cdev.blink_set = gpio_blink_set; + } + led_dat->cdev.brightness_set = gpio_led_set; ++ led_dat->cdev.brightness_get = gpio_led_get; + if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) + state = !!gpiod_get_value_cansleep(led_dat->gpiod); + else diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig -index 49794b4..640756b 100644 +index 5bda6a9..eb98cca 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig @@ -108,4 +108,11 @@ config LEDS_TRIGGER_CAMERA @@ -127033,10 +127521,10 @@ index 1abf48d..c03afdc 100644 +obj-$(CONFIG_LEDS_TRIGGER_INPUT) += ledtrig-input.o diff --git a/drivers/leds/trigger/ledtrig-input.c b/drivers/leds/trigger/ledtrig-input.c new file mode 100644 -index 0000000..2ca2b98 +index 0000000..07d1219 --- /dev/null +++ b/drivers/leds/trigger/ledtrig-input.c -@@ -0,0 +1,65 @@ +@@ -0,0 +1,54 @@ +/* + * Set LED GPIO to Input "Trigger" + * @@ -127057,27 +127545,16 @@ index 0000000..2ca2b98 +#include +#include "../leds.h" + -+/* This is a hack to get at the private 'gpio' member */ -+ -+struct gpio_led_data { -+ struct led_classdev cdev; -+ unsigned gpio; -+}; -+ +static void input_trig_activate(struct led_classdev *led_cdev) +{ -+ struct gpio_led_data *led_dat = -+ container_of(led_cdev, struct gpio_led_data, cdev); -+ if (gpio_is_valid(led_dat->gpio)) -+ gpio_direction_input(led_dat->gpio); ++ led_cdev->flags |= SET_GPIO_INPUT; ++ led_set_brightness_async(led_cdev, 0); +} + +static void input_trig_deactivate(struct led_classdev *led_cdev) +{ -+ struct gpio_led_data *led_dat = -+ container_of(led_cdev, struct gpio_led_data, cdev); -+ if (gpio_is_valid(led_dat->gpio)) -+ gpio_direction_output(led_dat->gpio, 0); ++ led_cdev->flags |= SET_GPIO_OUTPUT; ++ led_set_brightness_async(led_cdev, 0); +} + +static struct led_trigger input_led_trigger = { @@ -127102,11 +127579,25 @@ index 0000000..2ca2b98 +MODULE_AUTHOR("Phil Elwell "); +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); +diff --git a/include/linux/leds.h b/include/linux/leds.h +index b122eea..0b23990 100644 +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -48,6 +48,9 @@ struct led_classdev { + #define SET_BRIGHTNESS_ASYNC (1 << 21) + #define SET_BRIGHTNESS_SYNC (1 << 22) + #define LED_DEV_CAP_FLASH (1 << 23) ++ /* Additions for Raspberry Pi PWR LED */ ++#define SET_GPIO_INPUT (1 << 30) ++#define SET_GPIO_OUTPUT (1 << 31) + + /* Set LED brightness level */ + /* Must not sleep, use a workqueue if needed */ -From dfc29014435e46cbc28a4cdcdf1bff215964e13b Mon Sep 17 00:00:00 2001 +From 15b8e6fd3a6dcb183a65361dc845d06a1f031e1c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 20 Jun 2014 17:19:27 +0100 -Subject: [PATCH 054/204] bcm2709: Simplify and strip down IRQ handler +Subject: [PATCH 069/113] bcm2709: Simplify and strip down IRQ handler --- arch/arm/include/asm/entry-macro-multi.S | 2 + @@ -127114,7 +127605,7 @@ Subject: [PATCH 054/204] bcm2709: Simplify and strip down IRQ handler 2 files changed, 87 insertions(+), 88 deletions(-) diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S -index 469a2b3..9c0a7eb 100644 +index 609184f..693cc1f 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S @@ -1,5 +1,6 @@ @@ -127133,7 +127624,7 @@ index 469a2b3..9c0a7eb 100644 .macro arch_irq_handler, symbol_name .align 5 diff --git a/arch/arm/mach-bcm2709/include/mach/entry-macro.S b/arch/arm/mach-bcm2709/include/mach/entry-macro.S -index d08591b..08d184c 100644 +index d08591b..2e9f458 100644 --- a/arch/arm/mach-bcm2709/include/mach/entry-macro.S +++ b/arch/arm/mach-bcm2709/include/mach/entry-macro.S @@ -22,102 +22,99 @@ @@ -127189,7 +127680,7 @@ index d08591b..08d184c 100644 + str \tmp, [\irqstat] @ clear interrupt source + dsb + mov r1, sp -+ adr lr, BSYM(1b) ++ badr lr, 1b + b do_IPI +#endif +1030: @@ -127293,7 +127784,7 @@ index d08591b..08d184c 100644 + @ + @ routine called with r0 = irq number, r1 = struct pt_regs * + @ -+ adr lr, BSYM(1b) ++ badr lr, 1b + b asm_do_IRQ - .endm @@ -127325,100 +127816,10 @@ index d08591b..08d184c 100644 +1: get_irqnr_and_base r0, r2, r6, lr + .endm -From ee705807744ab8001d5ae997102c0c8c9785dafe Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 12 Feb 2015 11:17:53 +0000 -Subject: [PATCH 055/204] Fix LED "input" trigger implementation for 3.19 - ---- - drivers/leds/leds-gpio.c | 10 +++++++++- - drivers/leds/trigger/ledtrig-input.c | 19 ++++--------------- - include/linux/leds.h | 3 +++ - 3 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 15eb3f8..3cfbd6a 100644 ---- a/drivers/leds/leds-gpio.c -+++ b/drivers/leds/leds-gpio.c -@@ -41,6 +41,13 @@ static void gpio_led_work(struct work_struct *work) - led_dat->platform_gpio_blink_set(led_dat->gpiod, - led_dat->new_level, NULL, NULL); - led_dat->blinking = 0; -+ } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { -+ gpiod_direction_input(led_dat->gpiod); -+ led_dat->cdev.flags &= ~SET_GPIO_INPUT; -+ } -+ else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { -+ gpiod_direction_output(led_dat->gpiod, led_dat->new_level); -+ led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; - } else - gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); - } -@@ -61,7 +68,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, - * seem to have a reliable way to know if we're already in one; so - * let's just assume the worst. - */ -- if (led_dat->can_sleep) { -+ if (led_dat->can_sleep || -+ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) { - led_dat->new_level = level; - schedule_work(&led_dat->work); - } else { -diff --git a/drivers/leds/trigger/ledtrig-input.c b/drivers/leds/trigger/ledtrig-input.c -index 2ca2b98..07d1219 100644 ---- a/drivers/leds/trigger/ledtrig-input.c -+++ b/drivers/leds/trigger/ledtrig-input.c -@@ -18,27 +18,16 @@ - #include - #include "../leds.h" - --/* This is a hack to get at the private 'gpio' member */ -- --struct gpio_led_data { -- struct led_classdev cdev; -- unsigned gpio; --}; -- - static void input_trig_activate(struct led_classdev *led_cdev) - { -- struct gpio_led_data *led_dat = -- container_of(led_cdev, struct gpio_led_data, cdev); -- if (gpio_is_valid(led_dat->gpio)) -- gpio_direction_input(led_dat->gpio); -+ led_cdev->flags |= SET_GPIO_INPUT; -+ led_set_brightness_async(led_cdev, 0); - } - - static void input_trig_deactivate(struct led_classdev *led_cdev) - { -- struct gpio_led_data *led_dat = -- container_of(led_cdev, struct gpio_led_data, cdev); -- if (gpio_is_valid(led_dat->gpio)) -- gpio_direction_output(led_dat->gpio, 0); -+ led_cdev->flags |= SET_GPIO_OUTPUT; -+ led_set_brightness_async(led_cdev, 0); - } - - static struct led_trigger input_led_trigger = { -diff --git a/include/linux/leds.h b/include/linux/leds.h -index 9a2b000..60accc5 100644 ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -47,6 +47,9 @@ struct led_classdev { - #define SET_BRIGHTNESS_ASYNC (1 << 21) - #define SET_BRIGHTNESS_SYNC (1 << 22) - #define LED_DEV_CAP_FLASH (1 << 23) -+ /* Additions for Raspberry Pi PWR LED */ -+#define SET_GPIO_INPUT (1 << 30) -+#define SET_GPIO_OUTPUT (1 << 31) - - /* Set LED brightness level */ - /* Must not sleep, use a workqueue if needed */ - -From 27e98ca305c67ee354c42983a43f09b2e59ce5b5 Mon Sep 17 00:00:00 2001 +From 5a4e33549393b09c042a71a22b425d4367101827 Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 056/204] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 070/113] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes @@ -127427,7 +127828,7 @@ Signed-off-by: Noralf Tronnes 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 8d908e3..7a1900d 100644 +index 8efa235..04646672 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { @@ -127440,10 +127841,10 @@ index 8d908e3..7a1900d 100644 .can_sleep = false, }; -From e4022c2c7ada3dc69da92db183132c86cdc7d730 Mon Sep 17 00:00:00 2001 +From 325b7cc3bbc22776d12da10692d7008c619c4b85 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 4 Feb 2015 10:02:24 +0000 -Subject: [PATCH 057/204] pinctrl-bcm2835: bcm2835_gpio_direction_output must +Subject: [PATCH 071/113] pinctrl-bcm2835: bcm2835_gpio_direction_output must set the value --- @@ -127451,7 +127852,7 @@ Subject: [PATCH 057/204] pinctrl-bcm2835: bcm2835_gpio_direction_output must 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 7a1900d..62f85aa 100644 +index 04646672..f6de89e 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -355,7 +355,14 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -127471,10 +127872,10 @@ index 7a1900d..62f85aa 100644 static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -From d1c711959d41518b10f7c2797cac744c543468ad Mon Sep 17 00:00:00 2001 +From 0b206abf34d3ab8663d5b4b829e0e1d76af236cc Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Feb 2015 13:40:50 +0000 -Subject: [PATCH 058/204] pinctrl-bcm2835: Fix interrupt handling for GPIOs +Subject: [PATCH 072/113] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 and 46-53 Contrary to the documentation, the BCM2835 GPIO controller actually has @@ -127495,7 +127896,7 @@ the pins are often used for I2S instead. 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 62f85aa..c7cf266 100644 +index f6de89e..b5dedd78 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -47,6 +47,7 @@ @@ -127584,7 +127985,7 @@ index 62f85aa..c7cf266 100644 } static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, -@@ -1000,8 +1023,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1001,8 +1024,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for (i = 0; i < BCM2835_NUM_BANKS; i++) { unsigned long events; unsigned offset; @@ -127593,7 +127994,7 @@ index 62f85aa..c7cf266 100644 /* clear event detection flags */ bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0); -@@ -1016,10 +1037,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1017,10 +1038,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for_each_set_bit(offset, &events, 32) bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); @@ -127611,7 +128012,7 @@ index 62f85aa..c7cf266 100644 len = strlen(dev_name(pc->dev)) + 16; name = devm_kzalloc(pc->dev, len, GFP_KERNEL); -@@ -1077,6 +1103,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { +@@ -1078,6 +1104,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { .remove = bcm2835_pinctrl_remove, .driver = { .name = MODULE_NAME, @@ -127620,10 +128021,10 @@ index 62f85aa..c7cf266 100644 }, }; -From 3c62244d144a37b12b9af16a34eb67b4b7cf48ba Mon Sep 17 00:00:00 2001 +From 6c698f0d97ad6050f5c130108e5ccd15da46600d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 059/204] pinctrl-bcm2835: Only request the interrupts listed +Subject: [PATCH 073/113] pinctrl-bcm2835: Only request the interrupts listed in the DTB Although the GPIO controller can generate three interrupts (four counting @@ -127637,10 +128038,10 @@ interface, is unlikely to be a problem. 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index c7cf266..986779a 100644 +index b5dedd78..bee7c86 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -@@ -1044,6 +1044,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1045,6 +1045,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) int len; char *name; pc->irq[i] = irq_of_parse_and_map(np, i); @@ -127650,10 +128051,10 @@ index c7cf266..986779a 100644 pc->irq_data[i].irqgroup = i; -From f8391406e17d282f010b8deebe0ccd26f8ea2e49 Mon Sep 17 00:00:00 2001 +From c6a0e04c3aa39f40c0bbe5ceb14b2b1d8a105112 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Feb 2015 15:10:24 +0000 -Subject: [PATCH 060/204] enc28j60: Add device tree compatible string and an +Subject: [PATCH 074/113] enc28j60: Add device tree compatible string and an overlay --- @@ -127687,10 +128088,10 @@ index b1b5f66..c6b6e1a 100644 .probe = enc28j60_probe, .remove = enc28j60_remove, -From eb2703ff418ab3b72d09375f7c2aa49aee9f4a0e Mon Sep 17 00:00:00 2001 +From b58e541e5be30031e5f37132188ed6368be87bf6 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 061/204] Add driver for rpi-proto +Subject: [PATCH 075/113] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x @@ -127905,10 +128306,10 @@ index 0000000..c6e45a0 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From d3d38e562e57db9c529f93aedfe9fca8b5c70a38 Mon Sep 17 00:00:00 2001 +From b6f020bcccef5499dd127a7f9805863610dd56e5 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Thu, 2 Apr 2015 12:22:55 +0100 -Subject: [PATCH 062/204] Add Device Tree support for RPi-DAC. +Subject: [PATCH 076/113] Add Device Tree support for RPi-DAC. --- sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++ @@ -127983,24 +128384,24 @@ index b4eaa44..afe1b41 100644 }; -From b15b358e11a817bcc7c3d8354c8a2f6f7d30a806 Mon Sep 17 00:00:00 2001 +From 997d60065e6eaa8aa93c4abe4c3cbd421da1f99f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 063/204] config: Add default configs +Subject: [PATCH 077/113] config: Add default configs --- - arch/arm/configs/bcm2709_defconfig | 1204 ++++++++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 1199 +++++++++++++++++++++++++++++++++++ - 2 files changed, 2403 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1244 ++++++++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 1240 +++++++++++++++++++++++++++++++++++ + 2 files changed, 2484 insertions(+) create mode 100644 arch/arm/configs/bcm2709_defconfig create mode 100644 arch/arm/configs/bcmrpi_defconfig diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig new file mode 100644 -index 0000000..a3067bf +index 0000000..66a1c1399 --- /dev/null +++ b/arch/arm/configs/bcm2709_defconfig -@@ -0,0 +1,1204 @@ +@@ -0,0 +1,1244 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +CONFIG_LOCALVERSION="-v7" @@ -128020,6 +128421,7 @@ index 0000000..a3067bf +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y ++CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y @@ -128052,6 +128454,8 @@ index 0000000..a3067bf +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_SECCOMP=y +CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -128392,6 +128796,12 @@ index 0000000..a3067bf +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_UBI=m ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m @@ -128400,6 +128810,7 @@ index 0000000..a3067bf +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y @@ -128416,6 +128827,7 @@ index 0000000..a3067bf +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m @@ -128514,6 +128926,8 @@ index 0000000..a3067bf +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_WL_MEDIATEK=y ++CONFIG_MT7601U=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_MWIFIEX=m @@ -128531,9 +128945,11 @@ index 0000000..a3067bf +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y @@ -128552,19 +128968,27 @@ index 0000000..a3067bf +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_BCM2708=m @@ -128597,7 +129021,11 @@ index 0000000..a3067bf +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_BATTERY_DS2760=m -+# CONFIG_HWMON is not set ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_HWMON=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHTC1=m +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y @@ -128776,6 +129204,7 @@ index 0000000..a3067bf +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -128811,6 +129240,9 @@ index 0000000..a3067bf +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SOUND_PRIME=m +CONFIG_HIDRAW=y @@ -129060,7 +129492,7 @@ index 0000000..a3067bf +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y ++CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m @@ -129069,6 +129501,8 @@ index 0000000..a3067bf +CONFIG_IIO_BUFFER_CB=y +CONFIG_IIO_KFIFO_BUF=m +CONFIG_DHT11=m ++CONFIG_PWM_BCM2835=m ++CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -129089,12 +129523,14 @@ index 0000000..a3067bf +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y @@ -129114,11 +129550,13 @@ index 0000000..a3067bf +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y @@ -129133,6 +129571,10 @@ index 0000000..a3067bf +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_SMB2=y ++CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" @@ -129194,23 +129636,22 @@ index 0000000..a3067bf +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_SHA512_ARM_NEON=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig new file mode 100644 -index 0000000..6a41231 +index 0000000..3e1ac5a --- /dev/null +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,1199 @@ +@@ -0,0 +1,1240 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +# CONFIG_LOCALVERSION_AUTO is not set @@ -129229,6 +129670,7 @@ index 0000000..6a41231 +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y ++CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y @@ -129257,6 +129699,8 @@ index 0000000..6a41231 +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_SECCOMP=y +CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -129595,6 +130039,12 @@ index 0000000..6a41231 +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_UBI=m ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m @@ -129603,6 +130053,7 @@ index 0000000..6a41231 +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y @@ -129619,6 +130070,7 @@ index 0000000..6a41231 +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m @@ -129717,6 +130169,8 @@ index 0000000..6a41231 +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_WL_MEDIATEK=y ++CONFIG_MT7601U=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_MWIFIEX=m @@ -129734,9 +130188,11 @@ index 0000000..6a41231 +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y @@ -129755,19 +130211,27 @@ index 0000000..6a41231 +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_BCM2708=m @@ -129800,7 +130264,11 @@ index 0000000..6a41231 +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_BATTERY_DS2760=m -+# CONFIG_HWMON is not set ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_HWMON=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHTC1=m +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y @@ -129979,6 +130447,7 @@ index 0000000..6a41231 +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -130014,6 +130483,9 @@ index 0000000..6a41231 +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SOUND_PRIME=m +CONFIG_HIDRAW=y @@ -130263,7 +130735,7 @@ index 0000000..6a41231 +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y ++CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m @@ -130272,6 +130744,8 @@ index 0000000..6a41231 +CONFIG_IIO_BUFFER_CB=y +CONFIG_IIO_KFIFO_BUF=m +CONFIG_DHT11=m ++CONFIG_PWM_BCM2835=m ++CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -130292,12 +130766,14 @@ index 0000000..6a41231 +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y @@ -130317,11 +130793,13 @@ index 0000000..6a41231 +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y @@ -130336,6 +130814,10 @@ index 0000000..6a41231 +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_SMB2=y ++CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" @@ -130399,169 +130881,22 @@ index 0000000..6a41231 +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 97b84b787de84ad70a3a3a2d7faa9c898c89077c Mon Sep 17 00:00:00 2001 -From: Steve Glendinning -Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 064/204] smsx95xx: fix crimes against truesize - -smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. - -This patch stops smsc95xx from changing truesize. - -Signed-off-by: Steve Glendinning ---- - drivers/net/usb/smsc95xx.c | 2 -- - 1 file changed, 2 deletions(-) - mode change 100644 => 100755 drivers/net/usb/smsc95xx.c - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -old mode 100644 -new mode 100755 -index e29a323..aff63dc ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -1841,7 +1841,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(skb); - skb_trim(skb, skb->len - 4); /* remove fcs */ -- skb->truesize = size + sizeof(struct sk_buff); - - return 1; - } -@@ -1859,7 +1858,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(ax_skb); - skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ -- ax_skb->truesize = size + sizeof(struct sk_buff); - - usbnet_skb_return(dev, ax_skb); - } - -From f00f1c85db60369955c57b255c2588ff56d59fa7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 17 Apr 2015 16:58:45 +0100 -Subject: [PATCH 065/204] smsc95xx: Disable turbo mode by default - ---- - drivers/net/usb/smsc95xx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index aff63dc..08a8a8c 100755 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -71,7 +71,7 @@ struct smsc95xx_priv { - u8 suspend_flags; - }; - --static bool turbo_mode = true; -+static bool turbo_mode = false; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - - -From 122b539270dc7e0d8ee3b6926c77f5aedb06fb67 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 17 Apr 2015 19:30:22 +0100 -Subject: [PATCH 066/204] Add blk_pos parameter to mmc multi_io_quirk callback - ---- - drivers/mmc/card/block.c | 1 + - drivers/mmc/host/omap_hsmmc.c | 4 +++- - drivers/mmc/host/sh_mobile_sdhi.c | 4 +++- - drivers/mmc/host/tmio_mmc_pio.c | 4 +++- - include/linux/mmc/host.h | 4 +++- - 5 files changed, 13 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index 31d2627..8484ec9 100644 ---- a/drivers/mmc/card/block.c -+++ b/drivers/mmc/card/block.c -@@ -1415,6 +1415,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, - brq->data.blocks = card->host->ops->multi_io_quirk(card, - (rq_data_dir(req) == READ) ? - MMC_DATA_READ : MMC_DATA_WRITE, -+ blk_rq_pos(req), - brq->data.blocks); - } - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index d0abdffb..ebb6bf4 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1749,7 +1749,9 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) - } - - static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, int blk_size) -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size) - { - /* This controller can't do multiblock reads due to hw bugs */ - if (direction == MMC_DATA_READ) -diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c -index 354f4f3..4f1ccf3 100644 ---- a/drivers/mmc/host/sh_mobile_sdhi.c -+++ b/drivers/mmc/host/sh_mobile_sdhi.c -@@ -170,7 +170,9 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) - } - - static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, int blk_size) -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size) - { - /* - * In Renesas controllers, when performing a -diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c -index dba7e1c..0c87f4f 100644 ---- a/drivers/mmc/host/tmio_mmc_pio.c -+++ b/drivers/mmc/host/tmio_mmc_pio.c -@@ -1001,7 +1001,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) - } - - static int tmio_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, int blk_size) -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size) - { - struct tmio_mmc_host *host = mmc_priv(card->host); - -diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index b0258e8..d3cdad9 100644 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -140,7 +140,9 @@ struct mmc_host_ops { - * I/O. Returns the number of supported blocks for the request. - */ - int (*multi_io_quirk)(struct mmc_card *card, -- unsigned int direction, int blk_size); -+ unsigned int direction, -+ u32 blk_pos, -+ int blk_size); - }; - - struct mmc_card; - -From ec8a45bdc3e0afbf5ab8ba7735608e7ca11feca7 Mon Sep 17 00:00:00 2001 +From 2e2c297b30fc0f436fe743209a782b3b377c38c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 29 Apr 2015 17:24:02 +0200 -Subject: [PATCH 067/204] bcm2835: bcm2835_defconfig +Subject: [PATCH 078/113] bcm2835: bcm2835_defconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -130634,16 +130969,79 @@ rm merge.cfg filter filtered.cfg added.cfg defconfig ARCH=arm make bcm2835_defconfig ARCH=arm make oldconfig +Signed-off-by: Noralf Trønnes + +configs: Incorporate v4.1 dependency changes + +Commit 78e9b7de78bb53e8bc7f4c4a60ebacb250c0c190 added a +dependency on TI_ST instead of selecting it, disabling: +CONFIG_BT_WILINK=m +CONFIG_RADIO_WL128X=m + +Commit 652ccae5cc4e1305fb0a4619947f9ee89d8c7f5a added a +depency on ARM_CRYPTO, disabling: +CONFIG_CRYPTO_SHA*_ARM*=m +CONFIG_CRYPTO_AES_ARM*=m + +Signed-off-by: Noralf Trønnes + +Conflicts: + arch/arm/configs/bcm2709_defconfig + +bcm2835: Sync bcm2835_defconfig with bcmrpi_defconfig + +These commands where used to make this commit: + +: Get changed and new config values from a merge +./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg + +: Remove these options +cat << EOF > filter +CONFIG_ARCH_BCM2708 +CONFIG_BCM2708_DT +CONFIG_ARM_PATCH_PHYS_VIRT +CONFIG_PHYS_OFFSET +CONFIG_CMDLINE +CONFIG_BCM2708_WDT +CONFIG_HW_RANDOM_BCM2708 +CONFIG_SPI_BCM2708 +EOF + +: Apply filter +grep -F -v -f filter merge.cfg > filtered.cfg + +: Add these options +: watchdog contains the restart/poweroff code. +cat << EOF > added.cfg +CONFIG_WATCHDOG=y +CONFIG_BCM2835_WDT=y +CONFIG_MISC_FILESYSTEMS=y +CONFIG_I2C_BCM2835=m +CONFIG_SND_BCM2835_SOC_I2S=m +EOF + +: Create new config +ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg +: Verify +ARCH=arm make oldconfig + +: Update bcm2835_defconfig +ARCH=arm make savedefconfig +cp defconfig arch/arm/configs/bcm2835_defconfig + +: Clean up +rm merge.cfg filter filtered.cfg added.cfg defconfig + Signed-off-by: Noralf Trønnes --- - arch/arm/configs/bcm2835_defconfig | 1132 +++++++++++++++++++++++++++++++++++- - 1 file changed, 1107 insertions(+), 25 deletions(-) + arch/arm/configs/bcm2835_defconfig | 1165 +++++++++++++++++++++++++++++++++++- + 1 file changed, 1139 insertions(+), 26 deletions(-) diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 31cb073..2e8a95a 100644 +index 31cb073..5b391a5 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig -@@ -1,105 +1,1071 @@ +@@ -1,105 +1,1102 @@ # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y @@ -130707,6 +131105,8 @@ index 31cb073..2e8a95a 100644 CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_SECCOMP=y -CONFIG_CC_STACKPROTECTOR=y @@ -131052,6 +131452,8 @@ index 31cb073..2e8a95a 100644 # CONFIG_STANDALONE is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m @@ -131060,6 +131462,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y @@ -131179,6 +131582,8 @@ index 31cb073..2e8a95a 100644 +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_WL_MEDIATEK=y ++CONFIG_MT7601U=m +CONFIG_RTL8192CU=m +CONFIG_ZD1211RW=m +CONFIG_MWIFIEX=m @@ -131196,9 +131601,11 @@ index 31cb073..2e8a95a 100644 +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y @@ -131217,22 +131624,32 @@ index 31cb073..2e8a95a 100644 +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y +-CONFIG_I2C_BCM2835=y +CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2835=y ++CONFIG_I2C_BCM2708=m ++CONFIG_I2C_BCM2835=m CONFIG_SPI=y -CONFIG_SPI_BCM2835=y +CONFIG_SPI_BCM2835=m @@ -131262,6 +131679,8 @@ index 31cb073..2e8a95a 100644 +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_BATTERY_DS2760=m ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y # CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y @@ -131441,6 +131860,7 @@ index 31cb073..2e8a95a 100644 -CONFIG_FB_SIMPLE=y +CONFIG_FB_BCM2708=y +CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m CONFIG_FRAMEBUFFER_CONSOLE=y @@ -131470,6 +131890,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_SOC=m +CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m @@ -131477,6 +131898,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SOUND_PRIME=m +CONFIG_HIDRAW=y @@ -131531,6 +131953,7 @@ index 31cb073..2e8a95a 100644 CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y +CONFIG_USB_PRINTER=m CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m @@ -131699,6 +132122,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_STAGING_MEDIA=y +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_IMON=m ++CONFIG_LIRC_RPI=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_FB_TFT=m @@ -131730,14 +132154,20 @@ index 31cb073..2e8a95a 100644 +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y ++CONFIG_BCM2835_MBOX=y # CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_DHT11=m ++CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y -@@ -107,18 +1073,110 @@ CONFIG_EXT3_FS=y +@@ -107,18 +1104,110 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y @@ -131759,6 +132189,7 @@ index 31cb073..2e8a95a 100644 +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m @@ -131789,7 +132220,6 @@ index 31cb073..2e8a95a 100644 +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y CONFIG_NFS_FS=y -CONFIG_NFSD=y +CONFIG_NFS_V3_ACL=y @@ -131851,7 +132281,7 @@ index 31cb073..2e8a95a 100644 CONFIG_PRINTK_TIME=y CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y -@@ -128,14 +1186,38 @@ CONFIG_DEBUG_INFO=y +@@ -128,14 +1217,38 @@ CONFIG_DEBUG_INFO=y CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_LOCKUP_DETECTOR=y @@ -131877,88 +132307,46 @@ index 31cb073..2e8a95a 100644 +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y # CONFIG_XZ_DEC_ARM is not set # CONFIG_XZ_DEC_ARMTHUMB is not set -From af1868e02b629a2e2092bf358540d6ca4dcdff6c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 23:00:15 +0200 -Subject: [PATCH 068/204] BCM270x_DT: Add mailbox bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add bcm2708-vcio to Device Tree and don't add the -platform device when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 74ec578..5527d5c 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -870,7 +870,7 @@ void __init bcm2708_init(void) - bcm2708_dt_init(); - - bcm_register_device_dt(&bcm2708_dmaengine_device); -- bcm_register_device(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vcio_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 721559b..4a00561 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -890,7 +890,7 @@ void __init bcm2709_init(void) - bcm2709_dt_init(); - - bcm_register_device_dt(&bcm2708_dmaengine_device); -- bcm_register_device(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vcio_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - -From ab35f5a7f3921cd9d5d9f09f4bd82675822048dc Mon Sep 17 00:00:00 2001 +From 6d2eae30176f1d49a63f6834f218448c0e91e41f Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 069/204] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 079/113] rpi-ft5406: Add touchscreen driver for pi LCD display +Fix driver detection failure Check that the buffer response is non-zero meaning the touchscreen was detected + +rpi-ft5406: Use firmware API --- - drivers/input/touchscreen/Kconfig | 7 + - drivers/input/touchscreen/Makefile | 1 + - drivers/input/touchscreen/rpi-ft5406.c | 258 ++++++++++++++++++++++++++ - include/linux/platform_data/mailbox-bcm2708.h | 1 + - 4 files changed, 267 insertions(+) + drivers/input/touchscreen/Kconfig | 7 + + drivers/input/touchscreen/Makefile | 1 + + drivers/input/touchscreen/rpi-ft5406.c | 246 +++++++++++++++++++++++++++++++++ + 3 files changed, 254 insertions(+) create mode 100644 drivers/input/touchscreen/rpi-ft5406.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 80f6386..5848562 100644 +index 600dcce..5bfc087 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -583,6 +583,13 @@ config TOUCHSCREEN_EDT_FT5X06 +@@ -595,6 +595,13 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. +config TOUCHSCREEN_RPI_FT5406 + tristate "Raspberry Pi FT5406 driver" -+ depends on ARCH_BCM2708 || ARCH_BCM2709 ++ depends on RASPBERRYPI_FIRMWARE + help + Say Y here to enable the Raspberry Pi memory based FT5406 device + @@ -131967,7 +132355,7 @@ index 80f6386..5848562 100644 tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index 44deea7..a1be09f 100644 +index 1b79cc0..a0f77b2 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o @@ -131980,10 +132368,10 @@ index 44deea7..a1be09f 100644 obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c new file mode 100644 -index 0000000..f55151b +index 0000000..c08817e --- /dev/null +++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -0,0 +1,258 @@ +@@ -0,0 +1,246 @@ +/* + * Driver for memory based ft5406 touchscreen + * @@ -132007,7 +132395,7 @@ index 0000000..f55151b +#include +#include +#include -+#include ++#include + +#define MAXIMUM_SUPPORTED_POINTS 10 +struct ft5406_regs { @@ -132035,23 +132423,6 @@ index 0000000..f55151b + struct task_struct * thread; +}; + -+ -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the message id */ -+ uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -+ uint32_t data_size; /* amount of data being sent or received */ -+ uint32_t val; /* data buffer */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ +/* Thread to poll for touchscreen events + * + * This thread polls the memory based register copy of the ft5406 registers @@ -132122,11 +132493,37 @@ index 0000000..f55151b +{ + int ret; + struct input_dev * input_dev = input_allocate_device(); -+ struct vc_msg request; + struct ft5406 * ts; ++ struct device_node *fw_node; ++ struct rpi_firmware *fw; ++ u32 touchbuf; + + dev_info(&pdev->dev, "Probing device\n"); + ++ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++ if (!fw_node) { ++ dev_err(&pdev->dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++ ++ fw = rpi_firmware_get(fw_node); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF, ++ &touchbuf, sizeof(touchbuf)); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to get touch buffer\n"); ++ return ret; ++ } ++ ++ if (!touchbuf) { ++ dev_err(&pdev->dev, "Touchscreen not detected\n"); ++ return -ENODEV; ++ } ++ ++ dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", touchbuf); ++ + ts = kzalloc(sizeof(struct ft5406), GFP_KERNEL); + + if (!ts || !input_dev) { @@ -132160,36 +132557,15 @@ index 0000000..f55151b + return ret; + } + -+ memset(&request, 0, sizeof request); -+ -+ request.msg_size = sizeof request; -+ request.request_code = VCMSG_PROCESS_REQUEST; -+ request.tag.tag_id = VCMSG_GET_TOUCHBUF; -+ request.tag.buffer_size = 4; -+ request.tag.data_size = 4; -+ -+ bcm_mailbox_property(&request, sizeof(request)); -+ -+ if(request.request_code == VCMSG_REQUEST_SUCCESSFUL) -+ { -+ dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", request.tag.val); -+ } -+ else -+ { -+ input_unregister_device(input_dev); -+ kzfree(ts); -+ return -1; -+ } -+ + // mmap the physical memory -+ request.tag.val &= ~0xc0000000; -+ ts->ts_base = ioremap(request.tag.val, sizeof(*ts->regs)); ++ touchbuf &= ~0xc0000000; ++ ts->ts_base = ioremap(touchbuf, sizeof(*ts->regs)); + if(ts->ts_base == NULL) + { + dev_err(&pdev->dev, "Failed to map physical address\n"); + input_unregister_device(input_dev); + kzfree(ts); -+ return -1; ++ return -ENOMEM; + } + + ts->regs = (struct ft5406_regs *) ts->ts_base; @@ -132242,41 +132618,33 @@ index 0000000..f55151b +MODULE_AUTHOR("Gordon Hollingworth"); +MODULE_DESCRIPTION("Touchscreen driver for memory based FT5406"); +MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -index cc284ed..d3ea839 100644 ---- a/include/linux/platform_data/mailbox-bcm2708.h -+++ b/include/linux/platform_data/mailbox-bcm2708.h -@@ -115,6 +115,7 @@ enum { - VCMSG_SET_TRANSFORM = 0x0004800d, - VCMSG_TST_VSYNC = 0x0004400e, - VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_GET_TOUCHBUF = 0x0004000f, - VCMSG_SET_CURSOR_INFO = 0x00008010, - VCMSG_SET_CURSOR_STATE = 0x00008011, - }; -From f12bdfa033dd3c639b037c3acefc6df99e51936d Mon Sep 17 00:00:00 2001 +From 484967db8542a54000019550f8e45266b9d49a67 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 070/204] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 080/113] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use optimised memcpy/memmove/memcmp/memset implementations. + +arch/arm: Add mmiocpy/set aliases for memcpy/set + +See: https://github.com/raspberrypi/linux/issues/1082 --- arch/arm/include/asm/string.h | 5 + - arch/arm/include/asm/uaccess.h | 1 + + arch/arm/include/asm/uaccess.h | 3 + arch/arm/lib/Makefile | 15 +- arch/arm/lib/arm-mem.h | 159 ++++++++++++ arch/arm/lib/copy_from_user.S | 4 +- arch/arm/lib/exports_rpi.c | 37 +++ arch/arm/lib/memcmp_rpi.S | 285 +++++++++++++++++++++ - arch/arm/lib/memcpy_rpi.S | 59 +++++ + arch/arm/lib/memcpy_rpi.S | 61 +++++ arch/arm/lib/memcpymove.h | 506 +++++++++++++++++++++++++++++++++++++ arch/arm/lib/memmove_rpi.S | 61 +++++ - arch/arm/lib/memset_rpi.S | 121 +++++++++ + arch/arm/lib/memset_rpi.S | 123 +++++++++ arch/arm/lib/uaccess_with_memcpy.c | 112 +++++++- - 12 files changed, 1359 insertions(+), 6 deletions(-) + 12 files changed, 1365 insertions(+), 6 deletions(-) create mode 100644 arch/arm/lib/arm-mem.h create mode 100644 arch/arm/lib/exports_rpi.c create mode 100644 arch/arm/lib/memcmp_rpi.S @@ -132302,17 +132670,19 @@ index cf4f3aa..9fe7780 100644 #define memset(p,v,n) \ diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h -index 74b17d0..f4ad0a1 100644 +index 8cc85a4..21ec2fc 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h -@@ -475,6 +475,7 @@ do { \ +@@ -493,6 +493,9 @@ do { \ + extern unsigned long __must_check + arm_copy_from_user(void *to, const void __user *from, unsigned long n); - #ifdef CONFIG_MMU - extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); -+extern unsigned long __must_check __copy_from_user_std(void *to, const void __user *from, unsigned long n); - extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); - extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n); - extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); ++extern unsigned long __must_check ++__copy_from_user_std(void *to, const void __user *from, unsigned long n); ++ + static inline unsigned long __must_check + __copy_from_user(void *to, const void __user *from, unsigned long n) + { diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d8a7807..9c7dc5b 100644 --- a/arch/arm/lib/Makefile @@ -132512,20 +132882,20 @@ index 0000000..5d4bda1 +92: +.endm diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S -index 7a235b9..8aff879 100644 +index 1512beb..3da60dd 100644 --- a/arch/arm/lib/copy_from_user.S +++ b/arch/arm/lib/copy_from_user.S @@ -89,11 +89,13 @@ .text --ENTRY(__copy_from_user) +-ENTRY(arm_copy_from_user) +ENTRY(__copy_from_user_std) -+WEAK(__copy_from_user) ++WEAK(arm_copy_from_user) #include "copy_template.S" - ENDPROC(__copy_from_user) + ENDPROC(arm_copy_from_user) +ENDPROC(__copy_from_user_std) .pushsection .fixup,"ax" @@ -132866,10 +133236,10 @@ index 0000000..bf6e4ed +ENDPROC(memcmp) diff --git a/arch/arm/lib/memcpy_rpi.S b/arch/arm/lib/memcpy_rpi.S new file mode 100644 -index 0000000..15ff2bd +index 0000000..30f8a90 --- /dev/null +++ b/arch/arm/lib/memcpy_rpi.S -@@ -0,0 +1,59 @@ +@@ -0,0 +1,61 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd @@ -132926,9 +133296,11 @@ index 0000000..15ff2bd + +.set prefetch_distance, 3 + ++ENTRY(mmiocpy) +ENTRY(memcpy) + memcpy 0 +ENDPROC(memcpy) ++ENDPROC(mmiocpy) diff --git a/arch/arm/lib/memcpymove.h b/arch/arm/lib/memcpymove.h new file mode 100644 index 0000000..d8be584 @@ -133510,10 +133882,10 @@ index 0000000..8b0760c +ENDPROC(memmove) diff --git a/arch/arm/lib/memset_rpi.S b/arch/arm/lib/memset_rpi.S new file mode 100644 -index 0000000..2cde883 +index 0000000..7067415 --- /dev/null +++ b/arch/arm/lib/memset_rpi.S -@@ -0,0 +1,121 @@ +@@ -0,0 +1,123 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd @@ -133566,6 +133938,7 @@ index 0000000..2cde883 + * On exit: + * a1 preserved + */ ++ENTRY(mmioset) +ENTRY(memset) + S .req a1 + DAT0 .req a2 @@ -133635,8 +134008,9 @@ index 0000000..2cde883 + .unreq DAT2 + .unreq DAT3 +ENDPROC(memset) ++ENDPROC(mmioset) diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c -index 3e58d71..0622891 100644 +index d72b909..a6d8276 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -22,6 +22,14 @@ @@ -133753,9 +134127,9 @@ index 3e58d71..0622891 100644 +} + unsigned long - __copy_to_user(void __user *to, const void *from, unsigned long n) + arm_copy_to_user(void __user *to, const void *from, unsigned long n) { -@@ -145,10 +238,25 @@ __copy_to_user(void __user *to, const void *from, unsigned long n) +@@ -145,10 +238,25 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) * With frame pointer disabled, tail call optimization kicks in * as well making this test almost invisible. */ @@ -133765,8 +134139,8 @@ index 3e58d71..0622891 100644 return __copy_to_user_memcpy(to, from, n); } + -+unsigned long -+__copy_from_user(void *to, const void __user *from, unsigned long n) ++unsigned long __must_check ++arm_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + /* + * This test is stubbed out of the main function above to keep @@ -133783,67 +134157,10 @@ index 3e58d71..0622891 100644 static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From b52da83347f05007471699518545f3c8827d762a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 27 May 2015 17:22:15 +0100 -Subject: [PATCH 071/204] bcm2835-audio: Create the platform device if the DT - node is disabled - -For backwards compatibility, allow the built-in ALSA driver to be enabled -either by loading the module from /etc/modules or by enabling the "/audio" -node in DT. ---- - arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- - 2 files changed, 16 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5527d5c..937c2d3 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -898,8 +898,14 @@ void __init bcm2708_init(void) - #endif - bcm2708_init_led(); - bcm2708_init_uart1(); -- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ -+ /* Only create the platform devices for the ALSA driver in the -+ absence of an enabled "audio" DT node */ -+ if (!use_dt || -+ !of_device_is_available(of_find_node_by_path("/audio"))) { -+ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); -+ } - - bcm_register_device_dt(&bcm2708_spi_device); - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 4a00561..dec8043 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -918,8 +918,14 @@ void __init bcm2709_init(void) - #endif - bcm2709_init_led(); - bcm2709_init_uart1(); -- for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ -+ /* Only create the platform devices for the ALSA driver in the -+ absence of an enabled "audio" DT node */ -+ if (!use_dt || -+ !of_device_is_available(of_find_node_by_path("/audio"))) { -+ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); -+ } - - bcm_register_device_dt(&bcm2708_spi_device); - - -From 1b9a56248747ddcba15df7f60cf739eea2977349 Mon Sep 17 00:00:00 2001 +From 8da3450f9b95ba374f1458c9b920ee94e2cac869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 072/204] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 081/113] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -133868,10 +134185,10 @@ Signed-off-by: Noralf Trønnes 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c -index 70f2f39..f7fdacd 100644 +index 0f7b9ea..1e6f1cf9 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c -@@ -18,6 +18,7 @@ +@@ -17,12 +17,16 @@ #include #include #include @@ -133879,7 +134196,6 @@ index 70f2f39..f7fdacd 100644 #include #include -@@ -107,6 +108,9 @@ static void __init bcm2835_map_io(void) static void __init bcm2835_init(void) { @@ -133888,8 +134204,8 @@ index 70f2f39..f7fdacd 100644 + u64 val64; int ret; - bcm2835_setup_restart(); -@@ -121,6 +125,11 @@ static void __init bcm2835_init(void) + bcm2835_init_clocks(); +@@ -33,6 +37,11 @@ static void __init bcm2835_init(void) pr_err("of_platform_populate failed: %d\n", ret); BUG(); } @@ -133902,10 +134218,10 @@ index 70f2f39..f7fdacd 100644 static const char * const bcm2835_compat[] = { -From 6c1d2a6d20e29c2fb1809297925045701d8a4a2a Mon Sep 17 00:00:00 2001 +From 7684b7ce5c5c05c123d66d06b565a17326b19c42 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 16 Jun 2015 17:47:27 +0100 -Subject: [PATCH 073/204] platform: Add force_core command line setting to boot +Subject: [PATCH 082/113] platform: Add force_core command line setting to boot from a different core number --- @@ -133914,7 +134230,7 @@ Subject: [PATCH 073/204] platform: Add force_core command line setting to boot 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c -index a366275..90805a6 100644 +index c6f68b4..fb82f7d 100644 --- a/arch/arm/mach-bcm2709/armctrl.c +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -45,6 +45,8 @@ static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { @@ -133956,7 +134272,7 @@ index a366275..90805a6 100644 writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); } else if (d->irq == INTERRUPT_ARM_LOCAL_PMU_FAST) { diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index dec8043..fe71c50 100644 +index ea3b689..ad4993f5 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c @@ -96,6 +96,7 @@ static unsigned w1_gpio_pin = W1_GPIO; @@ -133967,7 +134283,7 @@ index dec8043..fe71c50 100644 static unsigned use_dt = 0; -@@ -1305,6 +1306,7 @@ MACHINE_START(BCM2708, "BCM2709") +@@ -1290,6 +1291,7 @@ MACHINE_START(BCM2708, "BCM2709") .dt_compat = bcm2709_compat, MACHINE_END @@ -133976,20 +134292,20 @@ index dec8043..fe71c50 100644 module_param(serial, uint, 0644); module_param(uart_clock, uint, 0644); -From fbedbf309c2ee139e3eace31eb388fc0c8c75301 Mon Sep 17 00:00:00 2001 +From 9a2d16a38a17ceb644ffaf913c75ffca38958c2e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 18 Jun 2015 17:46:17 +0100 -Subject: [PATCH 074/204] mach-bcm270x: Enable the building of pinctrl-bcm2835 +Subject: [PATCH 083/113] mach-bcm270x: Enable the building of pinctrl-bcm2835 --- drivers/pinctrl/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 6eadf04..9119513 100644 +index cad077c..26b0bb4 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile -@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o +@@ -39,6 +39,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o @@ -133998,2113 +134314,10 @@ index 6eadf04..9119513 100644 obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-y += freescale/ -From 697b347118f88f65839dbf93dfc583b06407e791 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 19 Jun 2015 16:41:39 +0100 -Subject: [PATCH 075/204] BCM270X_DT: Document the i2s-mmap overlay - ---- - arch/arm/boot/dts/overlays/README | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 3e08f98..7fa6d33 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -260,6 +260,12 @@ Params: ds1307 Select the DS1307 device - pcf8563 Select the PCF8563 device - - -+Name: i2s-mmap -+Info: Enables mmap support in the bcm2708-i2s driver -+Load: dtoverlay=i2s-mmap -+Params: -+ -+ - Name: iqaudio-dac - Info: Configures the IQaudio DAC audio card - Load: dtoverlay=iqaudio-dac - -From 459023e570ec920d21cf3d01988a595f9027c87c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 17 Jun 2015 11:36:53 +0100 -Subject: [PATCH 076/204] bcm2835-sdhost: Improve error handling and recovery - -1) Expose the hw_reset method to the MMC framework, removing many - internal calls by the driver. - -2) Reduce overclock setting on error. - -3) Increase timeout to cope with high capacity cards. - -4) Add properties and parameters to control pio_limit and debug. - -5) Reduce messages at probe time. ---- - arch/arm/boot/dts/overlays/README | 8 +- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 4 +- - drivers/mmc/host/bcm2835-sdhost.c | 578 ++++++++++++++++++-------- - 3 files changed, 404 insertions(+), 186 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7fa6d33..63da266 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -408,7 +408,13 @@ Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock - Load: dtoverlay=sdhost,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz -- force_pio Disable DMA support -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 2) -+ -+ debug Enable debug output (default off) - - - Name: spi-bcm2708 -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index 8fb28e9..b408ab4 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -22,6 +22,7 @@ - dma-names = "tx", "rx"; - brcm,delay-after-stop = <0>; - brcm,overclock-50 = <0>; -+ brcm,pio-limit = <2>; - status = "okay"; - }; - }; -@@ -70,9 +71,10 @@ - }; - - __overrides__ { -- delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; - overclock_50 = <&sdhost>,"brcm,overclock-50:0"; - force_pio = <&sdhost>,"brcm,force-pio?"; -+ pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ debug = <&sdhost>,"brcm,debug?"; - sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - }; - }; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index eef8a24..6277e43 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -90,9 +90,8 @@ - /* Reserved */ - #define SDHSTS_DATA_FLAG 0x01 - --#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) -+#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) - #define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) --/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ - - #define SDHCFG_BUSY_IRPT_EN (1<<10) - #define SDHCFG_BLOCK_IRPT_EN (1<<8) -@@ -111,16 +110,7 @@ - #define SDEDM_READ_THRESHOLD_SHIFT 14 - #define SDEDM_THRESHOLD_MASK 0x1f - --/* the inclusive limit in bytes under which PIO will be used instead of DMA */ --#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER --#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER --#else --#define PIO_DMA_BARRIER 0 --#endif -- --#define MIN_FREQ 400000 --#define TIMEOUT_VAL 0xE --#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) -+#define MHZ 1000000 - - #ifndef BCM2708_PERI_BASE - #define BCM2708_PERI_BASE 0x20000000 -@@ -138,19 +128,20 @@ struct bcm2835_host { - - struct mmc_host *mmc; - -- u32 timeout; -+ u32 pio_timeout; /* In jiffies */ - - int clock; /* Current clock speed */ - - bool slow_card; /* Force 11-bit divisor */ - - unsigned int max_clk; /* Max possible freq */ -- unsigned int timeout_clk; /* Timeout freq (KHz) */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - - struct timer_list timer; /* Timer for timeouts */ - -+ struct timer_list pio_timer; /* PIO error detection timer */ -+ - struct sg_mapping_iter sg_miter; /* SG state for PIO */ - unsigned int blocks; /* remaining PIO blocks */ - -@@ -170,6 +161,10 @@ struct bcm2835_host { - - unsigned int use_busy:1; /* Wait for busy interrupt */ - -+ unsigned int reduce_overclock:1; /* ...at the next opportunity */ -+ -+ unsigned int debug:1; /* Enable debug output */ -+ - u32 thread_isr; - - /*DMA part*/ -@@ -185,7 +180,8 @@ struct bcm2835_host { - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -- u32 max_overclock; /* Highest reported */ -+ u32 overclock; /* Current frequency if overclocked, else zero */ -+ u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - }; - - -@@ -204,41 +200,79 @@ static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg - return readl_relaxed(host->ioaddr + reg); - } - -+static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, -+ struct mmc_command *cmd, -+ const char *label) -+{ -+ if (cmd) -+ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", -+ mmc_hostname(host->mmc), -+ (cmd == host->cmd) ? '>' : ' ', -+ label, cmd->opcode, cmd->arg, cmd->flags, -+ cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], -+ cmd->error); -+} -+ - static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) - { -- pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", -+ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -+ if (host->mrq->data) -+ pr_err("%s: data blocks %x blksz %x - err %d\n", -+ mmc_hostname(host->mmc), -+ host->mrq->data->blocks, -+ host->mrq->data->blksz, -+ host->mrq->data->error); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); -+ -+ pr_info("%s: =========== REGISTER DUMP ===========\n", - mmc_hostname(host->mmc)); - -- pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", -+ pr_info("%s: SDCMD 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCMD)); -- pr_info(DRIVER_NAME ": SDARG 0x%08x\n", -+ pr_info("%s: SDARG 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDARG)); -- pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", -+ pr_info("%s: SDTOUT 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDTOUT)); -- pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", -+ pr_info("%s: SDCDIV 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCDIV)); -- pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", -+ pr_info("%s: SDRSP0 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP0)); -- pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", -+ pr_info("%s: SDRSP1 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP1)); -- pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", -+ pr_info("%s: SDRSP2 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP2)); -- pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", -+ pr_info("%s: SDRSP3 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP3)); -- pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", -+ pr_info("%s: SDHSTS 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHSTS)); -- pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", -+ pr_info("%s: SDVDD 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDVDD)); -- pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", -+ pr_info("%s: SDEDM 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDEDM)); -- pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", -+ pr_info("%s: SDHCFG 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHCFG)); -- pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", -+ pr_info("%s: SDHBCT 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBCT)); -- pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", -+ pr_info("%s: SDHBLC 0x%08x\n", -+ mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBLC)); - -- pr_debug(DRIVER_NAME ": ===========================================\n"); -+ pr_info("%s: ===========================================\n", -+ mmc_hostname(host->mmc)); - } - - -@@ -248,12 +282,10 @@ static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) - } - - --static void bcm2835_sdhost_reset(struct bcm2835_host *host) -+static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - { - u32 temp; - -- pr_debug("bcm2835_sdhost_reset\n"); -- - bcm2835_sdhost_set_power(host, false); - - bcm2835_sdhost_write(host, 0, SDCMD); -@@ -281,6 +313,20 @@ static void bcm2835_sdhost_reset(struct bcm2835_host *host) - mmiowb(); - } - -+ -+static void bcm2835_sdhost_reset(struct mmc_host *mmc) -+{ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ if (host->debug) -+ pr_info("%s: reset\n", mmc_hostname(mmc)); -+ spin_lock_irqsave(&host->lock, flags); -+ -+ bcm2835_sdhost_reset_internal(host); -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - - static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) -@@ -290,7 +336,7 @@ static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) - /* Set interrupt enables */ - host->hcfg = SDHCFG_BUSY_IRPT_EN; - -- bcm2835_sdhost_reset(host); -+ bcm2835_sdhost_reset_internal(host); - - if (soft) { - /* force clock reconfiguration */ -@@ -420,6 +466,40 @@ static void bcm2835_sdhost_dma_complete(void *param) - spin_unlock_irqrestore(&host->lock, flags); - } - -+static bool data_transfer_wait(struct bcm2835_host *host, const char *caller) -+{ -+ unsigned long timeout = 1000000; -+ u32 hsts; -+ while (timeout) -+ { -+ hsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (hsts & (SDHSTS_TRANSFER_ERROR_MASK | -+ SDHSTS_DATA_FLAG)) { -+ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -+ SDHSTS); -+ break; -+ } -+ timeout--; -+ } -+ -+ if (hsts & (SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) { -+ pr_err("%s: data error in %s - HSTS %x\n", -+ mmc_hostname(host->mmc), caller, hsts); -+ host->data->error = -EILSEQ; -+ return false; -+ } else if ((timeout == 0) || -+ (hsts & (SDHSTS_CMD_TIME_OUT | -+ SDHSTS_REW_TIME_OUT))) { -+ pr_err("%s: timeout in %s - HSTS %x\n", -+ mmc_hostname(host->mmc), caller, hsts); -+ host->data->error = -ETIMEDOUT; -+ return false; -+ } -+ return true; -+} -+ - static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - { - unsigned long flags; -@@ -443,35 +523,15 @@ static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - buf = (u32 *)host->sg_miter.addr; - - while (len) { -- while (1) { -- u32 hsts; -- hsts = bcm2835_sdhost_read(host, SDHSTS); -- if (hsts & SDHSTS_DATA_FLAG) -- break; -- -- if (hsts & SDHSTS_ERROR_MASK) { -- pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", -- mmc_hostname(host->mmc), -- hsts, -- bcm2835_sdhost_read(host, SDHBCT), -- blksize + len); -- if (hsts & SDHSTS_REW_TIME_OUT) -- host->data->error = -ETIMEDOUT; -- else if (hsts & (SDHSTS_CRC16_ERROR || -- SDHSTS_CRC7_ERROR)) -- host->data->error = -EILSEQ; -- else { -- pr_err("%s: unexpected data error\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -- } -- } -- } -+ if (!data_transfer_wait(host, "read_block_pio")) -+ break; - - *(buf++) = bcm2835_sdhost_read(host, SDDATA); - len -= 4; - } -+ -+ if (host->data->error) -+ break; - } - - sg_miter_stop(&host->sg_miter); -@@ -502,11 +562,15 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - buf = host->sg_miter.addr; - - while (len) { -- while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) -- continue; -+ if (!data_transfer_wait(host, "write_block_pio")) -+ break; -+ - bcm2835_sdhost_write(host, *(buf++), SDDATA); - len -= 4; - } -+ -+ if (host->data->error) -+ break; - } - - sg_miter_stop(&host->sg_miter); -@@ -519,10 +583,15 @@ static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - { - BUG_ON(!host->data); - -- if (host->data->flags & MMC_DATA_READ) -+ if (host->data->flags & MMC_DATA_READ) { - bcm2835_sdhost_read_block_pio(host); -- else -+ } else { - bcm2835_sdhost_write_block_pio(host); -+ -+ /* Start a timer in case a transfer error occurs because -+ there is no error interrupt */ -+ mod_timer(&host->pio_timer, jiffies + host->pio_timeout); -+ } - } - - -@@ -607,6 +676,7 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -+ host->use_dma = host->have_dma && (data->blocks > host->pio_limit); - if (!host->use_dma) { - int flags; - -@@ -619,8 +689,6 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->blocks = data->blocks; - } - -- host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; -- - bcm2835_sdhost_set_transfer_irqs(host); - - bcm2835_sdhost_write(host, data->blksz, SDHBCT); -@@ -638,22 +706,25 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - - WARN_ON(host->cmd); - -- if (1) { -- pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", -- cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); -- if (cmd->data) -- pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", -- (cmd->data->flags & MMC_DATA_READ) ? -- "read" : "write", cmd->data->blocks, -- cmd->data->blksz); -- } -+ if (cmd->data) -+ pr_debug("%s: send_command %d 0x%x " -+ "(flags 0x%x) - %s %d*%d\n", -+ mmc_hostname(host->mmc), -+ cmd->opcode, cmd->arg, cmd->flags, -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ else -+ pr_debug("%s: send_command %d 0x%x (flags 0x%x)\n", -+ mmc_hostname(host->mmc), -+ cmd->opcode, cmd->arg, cmd->flags); - - /* Wait max 10 ms */ - timeout = 1000; - - while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { - if (timeout == 0) { -- pr_err("%s: Previous command never completed.\n", -+ pr_err("%s: previous command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - cmd->error = -EIO; -@@ -666,16 +737,16 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - - if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { - host->max_delay = (1000-timeout)/100; -- pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); -+ pr_warning("%s: controller hung for %d ms\n", -+ mmc_hostname(host->mmc), -+ host->max_delay); - } - - timeout = jiffies; --#ifdef CONFIG_ARCH_BCM2835 - if (!cmd->data && cmd->busy_timeout > 9000) - timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; - else --#endif -- timeout += 10 * HZ; -+ timeout += 10 * HZ; - mod_timer(&host->timer, timeout); - - host->cmd = cmd; -@@ -685,7 +756,7 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - bcm2835_sdhost_write(host, cmd->arg, SDARG); - - if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { -- pr_err("%s: Unsupported response type!\n", -+ pr_err("%s: unsupported response type!\n", - mmc_hostname(host->mmc)); - cmd->error = -EINVAL; - tasklet_schedule(&host->finish_tasklet); -@@ -783,13 +854,6 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - pr_debug("transfer_complete(error %d, stop %d)\n", - data->error, data->stop ? 1 : 0); - -- if (data->error) -- /* -- * The controller needs a reset of internal state machines -- * upon error conditions. -- */ -- bcm2835_sdhost_reset(host); -- - /* - * Need to send CMD12 if - - * a) open-ended multiblock transfer (no CMD23) -@@ -845,7 +909,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - #endif - - if (timeout == 0) { -- pr_err("%s: Command never completed.\n", -+ pr_err("%s: command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - host->cmd->error = -EIO; -@@ -875,14 +939,23 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - { - u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); - -- pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -- mmc_hostname(host->mmc), sdcmd, sdhsts, -- bcm2835_sdhost_read(host, SDEDM)); -- -- if (sdhsts & SDHSTS_CMD_TIME_OUT) -+ if (host->debug) -+ pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -+ mmc_hostname(host->mmc), sdcmd, sdhsts, -+ bcm2835_sdhost_read(host, SDEDM)); -+ -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) { -+ switch (host->cmd->opcode) { -+ case 5: case 52: case 53: -+ /* Don't warn about SDIO commands */ -+ break; -+ default: -+ pr_err("%s: command timeout\n", -+ mmc_hostname(host->mmc)); -+ break; -+ } - host->cmd->error = -ETIMEDOUT; -- else -- { -+ } else { - pr_err("%s: unexpected command error\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); -@@ -897,11 +970,13 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - int i; - for (i = 0; i < 4; i++) - host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); -- pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", -+ pr_debug("%s: finish_command %08x %08x %08x %08x\n", -+ mmc_hostname(host->mmc), - host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); - } else { - host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); -- pr_debug("bcm2835_sdhost_finish_command: %08x\n", -+ pr_debug("%s: finish_command %08x\n", -+ mmc_hostname(host->mmc), - host->cmd->resp[0]); - } - } -@@ -932,7 +1007,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - } - } - --static void bcm2835_sdhost_timeout_timer(unsigned long data) -+static void bcm2835_sdhost_timeout(unsigned long data) - { - struct bcm2835_host *host; - unsigned long flags; -@@ -942,7 +1017,7 @@ static void bcm2835_sdhost_timeout_timer(unsigned long data) - spin_lock_irqsave(&host->lock, flags); - - if (host->mrq) { -- pr_err("%s: Timeout waiting for hardware interrupt.\n", -+ pr_err("%s: timeout waiting for hardware interrupt.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - -@@ -964,6 +1039,41 @@ static void bcm2835_sdhost_timeout_timer(unsigned long data) - spin_unlock_irqrestore(&host->lock, flags); - } - -+static void bcm2835_sdhost_pio_timeout(unsigned long data) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ host = (struct bcm2835_host *)data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->data) { -+ u32 hsts = bcm2835_sdhost_read(host, SDHSTS); -+ -+ if (hsts & SDHSTS_REW_TIME_OUT) { -+ pr_err("%s: transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); -+ } else { -+ pr_err("%s: unexpected transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -+ SDHSTS); -+ -+ host->data->error = -ETIMEDOUT; -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ - static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) - { - if (enable) -@@ -979,7 +1089,7 @@ static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; - -- pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); -+ pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); - spin_lock_irqsave(&host->lock, flags); - bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); - spin_unlock_irqrestore(&host->lock, flags); -@@ -987,11 +1097,12 @@ static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) - - static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - { -- const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | -+ SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR); - - if (!host->cmd) { -- pr_err("%s: Got command busy interrupt 0x%08x even " -+ pr_err("%s: got command busy interrupt 0x%08x even " - "though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -@@ -999,7 +1110,7 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - } - - if (!host->use_busy) { -- pr_err("%s: Got command busy interrupt 0x%08x even " -+ pr_err("%s: got command busy interrupt 0x%08x even " - "though not expecting one.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -@@ -1007,14 +1118,28 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - } - host->use_busy = 0; - -- if (intmask & SDHSTS_CMD_TIME_OUT) -- host->cmd->error = -ETIMEDOUT; -- else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -- SDHSTS_FIFO_ERROR)) -- host->cmd->error = -EILSEQ; -+ if (intmask & SDHSTS_ERROR_MASK) -+ { -+ pr_err("sdhost_busy_irq: intmask %x, data %p\n", intmask, host->mrq->data); -+ if (intmask & SDHSTS_CRC7_ERROR) -+ host->cmd->error = -EILSEQ; -+ else if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR)) { -+ if (host->mrq->data) -+ host->mrq->data->error = -EILSEQ; -+ else -+ host->cmd->error = -EILSEQ; -+ } else if (intmask & SDHSTS_REW_TIME_OUT) { -+ if (host->mrq->data) -+ host->mrq->data->error = -ETIMEDOUT; -+ else -+ host->cmd->error = -ETIMEDOUT; -+ } else if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; - -- if (host->cmd->error) -+ bcm2835_sdhost_dumpregs(host); - tasklet_schedule(&host->finish_tasklet); -+ } - else - bcm2835_sdhost_finish_command(host); - -@@ -1023,8 +1148,9 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - - static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - { -- const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); - - /* There are no dedicated data/space available interrupt - status bits, so it is necessary to use the single shared -@@ -1034,13 +1160,19 @@ static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - if (!host->data) - return 0; - -- // XXX FIFO_ERROR -- if (intmask & SDHSTS_CMD_TIME_OUT) -- host->cmd->error = -ETIMEDOUT; -- else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -- ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -- != MMC_BUS_TEST_R)) -- host->cmd->error = -EILSEQ; -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR | -+ SDHSTS_REW_TIME_OUT)) { -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->data->error = -EILSEQ; -+ else -+ host->data->error = -ETIMEDOUT; -+ -+ bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; -+ } - - /* Use the block interrupt for writes after the first block */ - if (host->data->flags & MMC_DATA_WRITE) { -@@ -1067,31 +1199,48 @@ static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - { - struct dma_chan *dma_chan; - u32 dir_data; -- const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); - - if (!host->data) { -- pr_err("%s: Got block interrupt 0x%08x even " -+ pr_err("%s: got block interrupt 0x%08x even " - "though no data operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); - return handled; - } - -- if (intmask & SDHSTS_CMD_TIME_OUT) -- host->cmd->error = -ETIMEDOUT; -- else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -- ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -- != MMC_BUS_TEST_R)) -- host->cmd->error = -EILSEQ; -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR | -+ SDHSTS_REW_TIME_OUT)) { -+ if (intmask & (SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->data->error = -EILSEQ; -+ else -+ host->data->error = -ETIMEDOUT; -+ -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; -+ } - - if (!host->use_dma) { - BUG_ON(!host->blocks); - host->blocks--; -- if ((host->blocks == 0) || host->data->error) -+ if ((host->blocks == 0) || host->data->error) { -+ /* Cancel the timer */ -+ del_timer(&host->pio_timer); -+ - bcm2835_sdhost_finish_data(host); -- else -+ } else { - bcm2835_sdhost_transfer_pio(host); -+ -+ /* Reset the timer */ -+ mod_timer(&host->pio_timer, -+ jiffies + host->pio_timeout); -+ } - } else if (host->data->flags & MMC_DATA_WRITE) { - dma_chan = host->dma_chan_tx; - dir_data = DMA_TO_DEVICE; -@@ -1125,7 +1274,7 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - SDHSTS_BLOCK_IRPT | - SDHSTS_SDIO_IRPT | - SDHSTS_DATA_FLAG); -- if ((handled == SDHSTS_DATA_FLAG) && // XXX -+ if ((handled == SDHSTS_DATA_FLAG) && - (loops == 0) && !host->data) { - pr_err("%s: sdhost_irq data interrupt 0x%08x even " - "though no data operation was in progress.\n", -@@ -1177,10 +1326,11 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - spin_unlock(&host->lock); - - if (early) -- pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); -+ pr_debug("%s: early %x (loops %d)\n", -+ mmc_hostname(host->mmc), early, loops); - - if (unexpected) { -- pr_err("%s: Unexpected interrupt 0x%08x.\n", -+ pr_err("%s: unexpected interrupt 0x%08x.\n", - mmc_hostname(host->mmc), unexpected); - bcm2835_sdhost_dumpregs(host); - } -@@ -1227,8 +1377,22 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - int div = 0; /* Initialized for compiler warning */ - unsigned int input_clock = clock; - -- if (host->overclock_50 && (clock == 50000000)) -- clock = host->overclock_50 * 1000000 + 999999; -+ if (host->debug) -+ pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -+ -+ if ((clock == 0) && host->reduce_overclock) { -+ /* This is a reset following data corruption - reduce any -+ overclock */ -+ host->reduce_overclock = 0; -+ if (host->overclock_50 > 50) { -+ pr_warn("%s: reducing overclock due to errors\n", -+ mmc_hostname(host->mmc)); -+ host->overclock_50--; -+ } -+ } -+ -+ if (host->overclock_50 && (clock == 50*MHZ)) -+ clock = host->overclock_50 * MHZ + (MHZ - 1); - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1275,17 +1439,34 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - -- if ((clock > input_clock) && (clock > host->max_overclock)) { -- pr_warn("%s: Overclocking to %dHz\n", -- mmc_hostname(host->mmc), clock); -- host->max_overclock = clock; -+ if (clock > input_clock) { -+ /* Save the closest value, to make it easier -+ to reduce in the event of error */ -+ host->overclock_50 = (clock/MHZ); -+ -+ if (clock != host->overclock) { -+ pr_warn("%s: overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); -+ host->overclock = clock; -+ } -+ } -+ else if ((clock == 50 * MHZ) && host->overclock) -+ { -+ pr_warn("%s: cancelling overclock\n", -+ mmc_hostname(host->mmc)); -+ host->overclock = 0; - } - - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -- input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); -+ -+ if (host->debug) -+ pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), input_clock, -+ host->max_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1293,29 +1474,32 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - struct bcm2835_host *host; - unsigned long flags; - -- if (1) { -+ host = mmc_priv(mmc); -+ -+ if (host->debug) { - struct mmc_command *cmd = mrq->cmd; -- const char *src = "cmd"; - BUG_ON(!cmd); -- pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", -- src, cmd->opcode, cmd->arg, cmd->flags); - if (cmd->data) -- pr_debug("bcm2835_sdhost_request: %s %d*%d\n", -- (cmd->data->flags & MMC_DATA_READ) ? -- "read" : "write", cmd->data->blocks, -- cmd->data->blksz); -+ pr_info("%s: cmd %d 0x%x (flags 0x%x) - %s %d*%d\n", -+ mmc_hostname(mmc), -+ cmd->opcode, cmd->arg, cmd->flags, -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ else -+ pr_info("%s: cmd %d 0x%x (flags 0x%x)\n", -+ mmc_hostname(mmc), -+ cmd->opcode, cmd->arg, cmd->flags); - } - - if (mrq->data && !is_power_of_2(mrq->data->blksz)) { -- pr_err("%s: Unsupported block size (%d bytes)\n", -+ pr_err("%s: unsupported block size (%d bytes)\n", - mmc_hostname(mmc), mrq->data->blksz); - mrq->cmd->error = -EINVAL; - mmc_request_done(mmc, mrq); - return; - } - -- host = mmc_priv(mmc); -- - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -@@ -1345,9 +1529,12 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; - -- pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -- ios->clock, ios->power_mode, ios->bus_width, -- ios->timing, ios->signal_voltage, ios->drv_type); -+ if (host->debug) -+ pr_info("%s: ios clock %d, pwr %d, bus_width %d, " -+ "timing %d, vdd %d, drv_type %d\n", -+ mmc_hostname(mmc), -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); - - spin_lock_irqsave(&host->lock, flags); - -@@ -1396,6 +1583,7 @@ static struct mmc_host_ops bcm2835_sdhost_ops = { - .request = bcm2835_sdhost_request, - .set_ios = bcm2835_sdhost_set_ios, - .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, -+ .hw_reset = bcm2835_sdhost_reset, - .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, - }; - -@@ -1423,15 +1611,24 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - mrq = host->mrq; - -- /* -- * The controller needs a reset of internal state machines -- * upon error conditions. -- */ -- if (((mrq->cmd && mrq->cmd->error) || -- (mrq->data && (mrq->data->error || -- (mrq->data->stop && mrq->data->stop->error))))) { -+ /* Drop the overclock after any data corruption, or after any -+ error overclocked */ -+ if (mrq->data && (mrq->data->error == -EILSEQ)) -+ host->reduce_overclock = 1; -+ else if (host->overclock) { -+ /* Convert timeout errors while overclocked to data errors, -+ because the system recovers better. */ -+ if (mrq->cmd && mrq->cmd->error) { -+ host->reduce_overclock = 1; -+ if (mrq->cmd->error == -ETIMEDOUT) -+ mrq->cmd->error = -EILSEQ; -+ } - -- bcm2835_sdhost_reset(host); -+ if (mrq->data && mrq->data->error) { -+ host->reduce_overclock = 1; -+ if (mrq->data->error == -ETIMEDOUT) -+ mrq->data->error = -EILSEQ; -+ } - } - - host->mrq = NULL; -@@ -1450,35 +1647,37 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - { - struct mmc_host *mmc; - struct dma_slave_config cfg; -+ char pio_limit_string[20]; - int ret; - - mmc = host->mmc; - -- bcm2835_sdhost_reset(host); -+ bcm2835_sdhost_reset_internal(host); - - mmc->f_max = host->max_clk; - mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; - -- /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ -- host->timeout_clk = mmc->f_max / 1000; --#ifdef CONFIG_ARCH_BCM2835 -- mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; --#endif -+ mmc->max_busy_timeout = (~(unsigned int)0)/(mmc->f_max/1000); -+ -+ pr_debug("f_max %d, f_min %d, max_busy_timeout %d\n", -+ mmc->f_max, mmc->f_min, mmc->max_busy_timeout); -+ - /* host controller capabilities */ - mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -- MMC_CAP_NEEDS_POLL | -+ MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | - (ALLOW_CMD23 * MMC_CAP_CMD23); - - spin_lock_init(&host->lock); - - if (host->allow_dma) { -- if (!host->dma_chan_tx || !host->dma_chan_rx || -- IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { -- pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); -+ if (IS_ERR_OR_NULL(host->dma_chan_tx) || -+ IS_ERR_OR_NULL(host->dma_chan_rx)) { -+ pr_err("%s: unable to initialise DMA channels. " -+ "Falling back to PIO\n", -+ mmc_hostname(mmc)); - host->have_dma = false; - } else { -- pr_info("DMA channels allocated for the SDHost driver"); - host->have_dma = true; - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -@@ -1496,7 +1695,6 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); - } - } else { -- pr_info("Forcing PIO mode\n"); - host->have_dma = false; - } - -@@ -1512,18 +1710,23 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - tasklet_init(&host->finish_tasklet, - bcm2835_sdhost_tasklet_finish, (unsigned long)host); - -- setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); -+ setup_timer(&host->timer, bcm2835_sdhost_timeout, -+ (unsigned long)host); -+ -+ setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, -+ (unsigned long)host); - - bcm2835_sdhost_init(host, 0); - #ifndef CONFIG_ARCH_BCM2835 - ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, - mmc_hostname(mmc), host); - #else -- ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, -+ bcm2835_sdhost_thread_irq, - IRQF_SHARED, mmc_hostname(mmc), host); - #endif - if (ret) { -- pr_err("%s: Failed to request IRQ %d: %d\n", -+ pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); - goto untasklet; - } -@@ -1531,10 +1734,13 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - mmiowb(); - mmc_add_host(mmc); - -- pr_info("Load BCM2835 SDHost driver\n"); -- if (host->delay_after_stop) -- pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", -- host->delay_after_stop); -+ pio_limit_string[0] = '\0'; -+ if (host->have_dma && (host->pio_limit > 0)) -+ sprintf(pio_limit_string, " (>%d)", host->pio_limit); -+ pr_info("%s: %s loaded - DMA %s%s\n", -+ mmc_hostname(mmc), DRIVER_NAME, -+ host->have_dma ? "enabled" : "disabled", -+ pio_limit_string); - - return 0; - -@@ -1562,7 +1768,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - mmc->ops = &bcm2835_sdhost_ops; - host = mmc_priv(mmc); - host->mmc = mmc; -- host->timeout = msecs_to_jiffies(1000); -+ host->pio_timeout = msecs_to_jiffies(500); - spin_lock_init(&host->lock); - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -1588,8 +1794,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - of_property_read_u32(node, - "brcm,overclock-50", - &host->overclock_50); -+ of_property_read_u32(node, -+ "brcm,pio-limit", -+ &host->pio_limit); - host->allow_dma = ALLOW_DMA && - !of_property_read_bool(node, "brcm,force-pio"); -+ host->debug = of_property_read_bool(node, "brcm,debug"); - } - - if (host->allow_dma) { - -From 1b37e961ff949769a09160dcc9567c47f8d093e6 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Jun 2015 13:11:46 -0700 -Subject: [PATCH 077/204] ARM: bcm2835: Add the Raspberry Pi firmware driver - -This gives us a function for making mailbox property channel requests -of the firmware, which is most notable in that it will let us get and -set clock rates. - -Signed-off-by: Eric Anholt ---- - drivers/firmware/Kconfig | 7 + - drivers/firmware/Makefile | 1 + - drivers/firmware/raspberrypi.c | 260 +++++++++++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 115 +++++++++++++ - 4 files changed, 383 insertions(+) - create mode 100644 drivers/firmware/raspberrypi.c - create mode 100644 include/soc/bcm2835/raspberrypi-firmware.h - -diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig -index 6517132..564aa5b 100644 ---- a/drivers/firmware/Kconfig -+++ b/drivers/firmware/Kconfig -@@ -136,6 +136,13 @@ config QCOM_SCM - bool - depends on ARM || ARM64 - -+config RASPBERRYPI_FIRMWARE -+ tristate "Raspberry Pi Firmware Driver" -+ depends on BCM2835_MBOX -+ help -+ This option enables support for communicating with the firmware on the -+ Raspberry Pi. -+ - source "drivers/firmware/google/Kconfig" - source "drivers/firmware/efi/Kconfig" - -diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile -index 3fdd391..ee101a2 100644 ---- a/drivers/firmware/Makefile -+++ b/drivers/firmware/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o - obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o - obj-$(CONFIG_QCOM_SCM) += qcom_scm.o - CFLAGS_qcom_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) -+obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o - - obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ - obj-$(CONFIG_EFI) += efi/ -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -new file mode 100644 -index 0000000..dd506cd3 ---- /dev/null -+++ b/drivers/firmware/raspberrypi.c -@@ -0,0 +1,260 @@ -+/* -+ * Defines interfaces for interacting wtih the Raspberry Pi firmware's -+ * property channel. -+ * -+ * Copyright © 2015 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_CHAN_PROPERTY 8 -+ -+struct rpi_firmware { -+ struct mbox_client cl; -+ struct mbox_chan *chan; /* The property channel. */ -+ struct completion c; -+ u32 enabled; -+}; -+ -+static DEFINE_MUTEX(transaction_lock); -+ -+static void response_callback(struct mbox_client *cl, void *msg) -+{ -+ struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); -+ complete(&fw->c); -+} -+ -+/* -+ * Sends a request to the firmware through the BCM2835 mailbox driver, -+ * and synchronously waits for the reply. -+ */ -+static int -+rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) -+{ -+ u32 message = MBOX_MSG(chan, data); -+ int ret; -+ -+ WARN_ON(data & 0xf); -+ -+ mutex_lock(&transaction_lock); -+ reinit_completion(&fw->c); -+ ret = mbox_send_message(fw->chan, &message); -+ if (ret >= 0) { -+ wait_for_completion(&fw->c); -+ ret = 0; -+ } else { -+ dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); -+ } -+ mutex_unlock(&transaction_lock); -+ -+ return ret; -+} -+ -+/** -+ * rpi_firmware_property_list - Submit firmware property list -+ * @fw: Pointer to firmware structure from rpi_firmware_get(). -+ * @data: Buffer holding tags. -+ * @tag_size: Size of tags buffer. -+ * -+ * Submits a set of concatenated tags to the VPU firmware through the -+ * mailbox property interface. -+ * -+ * The buffer header and the ending tag are added by this function and -+ * don't need to be supplied, just the actual tags for your operation. -+ * See struct rpi_firmware_property_tag_header for the per-tag -+ * structure. -+ */ -+int rpi_firmware_property_list(struct rpi_firmware *fw, -+ void *data, size_t tag_size) -+{ -+ size_t size = tag_size + 12; -+ u32 *buf; -+ dma_addr_t bus_addr; -+ int ret; -+ -+ /* Packets are processed a dword at a time. */ -+ if (size & 3) -+ return -EINVAL; -+ -+ buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, -+ GFP_ATOMIC); -+ if (!buf) -+ return -ENOMEM; -+ -+ /* The firmware will error out without parsing in this case. */ -+ WARN_ON(size >= 1024 * 1024); -+ -+ buf[0] = size; -+ buf[1] = RPI_FIRMWARE_STATUS_REQUEST; -+ memcpy(&buf[2], data, tag_size); -+ buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END; -+ wmb(); -+ -+ ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr); -+ -+ rmb(); -+ memcpy(data, &buf[2], tag_size); -+ if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) { -+ /* -+ * The tag name here might not be the one causing the -+ * error, if there were multiple tags in the request. -+ * But single-tag is the most common, so go with it. -+ */ -+ dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", -+ buf[2], buf[1]); -+ ret = -EINVAL; -+ } -+ -+ dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rpi_firmware_property_list); -+ -+/** -+ * rpi_firmware_property - Submit single firmware property -+ * @fw: Pointer to firmware structure from rpi_firmware_get(). -+ * @tag: One of enum_mbox_property_tag. -+ * @tag_data: Tag data buffer. -+ * @buf_size: Buffer size. -+ * -+ * Submits a single tag to the VPU firmware through the mailbox -+ * property interface. -+ * -+ * This is a convenience wrapper around -+ * rpi_firmware_property_list() to avoid some of the -+ * boilerplate in property calls. -+ */ -+int rpi_firmware_property(struct rpi_firmware *fw, -+ u32 tag, void *tag_data, size_t buf_size) -+{ -+ /* Single tags are very small (generally 8 bytes), so the -+ * stack should be safe. -+ */ -+ u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)]; -+ struct rpi_firmware_property_tag_header *header = -+ (struct rpi_firmware_property_tag_header *)data; -+ int ret; -+ -+ header->tag = tag; -+ header->buf_size = buf_size; -+ header->req_resp_size = 0; -+ memcpy(data + sizeof(struct rpi_firmware_property_tag_header), -+ tag_data, buf_size); -+ -+ ret = rpi_firmware_property_list(fw, &data, sizeof(data)); -+ memcpy(tag_data, -+ data + sizeof(struct rpi_firmware_property_tag_header), -+ buf_size); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rpi_firmware_property); -+ -+static void -+rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) -+{ -+ u32 packet; -+ int ret = rpi_firmware_property(fw, -+ RPI_FIRMWARE_GET_FIRMWARE_REVISION, -+ &packet, sizeof(packet)); -+ -+ if (ret == 0) { -+ struct tm tm; -+ -+ time_to_tm(packet, 0, &tm); -+ -+ dev_info(fw->cl.dev, -+ "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -+ tm.tm_hour, tm.tm_min); -+ } -+} -+ -+static int rpi_firmware_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct rpi_firmware *fw; -+ -+ fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); -+ if (!fw) -+ return -ENOMEM; -+ -+ fw->cl.dev = dev; -+ fw->cl.rx_callback = response_callback; -+ fw->cl.tx_block = true; -+ -+ fw->chan = mbox_request_channel(&fw->cl, 0); -+ if (IS_ERR(fw->chan)) { -+ int ret = PTR_ERR(fw->chan); -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "Failed to get mbox channel: %d\n", ret); -+ return ret; -+ } -+ -+ init_completion(&fw->c); -+ -+ platform_set_drvdata(pdev, fw); -+ -+ rpi_firmware_print_firmware_revision(fw); -+ -+ return 0; -+} -+ -+static int rpi_firmware_remove(struct platform_device *pdev) -+{ -+ struct rpi_firmware *fw = platform_get_drvdata(pdev); -+ -+ mbox_free_channel(fw->chan); -+ -+ return 0; -+} -+ -+/** -+ * rpi_firmware_get - Get pointer to rpi_firmware structure. -+ * @firmware_node: Pointer to the firmware Device Tree node. -+ * -+ * Returns NULL is the firmware device is not ready. -+ */ -+struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) -+{ -+ struct platform_device *pdev = of_find_device_by_node(firmware_node); -+ -+ if (!pdev) -+ return NULL; -+ -+ return platform_get_drvdata(pdev); -+} -+EXPORT_SYMBOL_GPL(rpi_firmware_get); -+ -+static const struct of_device_id rpi_firmware_of_match[] = { -+ { .compatible = "raspberrypi,bcm2835-firmware", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rpi_firmware_of_match); -+ -+static struct platform_driver rpi_firmware_driver = { -+ .driver = { -+ .name = "raspberrypi-firmware", -+ .of_match_table = rpi_firmware_of_match, -+ }, -+ .probe = rpi_firmware_probe, -+ .remove = rpi_firmware_remove, -+}; -+module_platform_driver(rpi_firmware_driver); -+ -+MODULE_AUTHOR("Eric Anholt "); -+MODULE_DESCRIPTION("Raspberry Pi firmware driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -new file mode 100644 -index 0000000..9d9efb7 ---- /dev/null -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -0,0 +1,115 @@ -+/* -+ * Copyright © 2015 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+struct rpi_firmware; -+ -+enum rpi_firmware_property_status { -+ RPI_FIRMWARE_STATUS_REQUEST = 0, -+ RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000, -+ RPI_FIRMWARE_STATUS_ERROR = 0x80000001, -+}; -+ -+/** -+ * struct rpi_firmware_property_tag_header - Firmware property tag header -+ * @tag: One of enum_mbox_property_tag. -+ * @buf_size: The number of bytes in the value buffer following this -+ * struct. -+ * @req_resp_size: On submit, the length of the request (though it doesn't -+ * appear to be currently used by the firmware). On return, -+ * the length of the response (always 4 byte aligned), with -+ * the low bit set. -+ */ -+struct rpi_firmware_property_tag_header { -+ u32 tag; -+ u32 buf_size; -+ u32 req_resp_size; -+}; -+ -+enum rpi_firmware_property_tag { -+ RPI_FIRMWARE_PROPERTY_END = 0, -+ RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, -+ -+ RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, -+ RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, -+ -+ RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, -+ RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, -+ RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, -+ RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, -+ RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, -+ RPI_FIRMWARE_GET_CLOCKS = 0x00010007, -+ RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, -+ RPI_FIRMWARE_GET_TIMING = 0x00020002, -+ RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, -+ RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, -+ RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, -+ RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, -+ RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, -+ RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, -+ RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, -+ RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, -+ RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, -+ RPI_FIRMWARE_GET_TURBO = 0x00030009, -+ RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, -+ RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, -+ RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, -+ RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, -+ RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, -+ RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, -+ RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, -+ RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, -+ RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, -+ RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, -+ RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, -+ RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, -+ RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, -+ RPI_FIRMWARE_SET_TURBO = 0x00038009, -+ -+ /* Dispmanx TAGS */ -+ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -+ RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, -+ RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, -+ -+ RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, -+ RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, -+}; -+ -+int rpi_firmware_property(struct rpi_firmware *fw, -+ u32 tag, void *data, size_t len); -+int rpi_firmware_property_list(struct rpi_firmware *fw, -+ void *data, size_t tag_size); -+struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); - -From 9666e309b64fbf73d945c934dc3e991e25218fba Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 22 Mar 2015 13:33:23 +0000 -Subject: [PATCH 078/204] config: Enable ZSMALLOC, ZRAM and PGTABLE_MAPPING - ---- - arch/arm/configs/bcm2709_defconfig | 4 ++++ - arch/arm/configs/bcmrpi_defconfig | 4 ++++ - 2 files changed, 8 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index a3067bf..7ef615c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -49,6 +49,8 @@ CONFIG_OABI_COMPAT=y - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y - CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y - CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y - CONFIG_ZBOOT_ROM_TEXT=0x0 -@@ -389,6 +391,8 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_CRYPTOLOOP=m - CONFIG_BLK_DEV_DRBD=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 6a41231..cacde14 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -44,6 +44,8 @@ CONFIG_OABI_COMPAT=y - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y - CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y - CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y - CONFIG_ZBOOT_ROM_TEXT=0x0 -@@ -382,6 +384,8 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_CRYPTOLOOP=m - CONFIG_BLK_DEV_DRBD=m - -From a767c3cb4c6604ad27b92a36644de098f8bdcabb Mon Sep 17 00:00:00 2001 -From: Gordon Hollingworth -Date: Mon, 22 Jun 2015 16:27:07 +0100 -Subject: [PATCH 079/204] Add rpi-ft5406 overlay Add rpi-ft5406 driver as - module - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 5 +++++ - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 16 ++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 24 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 6947556..19eef3c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -35,6 +35,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 63da266..aa09b6c 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -396,6 +396,11 @@ Params: speed Display SPI bus speed - - xohms Touchpanel sensitivity (X-plate resistance) - -+Name: rpi-ft5406 -+Info: Official Raspberry Pi display touchscreen -+Load: dtoverlay=rpi-ft5406 -+Params: -+ - - Name: rpi-proto - Info: Configures the RPi Proto audio card -diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -new file mode 100644 -index 0000000..40deab5 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -@@ -0,0 +1,16 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ rpi_ft5406: rpi_ft5406 { -+ compatible = "rpi,rpi-ft5406"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7ef615c..7469d07 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -535,6 +535,7 @@ CONFIG_JOYSTICK_XPAD_FF=y - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m - CONFIG_TOUCHSCREEN_STMPE=m - CONFIG_INPUT_MISC=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index cacde14..f952ff2 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -528,6 +528,7 @@ CONFIG_JOYSTICK_XPAD_FF=y - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m - CONFIG_TOUCHSCREEN_STMPE=m - CONFIG_INPUT_MISC=y - -From f13481ed18c0a520fc1776890d1066c1397b358f Mon Sep 17 00:00:00 2001 -From: Gordon Hollingworth -Date: Tue, 23 Jun 2015 09:53:40 +0100 -Subject: [PATCH 080/204] Fix driver detection failure Check that the buffer - response is non-zero meaning the touchscreen was detected - ---- - drivers/input/touchscreen/rpi-ft5406.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c -index f55151b..d41851d 100644 ---- a/drivers/input/touchscreen/rpi-ft5406.c -+++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -184,7 +184,7 @@ static int ft5406_probe(struct platform_device *pdev) - - bcm_mailbox_property(&request, sizeof(request)); - -- if(request.request_code == VCMSG_REQUEST_SUCCESSFUL) -+ if(request.request_code == VCMSG_REQUEST_SUCCESSFUL && request.tag.val != 0) - { - dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", request.tag.val); - } - -From 7b53303429e40fddef7ffeb405f898af16adf578 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 23 Jun 2015 13:24:01 +0100 -Subject: [PATCH 081/204] config: Enable 8250 serial port - ---- - arch/arm/configs/bcm2709_defconfig | 7 +++++++ - arch/arm/configs/bcmrpi_defconfig | 7 +++++++ - 2 files changed, 14 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7469d07..7e8643c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -557,8 +557,15 @@ CONFIG_GAMEPORT_L4=m - CONFIG_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=1 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_BCM2835=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index f952ff2..0c25d8b 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -550,8 +550,15 @@ CONFIG_GAMEPORT_L4=m - CONFIG_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=1 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_BCM2835=m - -From 1ae977a7312c852775ea4bd9da294d7010e42dff Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 23 Jun 2015 14:10:58 +0100 -Subject: [PATCH 082/204] config: Enable POWER_RESET_GPIO - ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7e8643c..46d56d7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -606,6 +606,8 @@ CONFIG_W1_SLAVE_DS2781=m - CONFIG_W1_SLAVE_DS28E04=m - CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0c25d8b..e757db6 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -599,6 +599,8 @@ CONFIG_W1_SLAVE_DS2781=m - CONFIG_W1_SLAVE_DS28E04=m - CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - -From 5c8ef44617382fa1fa35577714eb1d4e2e17b647 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 26 Jun 2015 17:37:38 +0100 -Subject: [PATCH 083/204] bcm2708-vcio: Remove restriction of only a single - instance being open - -We need more than one process to be able to use mailbox interface (e.g. HW cursor in fbturbo and hello_fft). -Locking should be handled on each mailbox access ---- - drivers/mailbox/bcm2708-vcio.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index d91672b..06fb2c2f 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -242,20 +242,9 @@ EXPORT_SYMBOL_GPL(bcm_mailbox_property); - - /* Platform Device for Mailbox */ - --/* -- * Is the device open right now? Used to prevent -- * concurent access into the same device -- */ --static bool device_is_open; -- - /* This is called whenever a process attempts to open the device file */ - static int device_open(struct inode *inode, struct file *file) - { -- /* We don't want to talk to two processes at the same time */ -- if (device_is_open) -- return -EBUSY; -- -- device_is_open = true; - try_module_get(THIS_MODULE); - - return 0; -@@ -263,9 +252,6 @@ static int device_open(struct inode *inode, struct file *file) - - static int device_release(struct inode *inode, struct file *file) - { -- /* We're now ready for our next caller */ -- device_is_open = false; -- - module_put(THIS_MODULE); - - return 0; - -From cc364b46f26d4d8fc925ab96616e2443f29a0a60 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 26 Jun 2015 08:39:19 +0100 -Subject: [PATCH 084/204] BCM270X_DT: Create a "core" clock, use it for SPI and - sdhost - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 6 +++--- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 28 ++------------------------- - 6 files changed, 9 insertions(+), 29 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 0fa2210..3b252dc 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -124,6 +124,7 @@ - i2c1 = <&i2c1>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 3fd49d0..40fded1 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -118,6 +118,7 @@ - i2c1 = <&i2c1>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 238bd65..e82fcb2 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -14,5 +14,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 8caa234..4a975dfd 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -110,7 +110,7 @@ - compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; -- clocks = <&clk_spi>; -+ clocks = <&clk_core>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; -@@ -203,11 +203,11 @@ - clock-frequency = <250000000>; - }; - -- clk_spi: clock@2 { -+ clk_core: clock@2 { - compatible = "fixed-clock"; - reg = <2>; - #clock-cells = <0>; -- clock-output-names = "spi"; -+ clock-output-names = "core"; - clock-frequency = <250000000>; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 8aaaf1f..24fa849 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -124,6 +124,7 @@ - i2c1 = <&i2c1>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index b408ab4..897204a 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -16,7 +16,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&sdhost_pins>; - interrupts = <2 24>; -- clocks = <&clk_sdhost>; -+ clocks = <&clk_core>; - dmas = <&dma 13>, - <&dma 13>; - dma-names = "tx", "rx"; -@@ -29,22 +29,6 @@ - }; - - fragment@1 { -- target = <&clocks>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_sdhost: sdhost { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "sdhost"; -- clock-frequency = <250000000>; -- }; -- }; -- }; -- -- fragment@2 { - target = <&gpio>; - __overlay__ { - sdhost_pins: sdhost_pins { -@@ -54,7 +38,7 @@ - }; - }; - -- fragment@3 { -+ fragment@2 { - target = <&mmc>; - __overlay__ { - /* Find a way to disable the other driver */ -@@ -63,18 +47,10 @@ - }; - }; - -- fragment@4 { -- target-path = "/__overrides__"; -- __overlay__ { -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -- }; -- }; -- - __overrides__ { - overclock_50 = <&sdhost>,"brcm,overclock-50:0"; - force_pio = <&sdhost>,"brcm,force-pio?"; - pio_limit = <&sdhost>,"brcm,pio-limit:0"; - debug = <&sdhost>,"brcm,debug?"; -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - }; - }; - -From 18fdf653ca9b05f1e30a4e1cb6bb9320b6642ea9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 24 Jun 2015 09:24:31 +0100 -Subject: [PATCH 085/204] BCM270X_DT: Add MCP7941X to i2c-rtc overlay - ---- - arch/arm/boot/dts/overlays/README | 3 +++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 6 ++++++ - 2 files changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index aa09b6c..425eb19 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -253,6 +253,8 @@ Params: ds1307 Select the DS1307 device - - ds3231 Select the DS3231 device - -+ mcp7941x Select the MCP7941x device -+ - pcf2127 Select the PCF2127 device - - pcf8523 Select the PCF8523 device -@@ -396,6 +398,7 @@ Params: speed Display SPI bus speed - - xohms Touchpanel sensitivity (X-plate resistance) - -+ - Name: rpi-ft5406 - Info: Official Raspberry Pi display touchscreen - Load: dtoverlay=rpi-ft5406 -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index 6bccfdc..7052c71 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -17,6 +17,11 @@ - reg = <0x68>; - status = "disable"; - }; -+ mcp7941x: mcp7941x@6f { -+ compatible = "microchip,mcp7941x"; -+ reg = <0x6f>; -+ status = "disable"; -+ }; - ds3231: ds3231@68 { - compatible = "maxim,ds3231"; - reg = <0x68>; -@@ -42,6 +47,7 @@ - __overrides__ { - ds1307 = <&ds1307>,"status"; - ds3231 = <&ds3231>,"status"; -+ mcp7941x = <&mcp7941x>,"status"; - pcf2127 = <&pcf2127>,"status"; - pcf8523 = <&pcf8523>,"status"; - pcf8563 = <&pcf8563>,"status"; - -From 4b29016b330d96063fcb94f935b2c0a18a3a3fde Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 24 Jun 2015 11:23:06 +0100 -Subject: [PATCH 086/204] dts/overlays: document DHT11 overlay - ---- - arch/arm/boot/dts/overlays/README | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 425eb19..9406cf3 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -173,6 +173,14 @@ Load: dtoverlay=bmp085_i2c-sensor - Params: - - -+Name: dht11 -+Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors -+ Also sometimes found with the part number(s) AM230x. -+Load: dtoverlay=dht11,= -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) -+ -+ - [ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] - - - -From a64baab36c2fea4043c2e862efd5f2ce979d3671 Mon Sep 17 00:00:00 2001 +From 0bdb8e1577ce61590107451fa0cbb9b629a487b6 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 087/204] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 084/113] gpio-poweroff: Allow it to work on Raspberry Pi The Raspberry Pi firmware manages the power-down and reboot process. To do this it installs a pm_power_off handler, causing @@ -136118,97 +134331,17 @@ Note that running in an active-low configuration (DT parameter allow a reboot without switching off, so an external inversion of the trigger signal may be preferable. --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 13 +++++++++ - .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 ++++++++++++++++++++++ - drivers/power/reset/gpio-poweroff.c | 4 ++- - 4 files changed, 51 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts + drivers/power/reset/gpio-poweroff.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 19eef3c..a1397c7 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -16,6 +16,7 @@ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9406cf3..0ed7094 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -192,6 +192,19 @@ Params: int_pin GPIO used for INT (default 25) - speed SPI bus speed (default 12000000) - - -+Name: gpio-poweroff -+Info: Drives a GPIO high or low on reboot -+Load: gpio-poweroff,= -+Params: gpiopin GPIO for signalling (default 26) -+ -+ active_low Set if the power control device requires a -+ high->low transition to trigger a power-down. -+ Note that this will require the support of a -+ custom dt-blob.bin to prevent a power-down -+ during the boot process, and that a reboot -+ will also cause the pin to go low. -+ -+ - Name: hifiberry-amp - Info: Configures the HifiBerry Amp and Amp+ audio cards - Load: dtoverlay=hifiberry-amp -diff --git a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -new file mode 100644 -index 0000000..ff8cb36 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for gpio-poweroff module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ power_ctrl: power_ctrl { -+ compatible = "gpio-poweroff"; -+ gpios = <&gpio 26 0>; -+ force; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ power_ctrl_pins: power_ctrl_pins { -+ brcm,pins = <26>; -+ brcm,function = <1>; // out -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&power_ctrl>,"gpios:4", -+ <&power_ctrl_pins>,"brcm,pins:0"; -+ active_low = <&power_ctrl>,"gpios:8"; -+ }; -+}; diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c -index e5332f1..6e3fec2 100644 +index be3d81f..a030ae9 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c -@@ -48,9 +48,11 @@ static void gpio_poweroff_do_poweroff(void) - static int gpio_poweroff_probe(struct platform_device *pdev) +@@ -49,9 +49,11 @@ static int gpio_poweroff_probe(struct platform_device *pdev) { bool input = false; + enum gpiod_flags flags; + bool force = false; /* If a pm_power_off function has already been added, leave it alone */ @@ -136219,994 +134352,20 @@ index e5332f1..6e3fec2 100644 "%s: pm_power_off function already registered", __func__); -From 751f8f85e9ecb31382f4b15fbf04311da32bd403 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 17 Jun 2015 17:10:40 +0100 -Subject: [PATCH 088/204] BCM270x_DT: Default Compute Module i2c, i2s and spi - support - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 67 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 67 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index e82fcb2..af252bd 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -10,10 +10,77 @@ - status = "okay"; - }; - -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ - / { - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; - -From 310ac993d7e597234de083f9e28a950beea57e05 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 22 Jun 2015 14:21:55 +0100 -Subject: [PATCH 089/204] BCM270X_DT: Sort nodes by bus address, and - consolidate aliases - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 19 ---------- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 19 ---------- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 21 ----------- - arch/arm/boot/dts/bcm2708_common.dtsi | 63 +++++++++++++++++++++++--------- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 19 ---------- - 5 files changed, 46 insertions(+), 95 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 3b252dc..9af99b8 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -5,25 +5,6 @@ - / { - compatible = "brcm,bcm2708"; - model = "Raspberry Pi Model B+"; -- -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; - }; - - &gpio { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 40fded1..092d15d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -5,25 +5,6 @@ - / { - compatible = "brcm,bcm2708"; - model = "Raspberry Pi Model B"; -- -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; - }; - - &gpio { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 3da7d3b..34d4bc6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -1,26 +1,5 @@ - /include/ "bcm2708.dtsi" - --/ { -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; --}; -- - &leds { - act_led: act { - label = "led0"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4a975dfd..b71b208 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -3,6 +3,31 @@ - / { - interrupt-parent = <&intc>; - -+ aliases { -+ audio = &audio; -+ sound = &sound; -+ soc = &soc; -+ dma = &dma; -+ intc = &intc; -+ watchdog = &watchdog; -+ random = &random; -+ mailbox = &mailbox; -+ gpio = &gpio; -+ uart0 = &uart0; -+ i2s = &i2s; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ uart1 = &uart1; -+ mmc = &mmc; -+ i2c1 = &i2c1; -+ usb = &usb; -+ leds = &leds; -+ fb = &fb; -+ vchiq = &vchiq; -+ thermal = &thermal; -+ clocks = &clocks; -+ }; -+ - /* Onboard audio */ - audio: audio { - compatible = "brcm,bcm2835-audio"; -@@ -10,6 +35,10 @@ - status = "disabled"; - }; - -+ /* External sound card */ -+ sound: sound { -+ }; -+ - soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; -@@ -43,6 +72,12 @@ - #interrupt-cells = <2>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - watchdog: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm-wdt"; - reg = <0x7e100000 0x28>; -@@ -55,12 +90,6 @@ - status = "disabled"; - }; - -- mailbox: mailbox@7e00b800 { -- compatible = "brcm,bcm2708-vcio"; -- reg = <0x7e00b880 0x40>; -- interrupts = <0 1>; -- }; -- - gpio: gpio { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; -@@ -73,17 +102,6 @@ - #interrupt-cells = <2>; - }; - -- mmc: mmc@7e300000 { -- compatible = "brcm,bcm2835-mmc"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- - uart0: uart@7e201000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; -@@ -144,6 +162,17 @@ - status = "disabled"; - }; - -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ - i2c1: i2c@7e804000 { - compatible = "brcm,bcm2708-i2c"; - reg = <0x7e804000 0x1000>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 24fa849..ccb9c31 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -5,25 +5,6 @@ - / { - compatible = "brcm,bcm2709"; - model = "Raspberry Pi 2 Model B"; -- -- aliases { -- soc = &soc; -- spi0 = &spi0; -- i2c0 = &i2c0; -- i2c1 = &i2c1; -- i2s = &i2s; -- gpio = &gpio; -- intc = &intc; -- leds = &leds; -- audio = &audio; -- sound = &sound; -- uart0 = &uart0; -- uart1 = &uart1; -- clocks = &clocks; -- }; -- -- sound: sound { -- }; - }; - - &gpio { - -From e2eb20fe73389475f652fa9ad78db6b9dc5fd780 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 22 Jun 2015 14:23:03 +0100 -Subject: [PATCH 090/204] i2c-bcm2708/BCM270X_DT: Add support for I2C2 - -The third I2C bus (I2C2) is normally reserved for HDMI use. Careless -use of this bus can break an attached display - use with caution. - -It is recommended to disable accesses by VideoCore by setting -hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt. - -The interface is disabled by default - enable using the -i2c2_iknowwhatimdoing DT parameter. ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 6 ++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 6 ++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 6 ++++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 14 ++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 6 ++++++ - drivers/i2c/busses/i2c-bcm2708.c | 5 ++++- - 6 files changed, 42 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 9af99b8..e3ae8e6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -75,6 +75,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -103,8 +107,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 092d15d..18ca7a2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -75,6 +75,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -97,8 +101,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index af252bd..bddc369 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -65,6 +65,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -79,8 +83,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index b71b208..8181a4e 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -20,6 +20,7 @@ - uart1 = &uart1; - mmc = &mmc; - i2c1 = &i2c1; -+ i2c2 = &i2c2; - usb = &usb; - leds = &leds; - fb = &fb; -@@ -183,6 +184,19 @@ - status = "disabled"; - }; - -+ i2c2: i2c@7e805000 { -+ // Beware - this is shared with the HDMI module. -+ // Careless use may break (really) your display. -+ // Caveat emptor. -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e805000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ - usb: usb@7e980000 { - compatible = "brcm,bcm2708-usb"; - reg = <0x7e980000 0x10000>, -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index ccb9c31..76d44a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -75,6 +75,10 @@ - clock-frequency = <100000>; - }; - -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ - &i2s { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -@@ -103,8 +107,10 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 8773203..7a24fbe 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -407,8 +407,11 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - case 1: - adap->class = I2C_CLASS_DDC; - break; -+ case 2: -+ adap->class = I2C_CLASS_DDC; -+ break; - default: -- dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); -+ dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n"); - err = -ENXIO; - goto out_free_bi; - } - -From 9845042a17cd1bfc818801e7a5793b00346bb242 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 29 Jun 2015 12:14:02 +0100 -Subject: [PATCH 091/204] BCM270X_DT: Correct the lirc-rpi overlay - documentation - -The polarity of the "sense" parameter was inverted with respect to reality. - -See: https://github.com/raspberrypi/linux/issues/1038 ---- - arch/arm/boot/dts/overlays/README | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0ed7094..ec762d2 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -313,8 +313,8 @@ Params: gpio_out_pin GPIO for output (default "17") - (default "down") - - sense Override the IR receive auto-detection logic: -- "1" = force active high -- "0" = force active low -+ "0" = force active-high -+ "1" = force active-low - "-1" = use auto-detection - (default "-1") - - -From e75018d8c8385653326af3519474b108f0f74945 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 25 Jun 2015 08:47:09 +0100 -Subject: [PATCH 092/204] bcm2835-sdhost: Further improve overclock back-off - ---- - drivers/mmc/host/bcm2835-sdhost.c | 144 +++++++++++++++++++++----------------- - 1 file changed, 78 insertions(+), 66 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 6277e43..a03db06 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -161,8 +161,6 @@ struct bcm2835_host { - - unsigned int use_busy:1; /* Wait for busy interrupt */ - -- unsigned int reduce_overclock:1; /* ...at the next opportunity */ -- - unsigned int debug:1; /* Enable debug output */ - - u32 thread_isr; -@@ -466,36 +464,25 @@ static void bcm2835_sdhost_dma_complete(void *param) - spin_unlock_irqrestore(&host->lock, flags); - } - --static bool data_transfer_wait(struct bcm2835_host *host, const char *caller) -+static bool data_transfer_wait(struct bcm2835_host *host) - { - unsigned long timeout = 1000000; -- u32 hsts; - while (timeout) - { -- hsts = bcm2835_sdhost_read(host, SDHSTS); -- if (hsts & (SDHSTS_TRANSFER_ERROR_MASK | -- SDHSTS_DATA_FLAG)) { -- bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -- SDHSTS); -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & SDHSTS_DATA_FLAG) { -+ bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); - break; - } - timeout--; - } -- -- if (hsts & (SDHSTS_CRC16_ERROR | -- SDHSTS_CRC7_ERROR | -- SDHSTS_FIFO_ERROR)) { -- pr_err("%s: data error in %s - HSTS %x\n", -- mmc_hostname(host->mmc), caller, hsts); -- host->data->error = -EILSEQ; -- return false; -- } else if ((timeout == 0) || -- (hsts & (SDHSTS_CMD_TIME_OUT | -- SDHSTS_REW_TIME_OUT))) { -- pr_err("%s: timeout in %s - HSTS %x\n", -- mmc_hostname(host->mmc), caller, hsts); -- host->data->error = -ETIMEDOUT; -- return false; -+ if (timeout == 0) { -+ pr_err("%s: Data %s timeout\n", -+ mmc_hostname(host->mmc), -+ (host->data->flags & MMC_DATA_READ) ? "read" : "write"); -+ bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; -+ return false; - } - return true; - } -@@ -523,7 +510,7 @@ static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - buf = (u32 *)host->sg_miter.addr; - - while (len) { -- if (!data_transfer_wait(host, "read_block_pio")) -+ if (!data_transfer_wait(host)) - break; - - *(buf++) = bcm2835_sdhost_read(host, SDDATA); -@@ -562,7 +549,7 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - buf = host->sg_miter.addr; - - while (len) { -- if (!data_transfer_wait(host, "write_block_pio")) -+ if (!data_transfer_wait(host)) - break; - - bcm2835_sdhost_write(host, *(buf++), SDDATA); -@@ -581,13 +568,33 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - - static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - { -+ u32 sdhsts; -+ bool is_read; - BUG_ON(!host->data); - -- if (host->data->flags & MMC_DATA_READ) { -+ is_read = (host->data->flags & MMC_DATA_READ) != 0; -+ if (is_read) - bcm2835_sdhost_read_block_pio(host); -- } else { -+ else - bcm2835_sdhost_write_block_pio(host); - -+ sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & (SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) { -+ pr_err("%s: %s transfer error - HSTS %x\n", -+ mmc_hostname(host->mmc), -+ is_read ? "read" : "write", -+ sdhsts); -+ host->data->error = -EILSEQ; -+ } else if ((sdhsts & (SDHSTS_CMD_TIME_OUT | -+ SDHSTS_REW_TIME_OUT))) { -+ pr_err("%s: %s timeout error - HSTS %x\n", -+ mmc_hostname(host->mmc), -+ is_read ? "read" : "write", -+ sdhsts); -+ host->data->error = -ETIMEDOUT; -+ } else if (!is_read && !host->data->error) { - /* Start a timer in case a transfer error occurs because - there is no error interrupt */ - mod_timer(&host->pio_timer, jiffies + host->pio_timeout); -@@ -701,8 +708,9 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - - void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) - { -- u32 sdcmd; -+ u32 sdcmd, sdhsts; - unsigned long timeout; -+ int delay; - - WARN_ON(host->cmd); - -@@ -719,8 +727,8 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - mmc_hostname(host->mmc), - cmd->opcode, cmd->arg, cmd->flags); - -- /* Wait max 10 ms */ -- timeout = 1000; -+ /* Wait max 100 ms */ -+ timeout = 10000; - - while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { - if (timeout == 0) { -@@ -735,8 +743,9 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - udelay(10); - } - -- if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { -- host->max_delay = (1000-timeout)/100; -+ delay = (10000 - timeout)/100; -+ if (delay > host->max_delay) { -+ host->max_delay = delay; - pr_warning("%s: controller hung for %d ms\n", - mmc_hostname(host->mmc), - host->max_delay); -@@ -751,6 +760,11 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - - host->cmd = cmd; - -+ /* Clear any error flags */ -+ sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & SDHSTS_ERROR_MASK) -+ bcm2835_sdhost_write(host, sdhsts, SDHSTS); -+ - bcm2835_sdhost_prepare_data(host, cmd); - - bcm2835_sdhost_write(host, cmd->arg, SDARG); -@@ -876,7 +890,7 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - { - u32 sdcmd; -- int timeout = 1000; -+ unsigned long timeout; - #ifdef DEBUG - struct timeval before, after; - int timediff = 0; -@@ -889,6 +903,8 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - #ifdef DEBUG - do_gettimeofday(&before); - #endif -+ /* Wait max 100 ms */ -+ timeout = 10000; - for (sdcmd = bcm2835_sdhost_read(host, SDCMD); - (sdcmd & SDCMD_NEW_FLAG) && timeout; - timeout--) { -@@ -1049,9 +1065,9 @@ static void bcm2835_sdhost_pio_timeout(unsigned long data) - spin_lock_irqsave(&host->lock, flags); - - if (host->data) { -- u32 hsts = bcm2835_sdhost_read(host, SDHSTS); -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); - -- if (hsts & SDHSTS_REW_TIME_OUT) { -+ if (sdhsts & SDHSTS_REW_TIME_OUT) { - pr_err("%s: transfer timeout\n", - mmc_hostname(host->mmc)); - if (host->debug) -@@ -1380,19 +1396,10 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); - -- if ((clock == 0) && host->reduce_overclock) { -- /* This is a reset following data corruption - reduce any -- overclock */ -- host->reduce_overclock = 0; -- if (host->overclock_50 > 50) { -- pr_warn("%s: reducing overclock due to errors\n", -- mmc_hostname(host->mmc)); -- host->overclock_50--; -- } -- } -- -- if (host->overclock_50 && (clock == 50*MHZ)) -+ if ((host->overclock_50 > 50) && -+ (clock == 50*MHZ)) { - clock = host->overclock_50 * MHZ + (MHZ - 1); -+ } - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1450,11 +1457,12 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->overclock = clock; - } - } -- else if ((clock == 50 * MHZ) && host->overclock) -+ else if (host->overclock) - { -- pr_warn("%s: cancelling overclock\n", -- mmc_hostname(host->mmc)); - host->overclock = 0; -+ if (clock == 50 * MHZ) -+ pr_warn("%s: cancelling overclock\n", -+ mmc_hostname(host->mmc)); - } - - host->cdiv = div; -@@ -1492,6 +1500,14 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - cmd->opcode, cmd->arg, cmd->flags); - } - -+ /* Reset the error statuses in case this is a retry */ -+ if (mrq->cmd) -+ mrq->cmd->error = 0; -+ if (mrq->data) -+ mrq->data->error = 0; -+ if (mrq->stop) -+ mrq->stop->error = 0; -+ - if (mrq->data && !is_power_of_2(mrq->data->blksz)) { - pr_err("%s: unsupported block size (%d bytes)\n", - mmc_hostname(mmc), mrq->data->blksz); -@@ -1613,21 +1629,16 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - /* Drop the overclock after any data corruption, or after any - error overclocked */ -- if (mrq->data && (mrq->data->error == -EILSEQ)) -- host->reduce_overclock = 1; -- else if (host->overclock) { -- /* Convert timeout errors while overclocked to data errors, -- because the system recovers better. */ -- if (mrq->cmd && mrq->cmd->error) { -- host->reduce_overclock = 1; -- if (mrq->cmd->error == -ETIMEDOUT) -- mrq->cmd->error = -EILSEQ; -- } -- -- if (mrq->data && mrq->data->error) { -- host->reduce_overclock = 1; -- if (mrq->data->error == -ETIMEDOUT) -- mrq->data->error = -EILSEQ; -+ if (host->overclock) { -+ if ((mrq->cmd && mrq->cmd->error) || -+ (mrq->data && mrq->data->error) || -+ (mrq->stop && mrq->stop->error)) { -+ host->overclock_50--; -+ pr_warn("%s: reducing overclock due to errors\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_set_clock(host,50*MHZ); -+ mrq->cmd->error = -EILSEQ; -+ mrq->cmd->retries = 1; - } - } - -@@ -1769,6 +1780,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host = mmc_priv(mmc); - host->mmc = mmc; - host->pio_timeout = msecs_to_jiffies(500); -+ host->max_delay = 1; /* Warn if over 1ms */ - spin_lock_init(&host->lock); - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - -From 13cbc57aa3f9dd10bdc8dad7915626d1697c9903 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 10:28:59 +0100 -Subject: [PATCH 093/204] i2c-bcm2708: Increase timeouts to allow larger - transfers - -Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting -for completion. The default timeout is 1 second. - -See: https://github.com/raspberrypi/linux/issues/260 ---- - drivers/i2c/busses/i2c-bcm2708.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 7a24fbe..8b8762d 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -67,10 +67,9 @@ - #define BSC_S_DONE 0x00000002 - #define BSC_S_TA 0x00000001 - --#define I2C_TIMEOUT_MS 150 --#define I2C_WAIT_LOOP_COUNT 40 -+#define I2C_WAIT_LOOP_COUNT 200 - --#define DRV_NAME "bcm2708_i2c" -+#define DRV_NAME "bcm2708_i2c" - - static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; - module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -@@ -305,7 +304,7 @@ static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, - goto error_timeout; - } - -- ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); -+ ret = wait_for_completion_timeout(&bi->done, adap->timeout); - if (ret == 0) { - dev_err(&adap->dev, "transfer timed out\n"); - goto error_timeout; - -From f7d430536dec32c07a6ba6eb7ed6167ff4974855 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 10:33:52 +0100 -Subject: [PATCH 094/204] spi-bcm2708: Increase timeout from 150ms to 1s - -See: https://github.com/raspberrypi/linux/issues/260 ---- - drivers/spi/spi-bcm2708.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 041b5e2..5c0214e 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -70,9 +70,9 @@ - #define SPI_CS_CS_10 0x00000002 - #define SPI_CS_CS_01 0x00000001 - --#define SPI_TIMEOUT_MS 150 -+#define SPI_TIMEOUT_MS 1000 - --#define DRV_NAME "bcm2708_spi" -+#define DRV_NAME "bcm2708_spi" - - struct bcm2708_spi { - spinlock_t lock; - -From 9f8135d6ddcbf9ab9dd9678249c3b8c5d17a9229 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 15 Jun 2015 09:59:38 +0100 -Subject: [PATCH 095/204] bcm2708-spi: Don't use static pin configuration with - DT - -Also remove superfluous error checking - the SPI framework ensures the -validity of the chip_select value. ---- - drivers/spi/spi-bcm2708.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 5c0214e..781c747 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -386,14 +386,6 @@ static int bcm2708_spi_setup(struct spi_device *spi) - if (bs->stopping) - return -ESHUTDOWN; - -- if (!(spi->mode & SPI_NO_CS) && -- (spi->chip_select > spi->master->num_chipselect)) { -- dev_dbg(&spi->dev, -- "setup: invalid chipselect %u (%u defined)\n", -- spi->chip_select, spi->master->num_chipselect); -- return -EINVAL; -- } -- - state = spi->controller_state; - if (!state) { - state = kzalloc(sizeof(*state), GFP_KERNEL); -@@ -496,7 +488,8 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - return PTR_ERR(clk); - } - -- bcm2708_init_pinmode(); -+ if (!pdev->dev.of_node) -+ bcm2708_init_pinmode(); - - master = spi_alloc_master(&pdev->dev, sizeof(*bs)); - if (!master) { - -From 8c4cdb44d24dba5443a6bc18b7729ba76967acaa Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 15 Jun 2015 10:10:59 +0100 -Subject: [PATCH 096/204] bcm2708-i2s: Don't use static pin configuration with - DT - ---- - sound/soc/bcm/bcm2708-i2s.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c -index a515992..5e93cd6 100644 ---- a/sound/soc/bcm/bcm2708-i2s.c -+++ b/sound/soc/bcm/bcm2708-i2s.c -@@ -409,8 +409,8 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, - if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) - return 0; - -- -- bcm2708_i2s_setup_gpio(); -+ if (!dev->dev->of_node) -+ bcm2708_i2s_setup_gpio(); - - /* - * Adjust the data length according to the format. - -From 21f6968a52663113eab7b89f7cb192e92d8ea951 Mon Sep 17 00:00:00 2001 +From bd7c2a5be55489e6cee8f311ed2959ba0e9ff67d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 30 Jun 2015 14:12:42 +0100 -Subject: [PATCH 097/204] serial: 8250: Don't crash when nr_uarts is 0 +Subject: [PATCH 085/113] serial: 8250: Don't crash when nr_uarts is 0 --- drivers/tty/serial/8250/8250_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c -index b4fd8de..f459feb 100644 +index 271d121..d8e44c9 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c -@@ -3270,6 +3270,8 @@ static void __init serial8250_isa_init_ports(void) +@@ -509,6 +509,8 @@ static void __init serial8250_isa_init_ports(void) if (nr_uarts > UART_NR) nr_uarts = UART_NR; @@ -137216,182 +134375,10 @@ index b4fd8de..f459feb 100644 for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; -From afddc0087e5b1db8311454fa66909bc400151982 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 26 Jun 2015 08:50:11 +0100 -Subject: [PATCH 098/204] BCM270X_DT: Add overlay to enable uart1 - -N.B. The UART1 clock is derived from the core clock. The firmware -will update clock-frequency if core_freq is set, but be aware -that unless force_turbo=1 while overclocking then the baud rate -will vary with ARM activity. ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++++ - arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 ++++++++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm/configs/bcmrpi_defconfig | 2 +- - 9 files changed, 53 insertions(+), 2 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index e3ae8e6..3ad2e0d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -103,6 +103,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 18ca7a2..65628e1 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -97,6 +97,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index bddc369..96d8b97 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -79,6 +79,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 76d44a2..f25f0a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -103,6 +103,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index a1397c7..e91548c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -42,6 +42,7 @@ dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index ec762d2..d81d41a 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -489,6 +489,14 @@ Params: speed Display SPI bus speed - dtoverlay=tinylcd35,touch,touchgpio=3 - - -+Name: uart1 -+Info: Enable uart1 in place of uart0 -+Load: dtoverlay=uart1,= -+Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) -+ -+ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) -+ -+ - Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. -diff --git a/arch/arm/boot/dts/overlays/uart1-overlay.dts b/arch/arm/boot/dts/overlays/uart1-overlay.dts -new file mode 100644 -index 0000000..fa73e1f ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/uart1-overlay.dts -@@ -0,0 +1,38 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&uart1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ uart1_pins: uart1_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <2>; /* alt5 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/chosen"; -+ __overlay__ { -+ bootargs = "8250.nr_uarts=1"; -+ }; -+ }; -+ -+ __overrides__ { -+ txd1_pin = <&uart1_pins>,"brcm,pins:0"; -+ rxd1_pin = <&uart1_pins>,"brcm,pins:4"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 46d56d7..8a240fd 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -562,7 +562,7 @@ CONFIG_SERIAL_8250=y - CONFIG_SERIAL_8250_CONSOLE=y - # CONFIG_SERIAL_8250_DMA is not set - CONFIG_SERIAL_8250_NR_UARTS=1 --CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e757db6..363c894 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -555,7 +555,7 @@ CONFIG_SERIAL_8250=y - CONFIG_SERIAL_8250_CONSOLE=y - # CONFIG_SERIAL_8250_DMA is not set - CONFIG_SERIAL_8250_NR_UARTS=1 --CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=y - -From 9b7dfacf1ff658c5aa03075776f71c8d6e16564e Mon Sep 17 00:00:00 2001 +From 83bf3d318d5af31c35c593529a9174caf0624733 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 099/204] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 086/113] spi-bcm2835: Support pin groups other than 7-11 The spi-bcm2835 driver automatically uses GPIO chip-selects due to some unreliability of the native ones. In doing so it chooses the @@ -137408,10 +134395,10 @@ Signed-off-by: Phil Elwell 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index a506773..cf3190f 100644 +index 3e8eeb2..3835332 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c -@@ -376,6 +376,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) +@@ -688,6 +688,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) { int err; struct gpio_chip *chip; @@ -137420,7 +134407,7 @@ index a506773..cf3190f 100644 /* * sanity checking the native-chipselects */ -@@ -392,15 +394,42 @@ static int bcm2835_spi_setup(struct spi_device *spi) +@@ -704,15 +706,42 @@ static int bcm2835_spi_setup(struct spi_device *spi) "setup: only two native chip-selects are supported\n"); return -EINVAL; } @@ -137472,2768 +134459,10 @@ index a506773..cf3190f 100644 /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -From c26edc1513a5086a1a4e0c16746d52423b0259c8 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 17:37:38 +0100 -Subject: [PATCH 100/204] BCM270X_DT: Change pio_limit of sdhost driver to 1 - ---- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index 897204a..2da14a4 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -22,7 +22,7 @@ - dma-names = "tx", "rx"; - brcm,delay-after-stop = <0>; - brcm,overclock-50 = <0>; -- brcm,pio-limit = <2>; -+ brcm,pio-limit = <1>; - status = "okay"; - }; - }; - -From 83dda549d089cd0117282ec6edebd697fa59f173 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 1 Jul 2015 12:51:52 +0100 -Subject: [PATCH 101/204] bcm2835-sdhost: Clear HBLC for PIO mode - -Also update pio_limit default in overlay README. ---- - arch/arm/boot/dts/overlays/README | 2 +- - drivers/mmc/host/bcm2835-sdhost.c | 3 +-- - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d81d41a..980d358 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -441,7 +441,7 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - force_pio Disable DMA support (default off) - - pio_limit Number of blocks above which to use DMA -- (default 2) -+ (default 1) - - debug Enable debug output (default off) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index a03db06..d65870a 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -699,8 +699,7 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - bcm2835_sdhost_set_transfer_irqs(host); - - bcm2835_sdhost_write(host, data->blksz, SDHBCT); -- if (host->use_dma) -- bcm2835_sdhost_write(host, data->blocks, SDHBLC); -+ bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); - - BUG_ON(!host->data); - } - -From ecdc3c6d8615d2f5df08e2514cb0b6b12be840e1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 3 Jul 2015 12:21:01 +0100 -Subject: [PATCH 102/204] BCM270X_DT: I2S needs function Alt2 - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 +- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 +- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 2 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 3ad2e0d..562eb08 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 65628e1..e2b1491 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <28 29 30 31>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 96d8b97..5e3db01 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -28,7 +28,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index f25f0a2..62d1c62 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <6>; /* alt2 */ - }; - }; - - -From 906a4b80abdc53ea1369eb0ecf310a4b906d2f1c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:16:15 +0200 -Subject: [PATCH 103/204] configs: Incorporate v4.1 dependency changes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 78e9b7de78bb53e8bc7f4c4a60ebacb250c0c190 added a -dependency on TI_ST instead of selecting it, disabling: -CONFIG_BT_WILINK=m -CONFIG_RADIO_WL128X=m - -Commit 652ccae5cc4e1305fb0a4619947f9ee89d8c7f5a added a -depency on ARM_CRYPTO, disabling: -CONFIG_CRYPTO_SHA*_ARM*=m -CONFIG_CRYPTO_AES_ARM*=m - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 10 ++++++---- - arch/arm/configs/bcm2835_defconfig | 8 +++++--- - arch/arm/configs/bcmrpi_defconfig | 8 +++++--- - 3 files changed, 16 insertions(+), 10 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 8a240fd..ccfc14c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -401,6 +401,7 @@ CONFIG_BLK_DEV_RAM=y - CONFIG_CDROM_PKTCDVD=m - CONFIG_ATA_OVER_ETH=m - CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -@@ -1100,6 +1101,7 @@ CONFIG_OCFS2_FS=m - CONFIG_BTRFS_FS=m - CONFIG_BTRFS_FS_POSIX_ACL=y - CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y - CONFIG_QFMT_V1=m - CONFIG_QFMT_V2=m -@@ -1129,7 +1131,6 @@ CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y - CONFIG_SQUASHFS_XZ=y --CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y -@@ -1205,14 +1206,15 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA1_ARM_NEON=m --CONFIG_CRYPTO_SHA512_ARM_NEON=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m --CONFIG_CRYPTO_AES_ARM_BS=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set - # CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_SHA512_ARM_NEON=m -+CONFIG_CRYPTO_AES_ARM_BS=m - CONFIG_CRC_ITU_T=y - CONFIG_LIBCRC32C=y -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 2e8a95a..47f2a6a 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -402,6 +402,7 @@ CONFIG_BLK_DEV_RAM=y - CONFIG_CDROM_PKTCDVD=m - CONFIG_ATA_OVER_ETH=m - CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -@@ -1091,6 +1092,7 @@ CONFIG_OCFS2_FS=m - CONFIG_BTRFS_FS=m - CONFIG_BTRFS_FS_POSIX_ACL=y - CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y - CONFIG_QFMT_V1=m - CONFIG_QFMT_V2=m -@@ -1120,7 +1122,6 @@ CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y - CONFIG_SQUASHFS_XZ=y --CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y -@@ -1208,15 +1209,16 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA1_ARM=m - CONFIG_CRYPTO_SHA512=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m --CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set - # CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRC_ITU_T=y - CONFIG_LIBCRC32C=y - # CONFIG_XZ_DEC_ARM is not set -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 363c894..80f84d7 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -394,6 +394,7 @@ CONFIG_BLK_DEV_RAM=y - CONFIG_CDROM_PKTCDVD=m - CONFIG_ATA_OVER_ETH=m - CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -@@ -1093,6 +1094,7 @@ CONFIG_OCFS2_FS=m - CONFIG_BTRFS_FS=m - CONFIG_BTRFS_FS_POSIX_ACL=y - CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y - CONFIG_QFMT_V1=m - CONFIG_QFMT_V2=m -@@ -1122,7 +1124,6 @@ CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y - CONFIG_SQUASHFS_XZ=y --CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y -@@ -1200,14 +1201,15 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA1_ARM=m - CONFIG_CRYPTO_SHA512=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m --CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set - # CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_AES_ARM=m - CONFIG_CRC_ITU_T=y - CONFIG_LIBCRC32C=y - -From 03edd2dd4b9c016f440383c9fae725f5c4e73eca Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 3 Jul 2015 15:47:33 +0100 -Subject: [PATCH 104/204] bcmrpi_defconfigs: Add SND_SOC_WM8804_I2C (for - HifiBerry Digi) - -4.1 has split out support for the I2C and SPI variants, so it now -necessary to explicitly enable the I2C support. ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index ccfc14c..5ecd84f 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -823,6 +823,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 80f84d7..14b91fdf 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -816,6 +816,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y - -From b1c7182dc37e87b47377b529de6e54a431fc07aa Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sat, 4 Jul 2015 19:55:23 +0100 -Subject: [PATCH 105/204] squash: BCM270X_DT: I2S only needs Alt2 on 28-31 - -See: https://github.com/raspberrypi/linux/issues/1046 ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 +- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 2 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 562eb08..3ad2e0d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 5e3db01..96d8b97 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -28,7 +28,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 62d1c62..f25f0a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -25,7 +25,7 @@ - - i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ - }; - }; - - -From b52bc261c9b3c08ac73aca166afb05090ffca7eb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 8 Jul 2015 14:48:57 +0100 -Subject: [PATCH 106/204] vchiq_arm: Two cacheing fixes - -1) Make fragment size vary with cache line size -Without this patch, non-cache-line-aligned transfers may corrupt -(or be corrupted by) adjacent data structures. - -Both ARM and VC need to be updated to enable this feature. This is -ensured by having the loader apply a new DT parameter - -cache-line-size. The existence of this parameter guarantees that the -kernel is capable, and the parameter will only be modified from the -safe default if the loader is capable. - -2) Flush/invalidate vmalloc'd memory, and invalidate after reads ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 + - .../interface/vchiq_arm/vchiq_2835_arm.c | 112 +++++++++++++-------- - 2 files changed, 77 insertions(+), 40 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 8181a4e..abf3e5d 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -218,6 +218,7 @@ - compatible = "brcm,bcm2835-vchiq"; - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; -+ cache-line-size = <32>; - }; - - thermal: thermal { -@@ -270,4 +271,8 @@ - clock-frequency = <126000000>; - }; - }; -+ -+ __overrides__ { -+ cache_line_size = <&vchiq>, "cache-line-size:0"; -+ }; - }; -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index c739083..5edba23 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - #include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) -@@ -64,8 +65,10 @@ typedef struct vchiq_2835_state_struct { - } VCHIQ_2835_ARM_STATE_T; - - static void __iomem *g_regs; --static FRAGMENTS_T *g_fragments_base; --static FRAGMENTS_T *g_free_fragments; -+static unsigned int g_cache_line_size = sizeof(CACHE_LINE_SIZE); -+static unsigned int g_fragments_size; -+static char *g_fragments_base; -+static char *g_free_fragments; - static struct semaphore g_free_fragments_sema; - static unsigned long g_virt_to_bus_offset; - -@@ -95,9 +98,13 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - - g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); - -+ (void)of_property_read_u32(dev->of_node, "cache-line-size", -+ &g_cache_line_size); -+ g_fragments_size = 2 * g_cache_line_size; -+ - /* Allocate space for the channels in coherent memory */ - slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); -- frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); -+ frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); - - slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, - &slot_phys, GFP_KERNEL); -@@ -117,15 +124,15 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = - MAX_FRAGMENTS; - -- g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); -+ g_fragments_base = (char *)slot_mem + slot_mem_size; - slot_mem_size += frag_mem_size; - - g_free_fragments = g_fragments_base; - for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { -- *(FRAGMENTS_T **)&g_fragments_base[i] = -- &g_fragments_base[i + 1]; -+ *(char **)&g_fragments_base[i*g_fragments_size] = -+ &g_fragments_base[(i + 1)*g_fragments_size]; - } -- *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; -+ *(char **)&g_fragments_base[i * g_fragments_size] = NULL; - sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); - - if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) -@@ -344,7 +351,7 @@ vchiq_doorbell_irq(int irq, void *dev_id) - ** cached area. - - ** N.B. This implementation plays slightly fast and loose with the Linux --** driver programming rules, e.g. its use of __virt_to_bus instead of -+** driver programming rules, e.g. its use of dmac_map_area instead of - ** dma_map_single, but it isn't a multi-platform driver and it benefits - ** from increased speed as a result. - */ -@@ -355,7 +362,6 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - { - PAGELIST_T *pagelist; - struct page **pages; -- struct page *page; - unsigned long *addrs; - unsigned int num_pages, offset, i; - char *addr, *base_addr, *next_addr; -@@ -386,10 +392,25 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - pages = (struct page **)(addrs + num_pages + 1); - - if (is_vmalloc_addr(buf)) { -- for (actual_pages = 0; actual_pages < num_pages; actual_pages++) { -- pages[actual_pages] = vmalloc_to_page(buf + (actual_pages * PAGE_SIZE)); -+ int dir = (type == PAGELIST_WRITE) ? -+ DMA_TO_DEVICE : DMA_FROM_DEVICE; -+ unsigned long length = pagelist->length; -+ unsigned int offset = pagelist->offset; -+ -+ for (actual_pages = 0; actual_pages < num_pages; -+ actual_pages++) { -+ struct page *pg = vmalloc_to_page(buf + (actual_pages * -+ PAGE_SIZE)); -+ size_t bytes = PAGE_SIZE - offset; -+ -+ if (bytes > length) -+ bytes = length; -+ pages[actual_pages] = pg; -+ dmac_map_area(page_address(pg) + offset, bytes, dir); -+ length -= bytes; -+ offset = 0; - } -- *need_release = 0; /* do not try and release vmalloc pages */ -+ *need_release = 0; /* do not try and release vmalloc pages */ - } else { - down_read(&task->mm->mmap_sem); - actual_pages = get_user_pages(task, task->mm, -@@ -418,7 +439,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - actual_pages = -ENOMEM; - return actual_pages; - } -- *need_release = 1; /* release user pages */ -+ *need_release = 1; /* release user pages */ - } - - pagelist->length = count; -@@ -451,10 +472,10 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - - /* Partial cache lines (fragments) require special measures */ - if ((type == PAGELIST_READ) && -- ((pagelist->offset & (CACHE_LINE_SIZE - 1)) || -+ ((pagelist->offset & (g_cache_line_size - 1)) || - ((pagelist->offset + pagelist->length) & -- (CACHE_LINE_SIZE - 1)))) { -- FRAGMENTS_T *fragments; -+ (g_cache_line_size - 1)))) { -+ char *fragments; - - if (down_interruptible(&g_free_fragments_sema) != 0) { - kfree(pagelist); -@@ -464,19 +485,15 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - WARN_ON(g_free_fragments == NULL); - - down(&g_free_fragments_mutex); -- fragments = (FRAGMENTS_T *) g_free_fragments; -+ fragments = g_free_fragments; - WARN_ON(fragments == NULL); -- g_free_fragments = *(FRAGMENTS_T **) g_free_fragments; -+ g_free_fragments = *(char **) g_free_fragments; - up(&g_free_fragments_mutex); -- pagelist->type = -- PAGELIST_READ_WITH_FRAGMENTS + (fragments - -- g_fragments_base); -+ pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + -+ (fragments - g_fragments_base) / g_fragments_size; - } - -- for (page = virt_to_page(pagelist); -- page <= virt_to_page(addrs + num_pages - 1); page++) { -- flush_dcache_page(page); -- } -+ dmac_flush_range(pagelist, addrs + num_pages); - - *ppagelist = pagelist; - -@@ -502,13 +519,14 @@ free_pagelist(PAGELIST_T *pagelist, int actual) - - /* Deal with any partial cache lines (fragments) */ - if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { -- FRAGMENTS_T *fragments = g_fragments_base + -- (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS); -+ char *fragments = g_fragments_base + -+ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * -+ g_fragments_size; - int head_bytes, tail_bytes; -- head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & -- (CACHE_LINE_SIZE - 1); -+ head_bytes = (g_cache_line_size - pagelist->offset) & -+ (g_cache_line_size - 1); - tail_bytes = (pagelist->offset + actual) & -- (CACHE_LINE_SIZE - 1); -+ (g_cache_line_size - 1); - - if ((actual >= 0) && (head_bytes != 0)) { - if (head_bytes > actual) -@@ -516,32 +534,46 @@ free_pagelist(PAGELIST_T *pagelist, int actual) - - memcpy((char *)page_address(pages[0]) + - pagelist->offset, -- fragments->headbuf, -+ fragments, - head_bytes); - } - if ((actual >= 0) && (head_bytes < actual) && - (tail_bytes != 0)) { - memcpy((char *)page_address(pages[num_pages - 1]) + - ((pagelist->offset + actual) & -- (PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)), -- fragments->tailbuf, tail_bytes); -+ (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), -+ fragments + g_cache_line_size, -+ tail_bytes); - } - - down(&g_free_fragments_mutex); -- *(FRAGMENTS_T **) fragments = g_free_fragments; -+ *(char **)fragments = g_free_fragments; - g_free_fragments = fragments; - up(&g_free_fragments_mutex); - up(&g_free_fragments_sema); - } - -- if (*need_release) { -- for (i = 0; i < num_pages; i++) { -- if (pagelist->type != PAGELIST_WRITE) -- set_page_dirty(pages[i]); -+ if (*need_release) { -+ unsigned int length = pagelist->length; -+ unsigned int offset = pagelist->offset; - -- page_cache_release(pages[i]); -+ for (i = 0; i < num_pages; i++) { -+ struct page *pg = pages[i]; -+ -+ if (pagelist->type != PAGELIST_WRITE) { -+ unsigned int bytes = PAGE_SIZE - offset; -+ -+ if (bytes > length) -+ bytes = length; -+ dmac_unmap_area(page_address(pg) + offset, -+ bytes, DMA_FROM_DEVICE); -+ length -= bytes; -+ offset = 0; -+ set_page_dirty(pg); -+ } -+ page_cache_release(pg); - } -- } -+ } - - kfree(pagelist); - } - -From fc0a0a8a198ad39fa58dd4e2b3efba0a89a9d627 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 30 Jun 2015 09:10:36 +0100 -Subject: [PATCH 107/204] BCM270X_DT: Overlay for the Fen Logic VGA666 board - -The VGA666 board requires GPIOs 2-21 (so no I2C or UART). Using the -overlay (instead of a custom dt-blob.bin) has the advantage that it will -reserve those pins and stop other devices using them (except for GPIO), -but it does delay the point at which the output becomes valid until 2-3 -seconds after the kernel has started. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 +++++++ - arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 +++++++++++++++++++++++++++ - 3 files changed, 39 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index e91548c..74ec825 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -43,6 +43,7 @@ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 980d358..5e1f530 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -497,6 +497,14 @@ Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) - rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - -+Name: vga666 -+Info: Overlay for the Fen Logic VGA666 board -+ This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds -+ after the kernel has started. -+Load: dtoverlay=vga666 -+Params: -+ -+ - Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. -diff --git a/arch/arm/boot/dts/overlays/vga666-overlay.dts b/arch/arm/boot/dts/overlays/vga666-overlay.dts -new file mode 100644 -index 0000000..7fcab96 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vga666-overlay.dts -@@ -0,0 +1,30 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ // There is no VGA driver module, but we need a platform device -+ // node (that doesn't already use pinctrl) to hang the pinctrl -+ // reference on - leds will do -+ -+ fragment@0 { -+ target = <&leds>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vga666_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ vga666_pins: vga666_pins { -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 -+ 13 14 15 16 17 18 19 20 21>; -+ brcm,function = <6>; /* alt2 */ -+ brcm,pull = <0>; /* no pull */ -+ }; -+ }; -+ }; -+}; - -From c9eb6844bc315ee5ab2c807f873ca04d45fc6303 Mon Sep 17 00:00:00 2001 -From: petit-miner -Date: Fri, 10 Jul 2015 13:59:18 +0200 -Subject: [PATCH 108/204] Added support for 2 mcp2515 CAN Bus IC - -See: https://github.com/raspberrypi/linux/issues/1018 - https://github.com/raspberrypi/linux/pull/1049 - https://github.com/raspberrypi/linux/pull/1052 ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 12 +++- - .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 69 ++++++++++++++++++++++ - 3 files changed, 81 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 74ec825..4ff9836 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,7 @@ dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 5e1f530..88ed678 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -328,7 +328,7 @@ Params: gpio_out_pin GPIO for output (default "17") - - - Name: mcp2515-can0 --Info: Configures the MCP2515 CAN controller -+Info: Configures the MCP2515 CAN controller on spi0.0 - Load: dtoverlay=mcp2515-can0,= - Params: oscillator Clock frequency for the CAN controller (Hz) - -@@ -337,6 +337,16 @@ Params: oscillator Clock frequency for the CAN controller (Hz) - interrupt GPIO for interrupt signal - - -+Name: mcp2515-can1 -+Info: Configures the MCP2515 CAN controller on spi0.1 -+Load: dtoverlay=mcp2515-can1,= -+Params: oscillator Clock frequency for the CAN controller (Hz) -+ -+ spimaxfrequency Maximum SPI frequence (Hz) -+ -+ interrupt GPIO for interrupt signal -+ -+ - Name: mmc - Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -new file mode 100644 -index 0000000..6bef9ae ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -0,0 +1,69 @@ -+/* -+ * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* disable spi-dev for spi0.1 */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ can1_pins: can1_pins { -+ brcm,pins = <25>; -+ brcm,function = <0>; /* input */ -+ }; -+ }; -+ }; -+ -+ /* the clock/oscillator of the can-controller */ -+ fragment@2 { -+ target-path = "/clocks"; -+ __overlay__ { -+ /* external oscillator of mcp2515 on spi0.1 */ -+ can1_osc: can1_osc { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <16000000>; -+ }; -+ }; -+ }; -+ -+ /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ can1: mcp2515@1 { -+ reg = <1>; -+ compatible = "microchip,mcp2515"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&can1_pins>; -+ spi-max-frequency = <10000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 0x2>; -+ clocks = <&can1_osc>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ oscillator = <&can1_osc>,"clock-frequency:0"; -+ spimaxfrequency = <&can1>,"spi-max-frequency:0"; -+ interrupt = <&can1_pins>,"brcm,pins:0",<&can1>,"interrupts:0"; -+ }; -+}; - -From 632d8b6abe925d8300a9c824856ea7c286d95229 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Tue, 5 May 2015 13:27:45 -0700 -Subject: [PATCH 109/204] mailbox: Enable BCM2835 mailbox support - -This mailbox driver provides a single mailbox channel to write 32-bit -values to the VPU and get a 32-bit response. The Raspberry Pi -firmware uses this mailbox channel to implement firmware calls, while -Roku 2 (despite being derived from the same firmware tree) doesn't. - -The driver was originally submitted by Lubomir, based on the -out-of-tree 2708 mailbox driver. Eric Anholt fixed it up for -upstreaming, with the major functional change being that it now has no -notion of multiple channels (since that is a firmware-dependent -concept) and instead the raspberrypi-firmware driver will do that -bit-twiddling in its own messages. -[Jassi: made the 'mbox_chan_ops' struct as const and removed a redundant -variable] - -Signed-off-by: Lubomir Rintel -Signed-off-by: Craig McGeachie -Signed-off-by: Eric Anholt -Acked-by: Stephen Warren -Signed-off-by: Jassi Brar ---- - drivers/mailbox/Kconfig | 9 ++ - drivers/mailbox/Makefile | 2 + - drivers/mailbox/bcm2835-mailbox.c | 216 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 227 insertions(+) - create mode 100644 drivers/mailbox/bcm2835-mailbox.c - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 7f19cb4..dc64c93 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -66,4 +66,13 @@ config ALTERA_MBOX - An implementation of the Altera Mailbox soft core. It is used - to send message between processors. Say Y here if you want to use the - Altera mailbox support. -+ -+config BCM2835_MBOX -+ tristate "BCM2835 Mailbox" -+ depends on ARCH_BCM2835 -+ help -+ An implementation of the BCM2385 Mailbox. It is used to invoke -+ the services of the Videocore. Say Y here if you want to use the -+ BCM2835 Mailbox. -+ - endif -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index cecfad3..c86bc91 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -13,3 +13,5 @@ obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o - obj-$(CONFIG_PCC) += pcc.o - - obj-$(CONFIG_ALTERA_MBOX) += mailbox-altera.o -+ -+obj-$(CONFIG_BCM2835_MBOX) += bcm2835-mailbox.o -diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c -new file mode 100644 -index 0000000..4b13268 ---- /dev/null -+++ b/drivers/mailbox/bcm2835-mailbox.c -@@ -0,0 +1,216 @@ -+/* -+ * Copyright (C) 2010,2015 Broadcom -+ * Copyright (C) 2013-2014 Lubomir Rintel -+ * Copyright (C) 2013 Craig McGeachie -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a mechanism for writing to the mailboxes, -+ * that are shared between the ARM and the VideoCore processor -+ * -+ * Parts of the driver are based on: -+ * - arch/arm/mach-bcm2708/vcio.c file written by Gray Girling that was -+ * obtained from branch "rpi-3.6.y" of git://github.com/raspberrypi/ -+ * linux.git -+ * - drivers/mailbox/bcm2835-ipc.c by Lubomir Rintel at -+ * https://github.com/hackerspace/rpi-linux/blob/lr-raspberry-pi/drivers/ -+ * mailbox/bcm2835-ipc.c -+ * - documentation available on the following web site: -+ * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Mailboxes */ -+#define ARM_0_MAIL0 0x00 -+#define ARM_0_MAIL1 0x20 -+ -+/* -+ * Mailbox registers. We basically only support mailbox 0 & 1. We -+ * deliver to the VC in mailbox 1, it delivers to us in mailbox 0. See -+ * BCM2835-ARM-Peripherals.pdf section 1.3 for an explanation about -+ * the placement of memory barriers. -+ */ -+#define MAIL0_RD (ARM_0_MAIL0 + 0x00) -+#define MAIL0_POL (ARM_0_MAIL0 + 0x10) -+#define MAIL0_STA (ARM_0_MAIL0 + 0x18) -+#define MAIL0_CNF (ARM_0_MAIL0 + 0x1C) -+#define MAIL1_WRT (ARM_0_MAIL1 + 0x00) -+ -+/* Status register: FIFO state. */ -+#define ARM_MS_FULL BIT(31) -+#define ARM_MS_EMPTY BIT(30) -+ -+/* Configuration register: Enable interrupts. */ -+#define ARM_MC_IHAVEDATAIRQEN BIT(0) -+ -+struct bcm2835_mbox { -+ void __iomem *regs; -+ spinlock_t lock; -+ struct mbox_controller controller; -+}; -+ -+static struct bcm2835_mbox *bcm2835_link_mbox(struct mbox_chan *link) -+{ -+ return container_of(link->mbox, struct bcm2835_mbox, controller); -+} -+ -+static irqreturn_t bcm2835_mbox_irq(int irq, void *dev_id) -+{ -+ struct bcm2835_mbox *mbox = dev_id; -+ struct device *dev = mbox->controller.dev; -+ struct mbox_chan *link = &mbox->controller.chans[0]; -+ -+ while (!(readl(mbox->regs + MAIL0_STA) & ARM_MS_EMPTY)) { -+ u32 msg = readl(mbox->regs + MAIL0_RD); -+ dev_dbg(dev, "Reply 0x%08X\n", msg); -+ mbox_chan_received_data(link, &msg); -+ } -+ return IRQ_HANDLED; -+} -+ -+static int bcm2835_send_data(struct mbox_chan *link, void *data) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ u32 msg = *(u32 *)data; -+ -+ spin_lock(&mbox->lock); -+ writel(msg, mbox->regs + MAIL1_WRT); -+ dev_dbg(mbox->controller.dev, "Request 0x%08X\n", msg); -+ spin_unlock(&mbox->lock); -+ return 0; -+} -+ -+static int bcm2835_startup(struct mbox_chan *link) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox->regs + MAIL0_CNF); -+ -+ return 0; -+} -+ -+static void bcm2835_shutdown(struct mbox_chan *link) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ -+ writel(0, mbox->regs + MAIL0_CNF); -+} -+ -+static bool bcm2835_last_tx_done(struct mbox_chan *link) -+{ -+ struct bcm2835_mbox *mbox = bcm2835_link_mbox(link); -+ bool ret; -+ -+ spin_lock(&mbox->lock); -+ ret = !(readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL); -+ spin_unlock(&mbox->lock); -+ return ret; -+} -+ -+static const struct mbox_chan_ops bcm2835_mbox_chan_ops = { -+ .send_data = bcm2835_send_data, -+ .startup = bcm2835_startup, -+ .shutdown = bcm2835_shutdown, -+ .last_tx_done = bcm2835_last_tx_done -+}; -+ -+static struct mbox_chan *bcm2835_mbox_index_xlate(struct mbox_controller *mbox, -+ const struct of_phandle_args *sp) -+{ -+ if (sp->args_count != 0) -+ return NULL; -+ -+ return &mbox->chans[0]; -+} -+ -+static int bcm2835_mbox_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ int ret = 0; -+ struct resource *iomem; -+ struct bcm2835_mbox *mbox; -+ -+ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL); -+ if (mbox == NULL) -+ return -ENOMEM; -+ spin_lock_init(&mbox->lock); -+ -+ ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), -+ bcm2835_mbox_irq, 0, dev_name(dev), mbox); -+ if (ret) { -+ dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", -+ ret); -+ return -ENODEV; -+ } -+ -+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mbox->regs = devm_ioremap_resource(&pdev->dev, iomem); -+ if (IS_ERR(mbox->regs)) { -+ ret = PTR_ERR(mbox->regs); -+ dev_err(&pdev->dev, "Failed to remap mailbox regs: %d\n", ret); -+ return ret; -+ } -+ -+ mbox->controller.txdone_poll = true; -+ mbox->controller.txpoll_period = 5; -+ mbox->controller.ops = &bcm2835_mbox_chan_ops; -+ mbox->controller.of_xlate = &bcm2835_mbox_index_xlate; -+ mbox->controller.dev = dev; -+ mbox->controller.num_chans = 1; -+ mbox->controller.chans = devm_kzalloc(dev, -+ sizeof(*mbox->controller.chans), GFP_KERNEL); -+ if (!mbox->controller.chans) -+ return -ENOMEM; -+ -+ ret = mbox_controller_register(&mbox->controller); -+ if (ret) -+ return ret; -+ -+ platform_set_drvdata(pdev, mbox); -+ dev_info(dev, "mailbox enabled\n"); -+ -+ return ret; -+} -+ -+static int bcm2835_mbox_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_mbox *mbox = platform_get_drvdata(pdev); -+ mbox_controller_unregister(&mbox->controller); -+ return 0; -+} -+ -+static const struct of_device_id bcm2835_mbox_of_match[] = { -+ { .compatible = "brcm,bcm2835-mbox", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_mbox_of_match); -+ -+static struct platform_driver bcm2835_mbox_driver = { -+ .driver = { -+ .name = "bcm2835-mbox", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_mbox_of_match, -+ }, -+ .probe = bcm2835_mbox_probe, -+ .remove = bcm2835_mbox_remove, -+}; -+module_platform_driver(bcm2835_mbox_driver); -+ -+MODULE_AUTHOR("Lubomir Rintel "); -+MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); -+MODULE_LICENSE("GPL v2"); - -From d9468dc86cfdb7fed108e1e888979b622d578f71 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 13 May 2015 13:10:32 -0700 -Subject: [PATCH 110/204] mailbox/bcm2835: Fix mailbox full detection. - -With the VC reader blocked and the ARM writing, MAIL0_STA reads empty -permanently while MAIL1_STA goes from empty (0x40000000) to non-empty -(0x00000001-0x00000007) to full (0x80000008). - -This bug ended up having no effect on us, because all of our -transactions in the client driver were synchronous and under a mutex. - -Suggested-by: Phil Elwell -Signed-off-by: Eric Anholt -Acked-by: Stephen Warren -Signed-off-by: Jassi Brar ---- - drivers/mailbox/bcm2835-mailbox.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c -index 4b13268..0b47dd4 100644 ---- a/drivers/mailbox/bcm2835-mailbox.c -+++ b/drivers/mailbox/bcm2835-mailbox.c -@@ -49,6 +49,7 @@ - #define MAIL0_STA (ARM_0_MAIL0 + 0x18) - #define MAIL0_CNF (ARM_0_MAIL0 + 0x1C) - #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) -+#define MAIL1_STA (ARM_0_MAIL1 + 0x18) - - /* Status register: FIFO state. */ - #define ARM_MS_FULL BIT(31) -@@ -117,7 +118,7 @@ static bool bcm2835_last_tx_done(struct mbox_chan *link) - bool ret; - - spin_lock(&mbox->lock); -- ret = !(readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL); -+ ret = !(readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL); - spin_unlock(&mbox->lock); - return ret; - } - -From 518512c73c439f3684fbe42f07048b79be906f4a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:19:30 +0200 -Subject: [PATCH 111/204] mailbox: bcm2835: Support ARCH_BCM270x -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make it possible to use bcm2835-mailbox without Device Tree. -Load driver early because of lacking support for deferred probing -in many drivers. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 2 +- - drivers/mailbox/bcm2835-mailbox.c | 18 ++++++++++++++++-- - drivers/mailbox/mailbox.c | 13 ++++++++++++- - 3 files changed, 29 insertions(+), 4 deletions(-) - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index dc64c93..962b80c 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -69,7 +69,7 @@ config ALTERA_MBOX - - config BCM2835_MBOX - tristate "BCM2835 Mailbox" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - help - An implementation of the BCM2385 Mailbox. It is used to invoke - the services of the Videocore. Say Y here if you want to use the -diff --git a/drivers/mailbox/bcm2835-mailbox.c b/drivers/mailbox/bcm2835-mailbox.c -index 0b47dd4..d16e286 100644 ---- a/drivers/mailbox/bcm2835-mailbox.c -+++ b/drivers/mailbox/bcm2835-mailbox.c -@@ -51,12 +51,15 @@ - #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) - #define MAIL1_STA (ARM_0_MAIL1 + 0x18) - -+/* On ARCH_BCM270x these come through (arm_control.h ) */ -+#ifndef ARM_MS_FULL - /* Status register: FIFO state. */ - #define ARM_MS_FULL BIT(31) - #define ARM_MS_EMPTY BIT(30) - - /* Configuration register: Enable interrupts. */ - #define ARM_MC_IHAVEDATAIRQEN BIT(0) -+#endif - - struct bcm2835_mbox { - void __iomem *regs; -@@ -151,7 +154,7 @@ static int bcm2835_mbox_probe(struct platform_device *pdev) - return -ENOMEM; - spin_lock_init(&mbox->lock); - -- ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), -+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), - bcm2835_mbox_irq, 0, dev_name(dev), mbox); - if (ret) { - dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", -@@ -210,7 +213,18 @@ static struct platform_driver bcm2835_mbox_driver = { - .probe = bcm2835_mbox_probe, - .remove = bcm2835_mbox_remove, - }; --module_platform_driver(bcm2835_mbox_driver); -+ -+static int __init bcm2835_mbox_init(void) -+{ -+ return platform_driver_register(&bcm2835_mbox_driver); -+} -+arch_initcall(bcm2835_mbox_init); -+ -+static void __init bcm2835_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm2835_mbox_driver); -+} -+module_exit(bcm2835_mbox_exit); - - MODULE_AUTHOR("Lubomir Rintel "); - MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); -diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c -index 19b491d..cc07d71 100644 ---- a/drivers/mailbox/mailbox.c -+++ b/drivers/mailbox/mailbox.c -@@ -304,13 +304,23 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) - unsigned long flags; - int ret; - -- if (!dev || !dev->of_node) { -+ if (!dev) { - pr_debug("%s: No owner device node\n", __func__); - return ERR_PTR(-ENODEV); - } - - mutex_lock(&con_mutex); - -+ if (!dev->of_node) { -+ chan = NULL; -+ /* pick the first controller in the list */ -+ list_for_each_entry(mbox, &mbox_cons, node) { -+ chan = &mbox->chans[0]; -+ break; -+ } -+ goto skip_dt; -+ } -+ - if (of_parse_phandle_with_args(dev->of_node, "mboxes", - "#mbox-cells", index, &spec)) { - dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__); -@@ -327,6 +337,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) - - of_node_put(spec.np); - -+skip_dt: - if (!chan || chan->cl || !try_module_get(mbox->dev->driver->owner)) { - dev_dbg(dev, "%s: mailbox not free\n", __func__); - mutex_unlock(&con_mutex); - -From 69b0fd32b30439447e33723fde68aadaed7d9b42 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Jun 2015 13:11:47 -0700 -Subject: [PATCH 112/204] ARM: bcm2835: Add the firmware driver information to - the RPi DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Eric Anholt -Acked-by: Lee Jones (previous version with pm-domains) -Acked-by: Stephen Warren -[Rebased on rpi-4.1.y] -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index 466f02b..5cdfd5a 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -27,6 +27,13 @@ - }; - }; - -+ soc { -+ firmware: firmware { -+ compatible = "raspberrypi,bcm2835-firmware"; -+ mboxes = <&mailbox>; -+ }; -+ }; -+ - /* Onboard audio */ - audio: audio { - compatible = "brcm,bcm2835-audio"; - -From 0438cbca296cfb3bc165b1f54c4e16f57f5760f0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:21:20 +0200 -Subject: [PATCH 113/204] firmware: bcm2835: Add missing property tags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index 9d9efb7..d3933af 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -60,6 +60,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, - RPI_FIRMWARE_GET_TURBO = 0x00030009, - RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, -+ RPI_FIRMWARE_GET_STC = 0x0003000b, - RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, - RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, - RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, -@@ -69,10 +70,12 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, - RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, - RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, -+ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, - RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, - RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, - RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, - RPI_FIRMWARE_SET_TURBO = 0x00038009, -+ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, - - /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -@@ -86,6 +89,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, - RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -@@ -95,6 +99,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, - RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, - RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, -@@ -103,6 +108,9 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, -+ -+ RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - -From 2df587b5e056fb8a0eba5efc2023533efb2807be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:25:01 +0200 -Subject: [PATCH 114/204] firmware: bcm2835: Support ARCH_BCM270x -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Support booting without Device Tree. -Turn on USB power. -Load driver early because of lacking support for deferred probing -in many drivers. - -Signed-off-by: Noralf Trønnes ---- - drivers/firmware/raspberrypi.c | 41 +++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 39 insertions(+), 2 deletions(-) - -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -index dd506cd3..b980d53 100644 ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -28,6 +28,8 @@ struct rpi_firmware { - u32 enabled; - }; - -+static struct platform_device *g_pdev; -+ - static DEFINE_MUTEX(transaction_lock); - - static void response_callback(struct mbox_client *cl, void *msg) -@@ -183,6 +185,25 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) - } - } - -+static int raspberrypi_firmware_set_power(struct rpi_firmware *fw, -+ u32 domain, bool on) -+{ -+ struct { -+ u32 domain; -+ u32 on; -+ } packet; -+ int ret; -+ -+ packet.domain = domain; -+ packet.on = on; -+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POWER_STATE, -+ &packet, sizeof(packet)); -+ if (!ret && packet.on != on) -+ ret = -EINVAL; -+ -+ return ret; -+} -+ - static int rpi_firmware_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -207,9 +228,13 @@ static int rpi_firmware_probe(struct platform_device *pdev) - init_completion(&fw->c); - - platform_set_drvdata(pdev, fw); -+ g_pdev = pdev; - - rpi_firmware_print_firmware_revision(fw); - -+ if (raspberrypi_firmware_set_power(fw, 3, true)) -+ dev_err(dev, "failed to turn on USB power\n"); -+ - return 0; - } - -@@ -218,6 +243,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) - struct rpi_firmware *fw = platform_get_drvdata(pdev); - - mbox_free_channel(fw->chan); -+ g_pdev = NULL; - - return 0; - } -@@ -230,7 +256,7 @@ static int rpi_firmware_remove(struct platform_device *pdev) - */ - struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) - { -- struct platform_device *pdev = of_find_device_by_node(firmware_node); -+ struct platform_device *pdev = g_pdev; - - if (!pdev) - return NULL; -@@ -253,7 +279,18 @@ static struct platform_driver rpi_firmware_driver = { - .probe = rpi_firmware_probe, - .remove = rpi_firmware_remove, - }; --module_platform_driver(rpi_firmware_driver); -+ -+static int __init rpi_firmware_init(void) -+{ -+ return platform_driver_register(&rpi_firmware_driver); -+} -+subsys_initcall(rpi_firmware_init); -+ -+static void __init rpi_firmware_exit(void) -+{ -+ platform_driver_unregister(&rpi_firmware_driver); -+} -+module_exit(rpi_firmware_exit); - - MODULE_AUTHOR("Eric Anholt "); - MODULE_DESCRIPTION("Raspberry Pi firmware driver"); - -From c9295b68944211995a84d596a904f9657b4482c6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:26:10 +0200 -Subject: [PATCH 115/204] firmware: bcm2835: Support legacy mailbox API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for the bcm_mailbox_*() functions. -This is temporary until all drivers have been converted to the -firmware API (rpi_firmware_property*()). - -Signed-off-by: Noralf Trønnes ---- - drivers/firmware/raspberrypi.c | 15 +++++++++++++-- - include/soc/bcm2835/raspberrypi-firmware.h | 2 ++ - 2 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -index b980d53..89421a9 100644 ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -19,6 +19,7 @@ - #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) - #define MBOX_CHAN(msg) ((msg) & 0xf) - #define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_CHAN_VCHIQ 3 - #define MBOX_CHAN_PROPERTY 8 - - struct rpi_firmware { -@@ -26,6 +27,7 @@ struct rpi_firmware { - struct mbox_chan *chan; /* The property channel. */ - struct completion c; - u32 enabled; -+ u32 received; - }; - - static struct platform_device *g_pdev; -@@ -35,6 +37,7 @@ static DEFINE_MUTEX(transaction_lock); - static void response_callback(struct mbox_client *cl, void *msg) - { - struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); -+ fw->received = *(u32 *)msg; - complete(&fw->c); - } - -@@ -42,7 +45,7 @@ static void response_callback(struct mbox_client *cl, void *msg) - * Sends a request to the firmware through the BCM2835 mailbox driver, - * and synchronously waits for the reply. - */ --static int -+int - rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - { - u32 message = MBOX_MSG(chan, data); -@@ -54,7 +57,8 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - reinit_completion(&fw->c); - ret = mbox_send_message(fw->chan, &message); - if (ret >= 0) { -- wait_for_completion(&fw->c); -+ if (chan != MBOX_CHAN_VCHIQ) -+ wait_for_completion(&fw->c); - ret = 0; - } else { - dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); -@@ -63,6 +67,13 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - - return ret; - } -+EXPORT_SYMBOL(rpi_firmware_transaction); -+ -+u32 rpi_firmware_transaction_received(struct rpi_firmware *fw) -+{ -+ return MBOX_DATA28(fw->received); -+} -+EXPORT_SYMBOL(rpi_firmware_transaction_received); - - /** - * rpi_firmware_property_list - Submit firmware property list -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index d3933af..9a08cf1 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -116,6 +116,8 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - }; - -+int rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data); -+u32 rpi_firmware_transaction_received(struct rpi_firmware *fw); - int rpi_firmware_property(struct rpi_firmware *fw, - u32 tag, void *data, size_t len); - int rpi_firmware_property_list(struct rpi_firmware *fw, - -From 2f10d2c9d55ec24c07d869e591d7db9fdde5dfa6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:27:06 +0200 -Subject: [PATCH 116/204] char: broadcom: Add vcio module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add module for accessing the mailbox property channel through -/dev/vcio. Was previously in bcm2708-vcio. - -Signed-off-by: Noralf Trønnes ---- - drivers/char/broadcom/Kconfig | 6 ++ - drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/vcio.c | 175 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 182 insertions(+) - create mode 100644 drivers/char/broadcom/vcio.c - -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index 75fa1cb..fc40846 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -22,6 +22,12 @@ config BCM2708_VCMEM - help - Helper for videocore memory access and total size allocation. - -+config BCM_VCIO -+ tristate "Mailbox userspace access" -+ depends on BCM2835_MBOX -+ help -+ Gives access to the mailbox property channel from userspace. -+ - endif - - config BCM_VC_SM -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index de8feb9..18171e2 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -1,3 +1,4 @@ - obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -+obj-$(CONFIG_BCM_VCIO) += vcio.o - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ -diff --git a/drivers/char/broadcom/vcio.c b/drivers/char/broadcom/vcio.c -new file mode 100644 -index 0000000..c19bc20 ---- /dev/null -+++ b/drivers/char/broadcom/vcio.c -@@ -0,0 +1,175 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * Copyright (C) 2015 Noralf Trønnes -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MBOX_CHAN_PROPERTY 8 -+ -+#define VCIO_IOC_MAGIC 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) -+ -+static struct { -+ dev_t devt; -+ struct cdev cdev; -+ struct class *class; -+ struct rpi_firmware *fw; -+} vcio; -+ -+static int vcio_user_property_list(void *user) -+{ -+ u32 *buf, size; -+ int ret; -+ -+ /* The first 32-bit is the size of the buffer */ -+ if (copy_from_user(&size, user, sizeof(size))) -+ return -EFAULT; -+ -+ buf = kmalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, user, size)) { -+ kfree(buf); -+ return -EFAULT; -+ } -+ -+ /* Strip off protocol encapsulation */ -+ ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); -+ if (ret) { -+ kfree(buf); -+ return ret; -+ } -+ -+ buf[1] = RPI_FIRMWARE_STATUS_SUCCESS; -+ if (copy_to_user(user, buf, size)) -+ ret = -EFAULT; -+ -+ kfree(buf); -+ -+ return ret; -+} -+ -+static int vcio_device_open(struct inode *inode, struct file *file) -+{ -+ try_module_get(THIS_MODULE); -+ -+ return 0; -+} -+ -+static int vcio_device_release(struct inode *inode, struct file *file) -+{ -+ module_put(THIS_MODULE); -+ -+ return 0; -+} -+ -+static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ return vcio_user_property_list((void *)ioctl_param); -+ default: -+ pr_err("unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+} -+ -+const struct file_operations vcio_fops = { -+ .unlocked_ioctl = vcio_device_ioctl, -+ .open = vcio_device_open, -+ .release = vcio_device_release, -+}; -+ -+static int __init vcio_init(void) -+{ -+ struct device_node *np; -+ static struct device *dev; -+ int ret; -+ -+ np = of_find_compatible_node(NULL, NULL, -+ "raspberrypi,bcm2835-firmware"); -+/* Uncomment this when we only boot with Device Tree -+ if (!of_device_is_available(np)) -+ return -ENODEV; -+*/ -+ vcio.fw = rpi_firmware_get(np); -+ if (!vcio.fw) -+ return -ENODEV; -+ -+ ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); -+ if (ret) { -+ pr_err("failed to allocate device number\n"); -+ return ret; -+ } -+ -+ cdev_init(&vcio.cdev, &vcio_fops); -+ vcio.cdev.owner = THIS_MODULE; -+ ret = cdev_add(&vcio.cdev, vcio.devt, 1); -+ if (ret) { -+ pr_err("failed to register device\n"); -+ goto err_unregister_chardev; -+ } -+ -+ /* -+ * Create sysfs entries -+ * 'bcm2708_vcio' is used for backwards compatibility so we don't break -+ * userspace. Raspian has a udev rule that changes the permissions. -+ */ -+ vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); -+ if (IS_ERR(vcio.class)) { -+ ret = PTR_ERR(vcio.class); -+ pr_err("failed to create class\n"); -+ goto err_cdev_del; -+ } -+ -+ dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); -+ if (IS_ERR(dev)) { -+ ret = PTR_ERR(dev); -+ pr_err("failed to create device\n"); -+ goto err_class_destroy; -+ } -+ -+ return 0; -+ -+err_class_destroy: -+ class_destroy(vcio.class); -+err_cdev_del: -+ cdev_del(&vcio.cdev); -+err_unregister_chardev: -+ unregister_chrdev_region(vcio.devt, 1); -+ -+ return ret; -+} -+module_init(vcio_init); -+ -+static void __exit vcio_exit(void) -+{ -+ device_destroy(vcio.class, vcio.devt); -+ class_destroy(vcio.class); -+ cdev_del(&vcio.cdev); -+ unregister_chrdev_region(vcio.devt, 1); -+} -+module_exit(vcio_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_AUTHOR("Noralf Trønnes"); -+MODULE_DESCRIPTION("Mailbox userspace access"); -+MODULE_LICENSE("GPL"); - -From 8bcd6e604c131b2009b0d9e47561cead558c3d82 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:37:19 +0200 -Subject: [PATCH 117/204] BCM270x: Switch to firmware driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -defconfig: enable BCM2835_MBOX, RASPBERRYPI_FIRMWARE and BCM_VCIO. -Add firmware node and change mailbox node in Device Tree. -Add/update platform file for firmware and mailbox. -Strip bcm2708-vcio of everything except the legacy API and hook it -up with the firmware driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 8 +- - arch/arm/configs/bcm2709_defconfig | 3 + - arch/arm/configs/bcmrpi_defconfig | 3 + - arch/arm/mach-bcm2708/bcm2708.c | 13 +- - arch/arm/mach-bcm2709/bcm2709.c | 13 +- - drivers/mailbox/Kconfig | 2 +- - drivers/mailbox/bcm2708-vcio.c | 353 ++-------------------------------- - 7 files changed, 51 insertions(+), 344 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index abf3e5d..2dd25f7 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -74,9 +74,10 @@ - }; - - mailbox: mailbox@7e00b800 { -- compatible = "brcm,bcm2708-vcio"; -+ compatible = "brcm,bcm2835-mbox"; - reg = <0x7e00b880 0x40>; - interrupts = <0 1>; -+ #mbox-cells = <0>; - }; - - watchdog: watchdog@7e100000 { -@@ -205,6 +206,11 @@ - <1 9>; - }; - -+ firmware: firmware { -+ compatible = "raspberrypi,bcm2835-firmware"; -+ mboxes = <&mailbox>; -+ }; -+ - leds: leds { - compatible = "gpio-leds"; - }; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 5ecd84f..d75b104 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -574,6 +574,7 @@ CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y - CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y - CONFIG_BCM_VC_SM=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1074,6 +1075,7 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -@@ -1082,6 +1084,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y - CONFIG_EXT4_FS_SECURITY=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 14b91fdf..9159892 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -567,6 +567,7 @@ CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y - CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y - CONFIG_BCM_VC_SM=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1067,6 +1068,7 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -@@ -1075,6 +1077,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y - CONFIG_EXT4_FS_SECURITY=y -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 937c2d3..1b9c3be 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -405,7 +405,7 @@ static struct resource bcm2708_vcio_resources[] = { - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = "bcm2708_vcio", -+ .name = "bcm2835-mbox", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -@@ -415,6 +415,16 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_rpifw_device = { -+ .name = "raspberrypi-firmware", -+ .dev = { -+ .dma_mask = &rpifw_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - static struct resource bcm2708_vchiq_resources[] = { - { - .start = ARMCTRL_0_BELL_BASE, -@@ -871,6 +881,7 @@ void __init bcm2708_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_rpifw_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index fe71c50..e1934dc 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -426,7 +426,7 @@ static struct resource bcm2708_vcio_resources[] = { - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = "bcm2708_vcio", -+ .name = "bcm2835-mbox", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -@@ -436,6 +436,16 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_rpifw_device = { -+ .name = "raspberrypi-firmware", -+ .dev = { -+ .dma_mask = &rpifw_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - static struct resource bcm2708_vchiq_resources[] = { - { - .start = ARMCTRL_0_BELL_BASE, -@@ -892,6 +902,7 @@ void __init bcm2709_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_rpifw_device); - bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 962b80c..d1a6671 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -9,7 +9,7 @@ if MAILBOX - - config BCM2708_MBOX - bool "Broadcom BCM2708 Mailbox (vcio)" -- depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ depends on BCM2835_MBOX - help - Broadcom BCM2708 Mailbox (vcio) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index 06fb2c2f..2e4031b 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -1,6 +1,4 @@ - /* -- * linux/arch/arm/mach-bcm2708/vcio.c -- * - * Copyright (C) 2010 Broadcom - * - * This program is free software; you can redistribute it and/or modify -@@ -12,195 +10,38 @@ - * VideoCore processor - */ - --#include - #include --#include --#include --#include - #include --#include --#include --#include -+#include - #include --#include - #include -+#include - - #define DRIVER_NAME "bcm2708_vcio" --#define DEVICE_FILE_NAME "vcio" -- --/* offsets from a mail box base address */ --#define MAIL0_RD 0x00 /* read - and next 4 words */ --#define MAIL0_POL 0x10 /* read without popping the fifo */ --#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL0_STA 0x18 /* status */ --#define MAIL0_CNF 0x1C /* configuration */ --#define MAIL1_WRT 0x20 /* write - and next 4 words */ --#define MAIL1_STA 0x38 /* status */ -- --/* On MACH_BCM270x these come through (arm_control.h ) */ --#ifndef ARM_MS_EMPTY --#define ARM_MS_EMPTY BIT(30) --#define ARM_MS_FULL BIT(31) -- --#define ARM_MC_IHAVEDATAIRQEN BIT(0) --#endif -- --#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) --#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) --#define MBOX_CHAN(msg) ((msg) & 0xf) --#define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -- --#define MBOX_MAGIC 0xd0d0c0de -- --#define MAJOR_NUM 100 --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -- --static struct class *vcio_class; -- --struct vc_mailbox { -- void __iomem *regs; -- uint32_t msg[MBOX_CHAN_COUNT]; -- struct semaphore sema[MBOX_CHAN_COUNT]; -- uint32_t magic; --}; -- --static void mbox_init(struct vc_mailbox *mbox_out) --{ -- int i; -- -- for (i = 0; i < MBOX_CHAN_COUNT; i++) { -- mbox_out->msg[i] = 0; -- sema_init(&mbox_out->sema[i], 0); -- } -- -- /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -- -- mbox_out->magic = MBOX_MAGIC; --} -- --static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) -- cpu_relax(); -- -- writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -- -- return 0; --} -- --static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- -- return 0; --} -- --static irqreturn_t mbox_irq_handler(int irq, void *dev_id) --{ -- /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -- int status = readl(mbox->regs + MAIL0_STA); -- int ret = IRQ_NONE; -- -- while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->regs + MAIL0_RD); -- int chan = MBOX_CHAN(msg); -- -- if (chan < MBOX_CHAN_COUNT) { -- if (mbox->msg[chan]) { -- pr_err(DRIVER_NAME -- ": mbox chan %d overflow - drop %08x\n", -- chan, msg); -- } else { -- mbox->msg[chan] = (msg | 0xf); -- up(&mbox->sema[chan]); -- } -- } else { -- pr_err(DRIVER_NAME -- ": invalid channel selector (msg %08x)\n", msg); -- } -- ret = IRQ_HANDLED; -- status = readl(mbox->regs + MAIL0_STA); -- } -- return ret; --} -- --/* Mailbox Methods */ -- --static struct device *mbox_dev; /* we assume there's only one! */ -- --static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_write(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_read(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} - - extern int bcm_mailbox_write(unsigned chan, uint32_t data28) - { -- if (!mbox_dev) -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); -+ -+ if (!fw) - return -ENODEV; - -- return dev_mbox_write(mbox_dev, chan, data28); -+ return rpi_firmware_transaction(fw, chan, data28); - } - EXPORT_SYMBOL_GPL(bcm_mailbox_write); - - extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) - { -- if (!mbox_dev) -- return -ENODEV; -- -- return dev_mbox_read(mbox_dev, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); - --static int mbox_copy_from_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)src < TASK_SIZE) -- return copy_from_user(dst, src, size); -- -- memcpy(dst, src, size); -- -- return 0; --} -- --static int mbox_copy_to_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)dst < TASK_SIZE) -- return copy_to_user(dst, src, size); -+ if (!fw) -+ return -ENODEV; - -- memcpy(dst, src, size); -+ *data28 = rpi_firmware_transaction_received(fw); - - return 0; - } -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); - - static DEFINE_MUTEX(mailbox_lock); - extern int bcm_mailbox_property(void *data, int size) -@@ -216,7 +57,7 @@ extern int bcm_mailbox_property(void *data, int size) - GFP_KERNEL); - if (mem_kern) { - /* create the message */ -- mbox_copy_from_user(mem_kern, data, size); -+ memcpy(mem_kern, data, size); - - /* send the message */ - wmb(); -@@ -226,7 +67,7 @@ extern int bcm_mailbox_property(void *data, int size) - if (s == 0) { - /* copy the response */ - rmb(); -- mbox_copy_to_user(data, mem_kern, size); -+ memcpy(data, mem_kern, size); - } - dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); - } else { -@@ -240,174 +81,6 @@ extern int bcm_mailbox_property(void *data, int size) - } - EXPORT_SYMBOL_GPL(bcm_mailbox_property); - --/* Platform Device for Mailbox */ -- --/* This is called whenever a process attempts to open the device file */ --static int device_open(struct inode *inode, struct file *file) --{ -- try_module_get(THIS_MODULE); -- -- return 0; --} -- --static int device_release(struct inode *inode, struct file *file) --{ -- module_put(THIS_MODULE); -- -- return 0; --} -- --/* -- * This function is called whenever a process tries to do an ioctl on our -- * device file. We get two extra parameters (additional to the inode and file -- * structures, which all device functions get): the number of the ioctl called -- * and the parameter given to the ioctl function. -- * -- * If the ioctl is write or read/write (meaning output is returned to the -- * calling process), the ioctl call returns the output of this function. -- * -- */ --static long device_ioctl(struct file *file, unsigned int ioctl_num, -- unsigned long ioctl_param) --{ -- unsigned size; -- -- switch (ioctl_num) { -- case IOCTL_MBOX_PROPERTY: -- /* -- * Receive a pointer to a message (in user space) and set that -- * to be the device's message. Get the parameter given to -- * ioctl by the process. -- */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -- return bcm_mailbox_property((void *)ioctl_param, size); -- default: -- pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -- return -EINVAL; -- } -- -- return 0; --} -- --/* Module Declarations */ -- --/* -- * This structure will hold the functions to be called -- * when a process does something to the device we -- * created. Since a pointer to this structure is kept in -- * the devices table, it can't be local to -- * init_module. NULL is for unimplemented functios. -- */ --const struct file_operations fops = { -- .unlocked_ioctl = device_ioctl, -- .open = device_open, -- .release = device_release, /* a.k.a. close */ --}; -- --static int bcm_vcio_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct device *vdev; -- struct vc_mailbox *mailbox; -- struct resource *res; -- int irq, ret; -- -- mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -- if (!mailbox) -- return -ENOMEM; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- mailbox->regs = devm_ioremap_resource(dev, res); -- if (IS_ERR(mailbox->regs)) -- return PTR_ERR(mailbox->regs); -- -- irq = platform_get_irq(pdev, 0); -- ret = devm_request_irq(dev, irq, mbox_irq_handler, -- IRQF_IRQPOLL, -- dev_name(dev), mailbox); -- if (ret) { -- dev_err(dev, "Interrupt request failed %d\n", ret); -- return ret; -- } -- -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- if (ret < 0) { -- pr_err("Character device registration failed %d\n", ret); -- return ret; -- } -- -- vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- pr_err("Class creation failed %d\n", ret); -- goto err_class; -- } -- -- vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -- if (IS_ERR(vdev)) { -- ret = PTR_ERR(vdev); -- pr_err("Device creation failed %d\n", ret); -- goto err_dev; -- } -- -- mbox_init(mailbox); -- platform_set_drvdata(pdev, mailbox); -- mbox_dev = dev; -- -- dev_info(dev, "mailbox at %p\n", mailbox->regs); -- -- return 0; -- --err_dev: -- class_destroy(vcio_class); --err_class: -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return ret; --} -- --static int bcm_vcio_remove(struct platform_device *pdev) --{ -- mbox_dev = NULL; -- platform_set_drvdata(pdev, NULL); -- device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return 0; --} -- --static const struct of_device_id bcm_vcio_of_match_table[] = { -- { .compatible = "brcm,bcm2708-vcio", }, -- {}, --}; --MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -- --static struct platform_driver bcm_mbox_driver = { -- .probe = bcm_vcio_probe, -- .remove = bcm_vcio_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- .of_match_table = bcm_vcio_of_match_table, -- }, --}; -- --static int __init bcm_mbox_init(void) --{ -- return platform_driver_register(&bcm_mbox_driver); --} -- --static void __exit bcm_mbox_exit(void) --{ -- platform_driver_unregister(&bcm_mbox_driver); --} -- --arch_initcall(bcm_mbox_init); /* Initialize early */ --module_exit(bcm_mbox_exit); -- - MODULE_AUTHOR("Gray Girling"); - MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); - MODULE_LICENSE("GPL"); - -From 51a7a4a822bc6ab6927bc0522e5afb6bda8f52b4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:39:21 +0200 -Subject: [PATCH 118/204] bcm2835: Switch to firmware driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -defconfig: enable BCM2835_MBOX, RASPBERRYPI_FIRMWARE and BCM_VCIO. - -Add firmware node and change mailbox node in Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 3 ++- - arch/arm/configs/bcm2835_defconfig | 3 +++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 4b6dd65f..4a63704 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -62,9 +62,10 @@ - }; - - mailbox: mailbox@7e00b800 { -- compatible = "brcm,bcm2708-vcio"; -+ compatible = "brcm,bcm2835-mbox"; - reg = <0x7e00b880 0x40>; - interrupts = <0 1>; -+ #mbox-cells = <0>; - }; - - gpio: gpio@7e200000 { -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 47f2a6a..c284414 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -568,6 +568,7 @@ CONFIG_HW_RANDOM_BCM2835=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y - CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y - CONFIG_BCM_VC_SM=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1064,9 +1065,11 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - CONFIG_EXT2_FS_POSIX_ACL=y - -From 46dd86c7b1dd676e614daca70ec3b7a31cc905f9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 13 Jul 2015 13:25:31 +0100 -Subject: [PATCH 119/204] Merge pull request #1059 from pelwell/rpi-4.0.y - -w1_therm: Back-port locking improvements from 4.2-rc1 ---- - Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 | 6 ++ - Documentation/w1/slaves/w1_therm | 11 ++- - drivers/w1/slaves/w1_therm.c | 102 +++++++++++++++++++++- - 3 files changed, 117 insertions(+), 2 deletions(-) - create mode 100644 Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 - -diff --git a/Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 b/Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 -new file mode 100644 -index 0000000..e928def ---- /dev/null -+++ b/Documentation/ABI/stable/sysfs-driver-w1_ds28ea00 -@@ -0,0 +1,6 @@ -+What: /sys/bus/w1/devices/.../w1_seq -+Date: Apr 2015 -+Contact: Matt Campbell -+Description: Support for the DS28EA00 chain sequence function -+ see Documentation/w1/slaves/w1_therm for detailed information -+Users: any user space application which wants to communicate with DS28EA00 -diff --git a/Documentation/w1/slaves/w1_therm b/Documentation/w1/slaves/w1_therm -index cc62a95..13411fe 100644 ---- a/Documentation/w1/slaves/w1_therm -+++ b/Documentation/w1/slaves/w1_therm -@@ -11,12 +11,14 @@ Author: Evgeniy Polyakov - Description - ----------- - --w1_therm provides basic temperature conversion for ds18*20 devices. -+w1_therm provides basic temperature conversion for ds18*20 devices, and the -+ds28ea00 device. - supported family codes: - W1_THERM_DS18S20 0x10 - W1_THERM_DS1822 0x22 - W1_THERM_DS18B20 0x28 - W1_THERM_DS1825 0x3B -+W1_THERM_DS28EA00 0x42 - - Support is provided through the sysfs w1_slave file. Each open and - read sequence will initiate a temperature conversion then provide two -@@ -48,3 +50,10 @@ resistor). The DS18b20 temperature sensor specification lists a - maximum current draw of 1.5mA and that a 5k pullup resistor is not - sufficient. The strong pullup is designed to provide the additional - current required. -+ -+The DS28EA00 provides an additional two pins for implementing a sequence -+detection algorithm. This feature allows you to determine the physical -+location of the chip in the 1-wire bus without needing pre-existing -+knowledge of the bus ordering. Support is provided through the sysfs -+w1_seq file. The file will contain a single line with an integer value -+representing the device index in the bus starting at 0. -diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c -index 55eb86c..2f029e8 100644 ---- a/drivers/w1/slaves/w1_therm.c -+++ b/drivers/w1/slaves/w1_therm.c -@@ -92,13 +92,24 @@ static void w1_therm_remove_slave(struct w1_slave *sl) - static ssize_t w1_slave_show(struct device *device, - struct device_attribute *attr, char *buf); - -+static ssize_t w1_seq_show(struct device *device, -+ struct device_attribute *attr, char *buf); -+ - static DEVICE_ATTR_RO(w1_slave); -+static DEVICE_ATTR_RO(w1_seq); - - static struct attribute *w1_therm_attrs[] = { - &dev_attr_w1_slave.attr, - NULL, - }; -+ -+static struct attribute *w1_ds28ea00_attrs[] = { -+ &dev_attr_w1_slave.attr, -+ &dev_attr_w1_seq.attr, -+ NULL, -+}; - ATTRIBUTE_GROUPS(w1_therm); -+ATTRIBUTE_GROUPS(w1_ds28ea00); - - static struct w1_family_ops w1_therm_fops = { - .add_slave = w1_therm_add_slave, -@@ -106,6 +117,12 @@ static struct w1_family_ops w1_therm_fops = { - .groups = w1_therm_groups, - }; - -+static struct w1_family_ops w1_ds28ea00_fops = { -+ .add_slave = w1_therm_add_slave, -+ .remove_slave = w1_therm_remove_slave, -+ .groups = w1_ds28ea00_groups, -+}; -+ - static struct w1_family w1_therm_family_DS18S20 = { - .fid = W1_THERM_DS18S20, - .fops = &w1_therm_fops, -@@ -123,7 +140,7 @@ static struct w1_family w1_therm_family_DS1822 = { - - static struct w1_family w1_therm_family_DS28EA00 = { - .fid = W1_THERM_DS28EA00, -- .fops = &w1_therm_fops, -+ .fops = &w1_ds28ea00_fops, - }; - - static struct w1_family w1_therm_family_DS1825 = { -@@ -316,6 +333,89 @@ static ssize_t w1_slave_show(struct device *device, - return ret; - } - -+#define W1_42_CHAIN 0x99 -+#define W1_42_CHAIN_OFF 0x3C -+#define W1_42_CHAIN_OFF_INV 0xC3 -+#define W1_42_CHAIN_ON 0x5A -+#define W1_42_CHAIN_ON_INV 0xA5 -+#define W1_42_CHAIN_DONE 0x96 -+#define W1_42_CHAIN_DONE_INV 0x69 -+#define W1_42_COND_READ 0x0F -+#define W1_42_SUCCESS_CONFIRM_BYTE 0xAA -+#define W1_42_FINISHED_BYTE 0xFF -+static ssize_t w1_seq_show(struct device *device, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w1_slave *sl = dev_to_w1_slave(device); -+ ssize_t c = PAGE_SIZE; -+ int rv; -+ int i; -+ u8 ack; -+ u64 rn; -+ struct w1_reg_num *reg_num; -+ int seq = 0; -+ -+ mutex_lock(&sl->master->bus_mutex); -+ /* Place all devices in CHAIN state */ -+ if (w1_reset_bus(sl->master)) -+ goto error; -+ w1_write_8(sl->master, W1_SKIP_ROM); -+ w1_write_8(sl->master, W1_42_CHAIN); -+ w1_write_8(sl->master, W1_42_CHAIN_ON); -+ w1_write_8(sl->master, W1_42_CHAIN_ON_INV); -+ msleep(sl->master->pullup_duration); -+ -+ /* check for acknowledgment */ -+ ack = w1_read_8(sl->master); -+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE) -+ goto error; -+ -+ /* In case the bus fails to send 0xFF, limit*/ -+ for (i = 0; i <= 64; i++) { -+ if (w1_reset_bus(sl->master)) -+ goto error; -+ -+ w1_write_8(sl->master, W1_42_COND_READ); -+ rv = w1_read_block(sl->master, (u8 *)&rn, 8); -+ reg_num = (struct w1_reg_num *) &rn; -+ if (reg_num->family == W1_42_FINISHED_BYTE) -+ break; -+ if (sl->reg_num.id == reg_num->id) -+ seq = i; -+ -+ w1_write_8(sl->master, W1_42_CHAIN); -+ w1_write_8(sl->master, W1_42_CHAIN_DONE); -+ w1_write_8(sl->master, W1_42_CHAIN_DONE_INV); -+ w1_read_block(sl->master, &ack, sizeof(ack)); -+ -+ /* check for acknowledgment */ -+ ack = w1_read_8(sl->master); -+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE) -+ goto error; -+ -+ } -+ -+ /* Exit from CHAIN state */ -+ if (w1_reset_bus(sl->master)) -+ goto error; -+ w1_write_8(sl->master, W1_SKIP_ROM); -+ w1_write_8(sl->master, W1_42_CHAIN); -+ w1_write_8(sl->master, W1_42_CHAIN_OFF); -+ w1_write_8(sl->master, W1_42_CHAIN_OFF_INV); -+ -+ /* check for acknowledgment */ -+ ack = w1_read_8(sl->master); -+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE) -+ goto error; -+ mutex_unlock(&sl->master->bus_mutex); -+ -+ c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", seq); -+ return PAGE_SIZE - c; -+error: -+ mutex_unlock(&sl->master->bus_mutex); -+ return -EIO; -+} -+ - static int __init w1_therm_init(void) - { - int err, i; - -From 86a4624ee6bc33f41fd7f53d081096ed4aa28cca Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 11:11:51 +0100 -Subject: [PATCH 120/204] vchiq_arm: Sort out the vmalloc case - -See: https://github.com/raspberrypi/linux/issues/1055 ---- - .../misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 5edba23..56bff05 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -394,21 +394,21 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - if (is_vmalloc_addr(buf)) { - int dir = (type == PAGELIST_WRITE) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE; -- unsigned long length = pagelist->length; -- unsigned int offset = pagelist->offset; -+ unsigned long length = count; -+ unsigned int off = offset; - - for (actual_pages = 0; actual_pages < num_pages; - actual_pages++) { - struct page *pg = vmalloc_to_page(buf + (actual_pages * - PAGE_SIZE)); -- size_t bytes = PAGE_SIZE - offset; -+ size_t bytes = PAGE_SIZE - off; - - if (bytes > length) - bytes = length; - pages[actual_pages] = pg; -- dmac_map_area(page_address(pg) + offset, bytes, dir); -+ dmac_map_area(page_address(pg) + off, bytes, dir); - length -= bytes; -- offset = 0; -+ off = 0; - } - *need_release = 0; /* do not try and release vmalloc pages */ - } else { - -From 18952e8ccf8d64fb32bb7b2bbd04967047f02840 Mon Sep 17 00:00:00 2001 +From 16bad45bd62dfa5c591bf33b1725a4a391c2a18d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 121/204] spidev: Add "spidev" compatible string to silence +Subject: [PATCH 087/113] spidev: Add "spidev" compatible string to silence warning See: https://github.com/raspberrypi/linux/issues/1054 @@ -140242,44 +134471,4446 @@ See: https://github.com/raspberrypi/linux/issues/1054 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 8fab566..a9db602 100644 +index ef008e5..1a59226 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c -@@ -707,6 +707,7 @@ static struct class *spidev_class; - #ifdef CONFIG_OF +@@ -695,6 +695,7 @@ static struct class *spidev_class; static const struct of_device_id spidev_dt_ids[] = { { .compatible = "rohm,dh2228fv" }, + { .compatible = "lineartechnology,ltc2488" }, + { .compatible = "spidev" }, {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); -From 58f35e5dc8355250d21db3b7ba0aa560d76a0adc Mon Sep 17 00:00:00 2001 +From c75c13a442609aa49583c5bcd525c60a578337bb Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 14 Jul 2015 17:00:18 +0100 +Subject: [PATCH 088/113] scripts/dtc: Add overlay support + +--- + scripts/dtc/checks.c | 119 ++- + scripts/dtc/dtc-lexer.l | 5 + + scripts/dtc/dtc-lexer.lex.c_shipped | 490 ++++----- + scripts/dtc/dtc-parser.tab.c_shipped | 1896 +++++++++++++++++++--------------- + scripts/dtc/dtc-parser.tab.h_shipped | 107 +- + scripts/dtc/dtc-parser.y | 23 +- + scripts/dtc/dtc.c | 9 +- + scripts/dtc/dtc.h | 38 + + scripts/dtc/flattree.c | 141 ++- + scripts/dtc/version_gen.h | 2 +- + 10 files changed, 1685 insertions(+), 1145 deletions(-) + +diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c +index e81a8c7..efd1bc6 100644 +--- a/scripts/dtc/checks.c ++++ b/scripts/dtc/checks.c +@@ -458,21 +458,91 @@ static void fixup_phandle_references(struct check *c, struct node *dt, + struct node *node, struct property *prop) + { + struct marker *m = prop->val.markers; ++ struct fixup *f, **fp; ++ struct fixup_entry *fe, **fep; + struct node *refnode; + cell_t phandle; ++ int has_phandle_refs; ++ ++ has_phandle_refs = 0; ++ for_each_marker_of_type(m, REF_PHANDLE) { ++ has_phandle_refs = 1; ++ break; ++ } ++ ++ if (!has_phandle_refs) ++ return; + + for_each_marker_of_type(m, REF_PHANDLE) { + assert(m->offset + sizeof(cell_t) <= prop->val.len); + + refnode = get_node_by_ref(dt, m->ref); +- if (! refnode) { ++ if (!refnode && !symbol_fixup_support) { + FAIL(c, "Reference to non-existent node or label \"%s\"\n", +- m->ref); ++ m->ref); + continue; + } + +- phandle = get_node_phandle(dt, refnode); +- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); ++ if (!refnode) { ++ /* allocate fixup entry */ ++ fe = xmalloc(sizeof(*fe)); ++ ++ fe->node = node; ++ fe->prop = prop; ++ fe->offset = m->offset; ++ fe->next = NULL; ++ ++ /* search for an already existing fixup */ ++ for_each_fixup(dt, f) ++ if (strcmp(f->ref, m->ref) == 0) ++ break; ++ ++ /* no fixup found, add new */ ++ if (f == NULL) { ++ f = xmalloc(sizeof(*f)); ++ f->ref = m->ref; ++ f->entries = NULL; ++ f->next = NULL; ++ ++ /* add it to the tree */ ++ fp = &dt->fixups; ++ while (*fp) ++ fp = &(*fp)->next; ++ *fp = f; ++ } ++ ++ /* and now append fixup entry */ ++ fep = &f->entries; ++ while (*fep) ++ fep = &(*fep)->next; ++ *fep = fe; ++ ++ /* mark the entry as unresolved */ ++ phandle = 0xdeadbeef; ++ } else { ++ phandle = get_node_phandle(dt, refnode); ++ ++ /* if it's a plugin, we need to record it */ ++ if (symbol_fixup_support && dt->is_plugin) { ++ ++ /* allocate a new local fixup entry */ ++ fe = xmalloc(sizeof(*fe)); ++ ++ fe->node = node; ++ fe->prop = prop; ++ fe->offset = m->offset; ++ fe->next = NULL; ++ ++ /* append it to the local fixups */ ++ fep = &dt->local_fixups; ++ while (*fep) ++ fep = &(*fep)->next; ++ *fep = fe; ++ } ++ } ++ ++ *((cell_t *)(prop->val.val + m->offset)) = ++ cpu_to_fdt32(phandle); + } + } + ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, +@@ -652,6 +722,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, + } + TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); + ++static void check_auto_label_phandles(struct check *c, struct node *dt, ++ struct node *node) ++{ ++ struct label *l; ++ struct symbol *s, **sp; ++ int has_label; ++ ++ if (!symbol_fixup_support) ++ return; ++ ++ has_label = 0; ++ for_each_label(node->labels, l) { ++ has_label = 1; ++ break; ++ } ++ ++ if (!has_label) ++ return; ++ ++ /* force allocation of a phandle for this node */ ++ (void)get_node_phandle(dt, node); ++ ++ /* add the symbol */ ++ for_each_label(node->labels, l) { ++ ++ s = xmalloc(sizeof(*s)); ++ s->label = l; ++ s->node = node; ++ s->next = NULL; ++ ++ /* add it to the symbols list */ ++ sp = &dt->symbols; ++ while (*sp) ++ sp = &((*sp)->next); ++ *sp = s; ++ } ++} ++NODE_WARNING(auto_label_phandles, NULL); ++ + static struct check *check_table[] = { + &duplicate_node_names, &duplicate_property_names, + &node_name_chars, &node_name_format, &property_name_chars, +@@ -670,6 +779,8 @@ static struct check *check_table[] = { + &avoid_default_addr_size, + &obsolete_chosen_interrupt_controller, + ++ &auto_label_phandles, ++ + &always_fail, + }; + +diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l +index 0ee1caf0..dd44ba2 100644 +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...); + return DT_V1; + } + ++<*>"/plugin/" { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ + <*>"/memreserve/" { + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); +diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped +index 11cd78e..1518525 100644 +--- a/scripts/dtc/dtc-lexer.lex.c_shipped ++++ b/scripts/dtc/dtc-lexer.lex.c_shipped +@@ -9,7 +9,7 @@ + #define FLEX_SCANNER + #define YY_FLEX_MAJOR_VERSION 2 + #define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 39 ++#define YY_FLEX_SUBMINOR_VERSION 35 + #if YY_FLEX_SUBMINOR_VERSION > 0 + #define FLEX_BETA + #endif +@@ -162,12 +162,7 @@ typedef unsigned int flex_uint32_t; + typedef struct yy_buffer_state *YY_BUFFER_STATE; + #endif + +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-extern yy_size_t yyleng; ++extern int yyleng; + + extern FILE *yyin, *yyout; + +@@ -176,7 +171,6 @@ extern FILE *yyin, *yyout; + #define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) +- #define YY_LINENO_REWIND_TO(ptr) + + /* Return all but the first "n" matched characters back to the input stream. */ + #define yyless(n) \ +@@ -194,6 +188,11 @@ extern FILE *yyin, *yyout; + + #define unput(c) yyunput( c, (yytext_ptr) ) + ++#ifndef YY_TYPEDEF_YY_SIZE_T ++#define YY_TYPEDEF_YY_SIZE_T ++typedef size_t yy_size_t; ++#endif ++ + #ifndef YY_STRUCT_YY_BUFFER_STATE + #define YY_STRUCT_YY_BUFFER_STATE + struct yy_buffer_state +@@ -211,7 +210,7 @@ struct yy_buffer_state + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ +- yy_size_t yy_n_chars; ++ int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to +@@ -281,8 +280,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + + /* yy_hold_char holds the character lost when yytext is formed. */ + static char yy_hold_char; +-static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +-yy_size_t yyleng; ++static int yy_n_chars; /* number of characters read into yy_ch_buf */ ++int yyleng; + + /* Points to current character in buffer. */ + static char *yy_c_buf_p = (char *) 0; +@@ -310,7 +309,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + + YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); + YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); ++YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + + void *yyalloc (yy_size_t ); + void *yyrealloc (void *,yy_size_t ); +@@ -342,7 +341,7 @@ void yyfree (void * ); + + /* Begin user sect3 */ + +-#define yywrap() 1 ++#define yywrap(n) 1 + #define YY_SKIP_YYWRAP + + typedef unsigned char YY_CHAR; +@@ -373,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +-#define YY_NUM_RULES 30 +-#define YY_END_OF_BUFFER 31 ++#define YY_NUM_RULES 31 ++#define YY_END_OF_BUFFER 32 + /* This struct is not used in this scanner, + but its presence is necessary. */ + struct yy_trans_info +@@ -382,25 +381,26 @@ struct yy_trans_info + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +-static yyconst flex_int16_t yy_accept[159] = ++static yyconst flex_int16_t yy_accept[166] = + { 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, +- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, +- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, +- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, +- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, +- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, +- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, +- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, +- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, +- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, +- +- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, +- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, +- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +- 5, 8, 0, 0, 0, 0, 7, 0 ++ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, ++ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, ++ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, ++ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, ++ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, ++ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, ++ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, ++ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, ++ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, ++ ++ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, ++ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, ++ 0, 0, 0, 8, 0 + } ; + + static yyconst flex_int32_t yy_ec[256] = +@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = + 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, + 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, + +- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, +- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, +- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, ++ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, ++ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, ++ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +@@ -435,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = + 1, 1, 1, 1, 1 + } ; + +-static yyconst flex_int32_t yy_meta[47] = ++static yyconst flex_int32_t yy_meta[48] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, + 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, + 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 3, 1, 4 ++ 8, 8, 8, 8, 3, 1, 4 + } ; + +-static yyconst flex_int16_t yy_base[173] = ++static yyconst flex_int16_t yy_base[180] = + { 0, +- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, +- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, +- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, +- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, +- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, +- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, +- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, +- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, +- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, +- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, +- +- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, +- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, +- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, +- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, +- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, +- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, +- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, +- 318, 326 ++ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, ++ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, ++ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, ++ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, ++ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, ++ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, ++ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, ++ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, ++ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, ++ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, ++ ++ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, ++ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, ++ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, ++ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, ++ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, ++ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, ++ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, ++ 281, 288, 292, 300, 308, 312, 318, 326, 334 + } ; + +-static yyconst flex_int16_t yy_def[173] = ++static yyconst flex_int16_t yy_def[180] = + { 0, +- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, +- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, +- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, +- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, +- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, +- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, +- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- +- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, +- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, +- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158 ++ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, ++ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, ++ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, ++ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, ++ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, ++ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, ++ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, ++ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, ++ ++ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, ++ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_nxt[438] = ++static yyconst flex_int16_t yy_nxt[449] = + { 0, + 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, + 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, + 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, +- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, +- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, +- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, +- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, +- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, +- +- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, +- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, +- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, +- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, +- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, +- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, +- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, +- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, +- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, +- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, +- +- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, +- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, +- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, +- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, +- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, +- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, +- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, +- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, +- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, +- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, +- +- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, +- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, +- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, +- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, +- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, +- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, +- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, +- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, +- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, +- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158 ++ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, ++ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, ++ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, ++ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, ++ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, ++ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, ++ ++ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, ++ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, ++ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, ++ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, ++ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, ++ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, ++ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, ++ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, ++ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, ++ ++ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, ++ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, ++ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, ++ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, ++ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, ++ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, ++ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, ++ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, ++ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, ++ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, ++ ++ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, ++ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, ++ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, ++ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, ++ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, ++ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, ++ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, ++ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, ++ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, ++ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, ++ ++ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_chk[438] = ++static yyconst flex_int16_t yy_chk[449] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, +- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, +- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, ++ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, ++ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, ++ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, +- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, +- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, +- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, +- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, +- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, +- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, +- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, +- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, +- +- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, +- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, +- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, +- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, +- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, +- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, +- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, +- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, +- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, +- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, +- +- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, +- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, +- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, +- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, +- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, +- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, +- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, +- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, ++ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, ++ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, ++ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, ++ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, ++ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, ++ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, ++ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, ++ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, ++ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, ++ ++ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, ++ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, ++ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, ++ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, ++ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, ++ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, ++ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, ++ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, ++ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, ++ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, ++ ++ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, ++ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, ++ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, ++ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, ++ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, ++ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, ++ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, ++ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, ++ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, + 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158 ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + + static yy_state_type yy_last_accepting_state; +@@ -662,7 +664,7 @@ static int dts_version = 1; + static void push_input_file(const char *filename); + static bool pop_input_file(void); + static void lexical_error(const char *fmt, ...); +-#line 666 "dtc-lexer.lex.c" ++#line 668 "dtc-lexer.lex.c" + + #define INITIAL 0 + #define BYTESTRING 1 +@@ -704,7 +706,7 @@ FILE *yyget_out (void ); + + void yyset_out (FILE * out_str ); + +-yy_size_t yyget_leng (void ); ++int yyget_leng (void ); + + char *yyget_text (void ); + +@@ -853,6 +855,10 @@ YY_DECL + register char *yy_cp, *yy_bp; + register int yy_act; + ++#line 68 "dtc-lexer.l" ++ ++#line 861 "dtc-lexer.lex.c" ++ + if ( !(yy_init) ) + { + (yy_init) = 1; +@@ -879,11 +885,6 @@ YY_DECL + yy_load_buffer_state( ); + } + +- { +-#line 68 "dtc-lexer.l" +- +-#line 886 "dtc-lexer.lex.c" +- + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); +@@ -901,7 +902,7 @@ YY_DECL + yy_match: + do + { +- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; ++ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; +@@ -910,13 +911,13 @@ yy_match: + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } +- while ( yy_current_state != 158 ); ++ while ( yy_current_state != 165 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +@@ -1007,23 +1008,31 @@ case 5: + YY_RULE_SETUP + #line 116 "dtc-lexer.l" + { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ YY_BREAK ++case 6: ++YY_RULE_SETUP ++#line 121 "dtc-lexer.l" ++{ + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); + return DT_MEMRESERVE; + } + YY_BREAK +-case 6: ++case 7: + YY_RULE_SETUP +-#line 122 "dtc-lexer.l" ++#line 127 "dtc-lexer.l" + { + DPRINT("Keyword: /bits/\n"); + BEGIN_DEFAULT(); + return DT_BITS; + } + YY_BREAK +-case 7: ++case 8: + YY_RULE_SETUP +-#line 128 "dtc-lexer.l" ++#line 133 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-property/\n"); + DPRINT("\n"); +@@ -1031,9 +1040,9 @@ YY_RULE_SETUP + return DT_DEL_PROP; + } + YY_BREAK +-case 8: ++case 9: + YY_RULE_SETUP +-#line 135 "dtc-lexer.l" ++#line 140 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-node/\n"); + DPRINT("\n"); +@@ -1041,9 +1050,9 @@ YY_RULE_SETUP + return DT_DEL_NODE; + } + YY_BREAK +-case 9: ++case 10: + YY_RULE_SETUP +-#line 142 "dtc-lexer.l" ++#line 147 "dtc-lexer.l" + { + DPRINT("Label: %s\n", yytext); + yylval.labelref = xstrdup(yytext); +@@ -1051,9 +1060,9 @@ YY_RULE_SETUP + return DT_LABEL; + } + YY_BREAK +-case 10: ++case 11: + YY_RULE_SETUP +-#line 149 "dtc-lexer.l" ++#line 154 "dtc-lexer.l" + { + char *e; + DPRINT("Integer Literal: '%s'\n", yytext); +@@ -1073,10 +1082,10 @@ YY_RULE_SETUP + return DT_LITERAL; + } + YY_BREAK +-case 11: +-/* rule 11 can match eol */ ++case 12: ++/* rule 12 can match eol */ + YY_RULE_SETUP +-#line 168 "dtc-lexer.l" ++#line 173 "dtc-lexer.l" + { + struct data d; + DPRINT("Character literal: %s\n", yytext); +@@ -1098,18 +1107,18 @@ YY_RULE_SETUP + return DT_CHAR_LITERAL; + } + YY_BREAK +-case 12: ++case 13: + YY_RULE_SETUP +-#line 189 "dtc-lexer.l" ++#line 194 "dtc-lexer.l" + { /* label reference */ + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = xstrdup(yytext+1); + return DT_REF; + } + YY_BREAK +-case 13: ++case 14: + YY_RULE_SETUP +-#line 195 "dtc-lexer.l" ++#line 200 "dtc-lexer.l" + { /* new-style path reference */ + yytext[yyleng-1] = '\0'; + DPRINT("Ref: %s\n", yytext+2); +@@ -1117,27 +1126,27 @@ YY_RULE_SETUP + return DT_REF; + } + YY_BREAK +-case 14: ++case 15: + YY_RULE_SETUP +-#line 202 "dtc-lexer.l" ++#line 207 "dtc-lexer.l" + { + yylval.byte = strtol(yytext, NULL, 16); + DPRINT("Byte: %02x\n", (int)yylval.byte); + return DT_BYTE; + } + YY_BREAK +-case 15: ++case 16: + YY_RULE_SETUP +-#line 208 "dtc-lexer.l" ++#line 213 "dtc-lexer.l" + { + DPRINT("/BYTESTRING\n"); + BEGIN_DEFAULT(); + return ']'; + } + YY_BREAK +-case 16: ++case 17: + YY_RULE_SETUP +-#line 214 "dtc-lexer.l" ++#line 219 "dtc-lexer.l" + { + DPRINT("PropNodeName: %s\n", yytext); + yylval.propnodename = xstrdup((yytext[0] == '\\') ? +@@ -1146,75 +1155,75 @@ YY_RULE_SETUP + return DT_PROPNODENAME; + } + YY_BREAK +-case 17: ++case 18: + YY_RULE_SETUP +-#line 222 "dtc-lexer.l" ++#line 227 "dtc-lexer.l" + { + DPRINT("Binary Include\n"); + return DT_INCBIN; + } + YY_BREAK +-case 18: +-/* rule 18 can match eol */ +-YY_RULE_SETUP +-#line 227 "dtc-lexer.l" +-/* eat whitespace */ +- YY_BREAK + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP +-#line 228 "dtc-lexer.l" +-/* eat C-style comments */ ++#line 232 "dtc-lexer.l" ++/* eat whitespace */ + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP +-#line 229 "dtc-lexer.l" +-/* eat C++-style comments */ ++#line 233 "dtc-lexer.l" ++/* eat C-style comments */ + YY_BREAK + case 21: ++/* rule 21 can match eol */ + YY_RULE_SETUP +-#line 231 "dtc-lexer.l" +-{ return DT_LSHIFT; }; ++#line 234 "dtc-lexer.l" ++/* eat C++-style comments */ + YY_BREAK + case 22: + YY_RULE_SETUP +-#line 232 "dtc-lexer.l" +-{ return DT_RSHIFT; }; ++#line 236 "dtc-lexer.l" ++{ return DT_LSHIFT; }; + YY_BREAK + case 23: + YY_RULE_SETUP +-#line 233 "dtc-lexer.l" +-{ return DT_LE; }; ++#line 237 "dtc-lexer.l" ++{ return DT_RSHIFT; }; + YY_BREAK + case 24: + YY_RULE_SETUP +-#line 234 "dtc-lexer.l" +-{ return DT_GE; }; ++#line 238 "dtc-lexer.l" ++{ return DT_LE; }; + YY_BREAK + case 25: + YY_RULE_SETUP +-#line 235 "dtc-lexer.l" +-{ return DT_EQ; }; ++#line 239 "dtc-lexer.l" ++{ return DT_GE; }; + YY_BREAK + case 26: + YY_RULE_SETUP +-#line 236 "dtc-lexer.l" +-{ return DT_NE; }; ++#line 240 "dtc-lexer.l" ++{ return DT_EQ; }; + YY_BREAK + case 27: + YY_RULE_SETUP +-#line 237 "dtc-lexer.l" +-{ return DT_AND; }; ++#line 241 "dtc-lexer.l" ++{ return DT_NE; }; + YY_BREAK + case 28: + YY_RULE_SETUP +-#line 238 "dtc-lexer.l" +-{ return DT_OR; }; ++#line 242 "dtc-lexer.l" ++{ return DT_AND; }; + YY_BREAK + case 29: + YY_RULE_SETUP +-#line 240 "dtc-lexer.l" ++#line 243 "dtc-lexer.l" ++{ return DT_OR; }; ++ YY_BREAK ++case 30: ++YY_RULE_SETUP ++#line 245 "dtc-lexer.l" + { + DPRINT("Char: %c (\\x%02x)\n", yytext[0], + (unsigned)yytext[0]); +@@ -1230,12 +1239,12 @@ YY_RULE_SETUP + return yytext[0]; + } + YY_BREAK +-case 30: ++case 31: + YY_RULE_SETUP +-#line 255 "dtc-lexer.l" ++#line 260 "dtc-lexer.l" + ECHO; + YY_BREAK +-#line 1239 "dtc-lexer.lex.c" ++#line 1248 "dtc-lexer.lex.c" + + case YY_END_OF_BUFFER: + { +@@ -1365,7 +1374,6 @@ ECHO; + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +- } /* end of user's declarations */ + } /* end of yylex */ + + /* yy_get_next_buffer - try to read in a new buffer +@@ -1421,21 +1429,21 @@ static int yy_get_next_buffer (void) + + else + { +- yy_size_t num_to_read = ++ int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; ++ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { +- yy_size_t new_size = b->yy_buf_size * 2; ++ int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; +@@ -1466,7 +1474,7 @@ static int yy_get_next_buffer (void) + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), num_to_read ); ++ (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } +@@ -1528,7 +1536,7 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +@@ -1556,13 +1564,13 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 158); ++ yy_is_jam = (yy_current_state == 165); + +- return yy_is_jam ? 0 : yy_current_state; ++ return yy_is_jam ? 0 : yy_current_state; + } + + #ifndef YY_NO_INPUT +@@ -1589,7 +1597,7 @@ static int yy_get_next_buffer (void) + + else + { /* need more input */ +- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++ int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) +@@ -1863,7 +1871,7 @@ void yypop_buffer_state (void) + */ + static void yyensure_buffer_stack (void) + { +- yy_size_t num_to_alloc; ++ int num_to_alloc; + + if (!(yy_buffer_stack)) { + +@@ -1960,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) + * + * @return the newly allocated buffer state object. + */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) ++YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; +- yy_size_t i; ++ int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; +@@ -2047,7 +2055,7 @@ FILE *yyget_out (void) + /** Get the length of the current token. + * + */ +-yy_size_t yyget_leng (void) ++int yyget_leng (void) + { + return yyleng; + } +@@ -2195,7 +2203,7 @@ void yyfree (void * ptr ) + + #define YYTABLES_NAME "yytables" + +-#line 254 "dtc-lexer.l" ++#line 260 "dtc-lexer.l" + + + +diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped +index 116458c..2c1784e 100644 +--- a/scripts/dtc/dtc-parser.tab.c_shipped ++++ b/scripts/dtc/dtc-parser.tab.c_shipped +@@ -1,19 +1,19 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ ++/* A Bison parser, made by GNU Bison 2.5. */ + + /* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- ++ ++ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. ++ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +@@ -26,7 +26,7 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +@@ -44,7 +44,7 @@ + #define YYBISON 1 + + /* Bison version. */ +-#define YYBISON_VERSION "3.0.2" ++#define YYBISON_VERSION "2.5" + + /* Skeleton name. */ + #define YYSKELETON_NAME "yacc.c" +@@ -58,13 +58,18 @@ + /* Pull parsers. */ + #define YYPULL 1 + ++/* Using locations. */ ++#define YYLSP_NEEDED 1 + + + + /* Copy the first part of user declarations. */ +-#line 20 "dtc-parser.y" /* yacc.c:339 */ ++ ++/* Line 268 of yacc.c */ ++#line 20 "dtc-parser.y" + + #include ++#include + + #include "dtc.h" + #include "srcpos.h" +@@ -80,15 +85,14 @@ extern void yyerror(char const *s); + extern struct boot_info *the_boot_info; + extern bool treesource_error; + +-#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ + +-# ifndef YY_NULLPTR +-# if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULLPTR nullptr +-# else +-# define YY_NULLPTR 0 +-# endif +-# endif ++/* Line 268 of yacc.c */ ++#line 91 "dtc-parser.tab.c" ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif + + /* Enabling verbose error messages. */ + #ifdef YYERROR_VERBOSE +@@ -98,53 +102,51 @@ extern bool treesource_error; + # define YYERROR_VERBOSE 0 + #endif + +-/* In a future release of Bison, this section will be replaced +- by #include "dtc-parser.tab.h". */ +-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED +-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; ++/* Enabling the token table. */ ++#ifndef YYTOKEN_TABLE ++# define YYTOKEN_TABLE 0 + #endif + +-/* Token type. */ ++ ++/* Tokens. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- enum yytokentype +- { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BYTE = 274, +- DT_STRING = 275, +- DT_LABEL = 276, +- DT_REF = 277, +- DT_INCBIN = 278 +- }; ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +-/* Value type. */ ++ ++ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE ++typedef union YYSTYPE + { +-#line 38 "dtc-parser.y" /* yacc.c:355 */ ++ ++/* Line 293 of yacc.c */ ++#line 39 "dtc-parser.y" + + char *propnodename; + char *labelref; +@@ -162,37 +164,37 @@ union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + +-#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ +-}; ++ ++ ++/* Line 293 of yacc.c */ ++#line 173 "dtc-parser.tab.c" ++} YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-/* Location type. */ + #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +-typedef struct YYLTYPE YYLTYPE; +-struct YYLTYPE ++typedef struct YYLTYPE + { + int first_line; + int first_column; + int last_line; + int last_column; +-}; ++} YYLTYPE; ++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ + # define YYLTYPE_IS_DECLARED 1 + # define YYLTYPE_IS_TRIVIAL 1 + #endif + + +-extern YYSTYPE yylval; +-extern YYLTYPE yylloc; +-int yyparse (void); +- +-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +- + /* Copy the second part of user declarations. */ + +-#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ ++ ++/* Line 343 of yacc.c */ ++#line 198 "dtc-parser.tab.c" + + #ifdef short + # undef short +@@ -206,8 +208,11 @@ typedef unsigned char yytype_uint8; + + #ifdef YYTYPE_INT8 + typedef YYTYPE_INT8 yytype_int8; +-#else ++#elif (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + typedef signed char yytype_int8; ++#else ++typedef short int yytype_int8; + #endif + + #ifdef YYTYPE_UINT16 +@@ -227,7 +232,8 @@ typedef short int yytype_int16; + # define YYSIZE_T __SIZE_TYPE__ + # elif defined size_t + # define YYSIZE_T size_t +-# elif ! defined YYSIZE_T ++# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + # include /* INFRINGES ON USER NAME SPACE */ + # define YYSIZE_T size_t + # else +@@ -241,68 +247,39 @@ typedef short int yytype_int16; + # if defined YYENABLE_NLS && YYENABLE_NLS + # if ENABLE_NLS + # include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(Msgid) dgettext ("bison-runtime", Msgid) ++# define YY_(msgid) dgettext ("bison-runtime", msgid) + # endif + # endif + # ifndef YY_ +-# define YY_(Msgid) Msgid +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +-#endif +- +-#ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +-#endif +- +-#if !defined _Noreturn \ +- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +-# if defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) ++# define YY_(msgid) msgid + # endif + #endif + + /* Suppress unused-variable warnings by "using" E. */ + #if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) ++# define YYUSE(e) ((void) (e)) + #else +-# define YYUSE(E) /* empty */ ++# define YYUSE(e) /* empty */ + #endif + +-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +-/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +- _Pragma ("GCC diagnostic pop") ++/* Identity function, used to suppress warnings about constant conditions. */ ++#ifndef lint ++# define YYID(n) (n) + #else +-# define YY_INITIAL_VALUE(Value) Value +-#endif +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static int ++YYID (int yyi) ++#else ++static int ++YYID (yyi) ++ int yyi; + #endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ ++{ ++ return yyi; ++} + #endif + +- + #if ! defined yyoverflow || YYERROR_VERBOSE + + /* The parser invokes alloca or malloc; define the necessary symbols. */ +@@ -320,9 +297,9 @@ typedef short int yytype_int16; + # define alloca _alloca + # else + # define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS ++# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + # include /* INFRINGES ON USER NAME SPACE */ +- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ + # ifndef EXIT_SUCCESS + # define EXIT_SUCCESS 0 + # endif +@@ -332,8 +309,8 @@ typedef short int yytype_int16; + # endif + + # ifdef YYSTACK_ALLOC +- /* Pacify GCC's 'empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + # ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely +@@ -349,7 +326,7 @@ typedef short int yytype_int16; + # endif + # if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) ++ && (defined YYFREE || defined free))) + # include /* INFRINGES ON USER NAME SPACE */ + # ifndef EXIT_SUCCESS + # define EXIT_SUCCESS 0 +@@ -357,13 +334,15 @@ typedef short int yytype_int16; + # endif + # ifndef YYMALLOC + # define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS ++# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif + # ifndef YYFREE + # define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS ++# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + void free (void *); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif +@@ -373,8 +352,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ + + #if (! defined yyoverflow \ + && (! defined __cplusplus \ +- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ +- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) ++ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ ++ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + + /* A type that is properly aligned for any stack member. */ + union yyalloc +@@ -400,35 +379,35 @@ union yyalloc + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (0) ++# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ ++ Stack = &yyptr->Stack_alloc; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (YYID (0)) + + #endif + + #if defined YYCOPY_NEEDED && YYCOPY_NEEDED +-/* Copy COUNT objects from SRC to DST. The source and destination do ++/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ + # ifndef YYCOPY + # if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) + # else +-# define YYCOPY(Dst, Src, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (Dst)[yyi] = (Src)[yyi]; \ +- } \ +- while (0) ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (YYID (0)) + # endif + # endif + #endif /* !YYCOPY_NEEDED */ +@@ -439,39 +418,37 @@ union yyalloc + #define YYLAST 136 + + /* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 47 ++#define YYNTOKENS 48 + /* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 28 ++#define YYNNTS 29 + /* YYNRULES -- Number of rules. */ +-#define YYNRULES 80 +-/* YYNSTATES -- Number of states. */ +-#define YYNSTATES 144 ++#define YYNRULES 82 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 147 + +-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +- by yylex, with out-of-bounds checking. */ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + #define YYUNDEFTOK 2 +-#define YYMAXUTOK 278 ++#define YYMAXUTOK 279 + +-#define YYTRANSLATE(YYX) \ ++#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +- as returned by yylex, without out-of-bounds checking. */ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ + static const yytype_uint8 yytranslate[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, +- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, +- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, ++ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, ++ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, ++ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, ++ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +@@ -486,292 +463,335 @@ static const yytype_uint8 yytranslate[] = + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23 ++ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 + }; + + #if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const yytype_uint16 yyprhs[] = ++{ ++ 0, 0, 3, 9, 10, 13, 14, 17, 22, 25, ++ 28, 32, 37, 41, 46, 52, 53, 56, 61, 64, ++ 68, 71, 74, 78, 83, 86, 96, 102, 105, 106, ++ 109, 112, 116, 118, 121, 124, 127, 129, 131, 135, ++ 137, 139, 145, 147, 151, 153, 157, 159, 163, 165, ++ 169, 171, 175, 177, 181, 185, 187, 191, 195, 199, ++ 203, 207, 211, 213, 217, 221, 223, 227, 231, 235, ++ 237, 239, 242, 245, 248, 249, 252, 255, 256, 259, ++ 262, 265, 269 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const yytype_int8 yyrhs[] = ++{ ++ 49, 0, -1, 3, 25, 50, 51, 53, -1, -1, ++ 4, 25, -1, -1, 52, 51, -1, 5, 60, 60, ++ 25, -1, 22, 52, -1, 26, 54, -1, 53, 26, ++ 54, -1, 53, 22, 23, 54, -1, 53, 23, 54, ++ -1, 53, 16, 23, 25, -1, 27, 55, 75, 28, ++ 25, -1, -1, 55, 56, -1, 17, 29, 57, 25, ++ -1, 17, 25, -1, 15, 17, 25, -1, 22, 56, ++ -1, 58, 21, -1, 58, 59, 30, -1, 58, 31, ++ 74, 32, -1, 58, 23, -1, 58, 24, 33, 21, ++ 34, 60, 34, 60, 35, -1, 58, 24, 33, 21, ++ 35, -1, 57, 22, -1, -1, 57, 34, -1, 58, ++ 22, -1, 14, 18, 36, -1, 36, -1, 59, 60, ++ -1, 59, 23, -1, 59, 22, -1, 18, -1, 19, ++ -1, 33, 61, 35, -1, 62, -1, 63, -1, 63, ++ 37, 61, 38, 62, -1, 64, -1, 63, 13, 64, ++ -1, 65, -1, 64, 12, 65, -1, 66, -1, 65, ++ 39, 66, -1, 67, -1, 66, 40, 67, -1, 68, ++ -1, 67, 41, 68, -1, 69, -1, 68, 10, 69, ++ -1, 68, 11, 69, -1, 70, -1, 69, 36, 70, ++ -1, 69, 30, 70, -1, 69, 8, 70, -1, 69, ++ 9, 70, -1, 70, 6, 71, -1, 70, 7, 71, ++ -1, 71, -1, 71, 42, 72, -1, 71, 43, 72, ++ -1, 72, -1, 72, 44, 73, -1, 72, 26, 73, ++ -1, 72, 45, 73, -1, 73, -1, 60, -1, 43, ++ 73, -1, 46, 73, -1, 47, 73, -1, -1, 74, ++ 20, -1, 74, 22, -1, -1, 76, 75, -1, 76, ++ 56, -1, 17, 54, -1, 16, 17, 25, -1, 22, ++ 76, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + static const yytype_uint16 yyrline[] = + { +- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, +- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, +- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, +- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, +- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, +- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, +- 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, +- 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, +- 465 ++ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, ++ 156, 161, 172, 182, 197, 205, 208, 215, 219, 223, ++ 227, 235, 239, 243, 247, 251, 267, 277, 285, 288, ++ 292, 299, 315, 320, 339, 353, 360, 361, 362, 369, ++ 373, 374, 378, 379, 383, 384, 388, 389, 393, 394, ++ 398, 399, 403, 404, 405, 409, 410, 411, 412, 413, ++ 417, 418, 419, 423, 424, 425, 429, 430, 431, 432, ++ 436, 437, 438, 439, 444, 447, 451, 459, 462, 466, ++ 474, 478, 482 + }; + #endif + +-#if YYDEBUG || YYERROR_VERBOSE || 0 ++#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ + static const char *const yytname[] = + { +- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", +- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", +- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", +- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", +- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", +- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", +- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", +- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", +- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", +- "integer_expr", "integer_trinary", "integer_or", "integer_and", +- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", +- "integer_rela", "integer_shift", "integer_add", "integer_mul", +- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR ++ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", ++ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", ++ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", ++ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", ++ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", ++ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", ++ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", ++ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", ++ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", ++ "integer_prim", "integer_expr", "integer_trinary", "integer_or", ++ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", ++ "integer_eq", "integer_rela", "integer_shift", "integer_add", ++ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", 0 + }; + #endif + + # ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ + static const yytype_uint16 yytoknum[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, +- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, +- 38, 43, 45, 42, 37, 126, 33 ++ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, ++ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, ++ 94, 38, 43, 45, 42, 37, 126, 33 + }; + # endif + +-#define YYPACT_NINF -81 +- +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-81))) +- +-#define YYTABLE_NINF -1 +- +-#define yytable_value_is_error(Yytable_value) \ +- 0 +- +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-static const yytype_int8 yypact[] = ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const yytype_uint8 yyr1[] = + { +- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, +- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, +- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, +- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, +- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, +- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, +- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, +- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, +- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, +- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, +- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, +- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, +- 74, 25, 75, -81 ++ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, ++ 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, ++ 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, ++ 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, ++ 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, ++ 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, ++ 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, ++ 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, ++ 76, 76, 76 + }; + +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const yytype_uint8 yyr2[] = + { +- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, +- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, +- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, +- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, +- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, +- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, +- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, +- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, +- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, +- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, +- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, +- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, +- 0, 0, 0, 23 ++ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, ++ 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, ++ 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, ++ 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, ++ 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, ++ 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, ++ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, ++ 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, ++ 2, 3, 2 + }; + +- /* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = ++/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. ++ Performed when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const yytype_uint8 yydefact[] = + { +- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, +- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, +- 37, 27, 34, 38, -14, -81, 22, 24 ++ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, ++ 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, ++ 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, ++ 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, ++ 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, ++ 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, ++ 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, ++ 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, ++ 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, ++ 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, ++ 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, ++ 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, ++ 23, 0, 26, 0, 0, 0, 25 + }; + +- /* YYDEFGOTO[NTERM-NUM]. */ ++/* YYDEFGOTO[NTERM-NUM]. */ + static const yytype_int16 yydefgoto[] = + { +- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, +- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 128, 94, 95 ++ -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, ++ 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, ++ 31, 32, 33, 34, 35, 36, 131, 97, 98 + }; + +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-static const yytype_uint8 yytable[] = ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -84 ++static const yytype_int8 yypact[] = + { +- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, +- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, +- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, +- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, +- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, +- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, +- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, +- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, +- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, +- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, +- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, +- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, +- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, +- 0, 0, 75, 140, 0, 0, 142 ++ 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, ++ 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, ++ -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, ++ 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, ++ 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, ++ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, ++ -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, ++ 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, ++ 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, ++ -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, ++ -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, ++ -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, ++ -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, ++ 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, ++ -84, 24, -84, 77, 24, 80, -84 + }; + +-static const yytype_int16 yycheck[] = ++/* YYPGOTO[NTERM-NUM]. */ ++static const yytype_int8 yypgoto[] = + { +- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, +- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, +- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, +- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, +- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, +- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, +- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, +- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, +- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, +- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, +- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, +- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, +- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, +- -1, -1, 50, 138, -1, -1, 141 ++ -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, ++ -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, ++ 82, 29, 18, 25, 26, -17, -84, 20, 28 + }; + +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -1 ++static const yytype_uint8 yytable[] = + { +- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, +- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, +- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, +- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, +- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, +- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, +- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, +- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, +- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, +- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, +- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, +- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, +- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, +- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, +- 58, 33, 58, 34 ++ 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, ++ 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, ++ 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, ++ 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, ++ 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, ++ 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, ++ 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, ++ 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, ++ 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, ++ 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, ++ 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, ++ 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, ++ 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 143, 0, 78, 145 + }; + +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = ++#define yypact_value_is_default(yystate) \ ++ ((yystate) == (-84)) ++ ++#define yytable_value_is_error(yytable_value) \ ++ YYID (0) ++ ++static const yytype_int16 yycheck[] = + { +- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, +- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, +- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, +- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, +- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, +- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, +- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, +- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, +- 74 ++ 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, ++ 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, ++ 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, ++ 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, ++ 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, ++ 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, ++ 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, ++ 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, ++ 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, ++ 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, ++ 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, ++ 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, ++ 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, 141, -1, 53, 144 + }; + +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const yytype_uint8 yystos[] = + { +- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, +- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, +- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, +- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, +- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, +- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, +- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, +- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, +- 2 ++ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, ++ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, ++ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, ++ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, ++ 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, ++ 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, ++ 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, ++ 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, ++ 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, ++ 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, ++ 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, ++ 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, ++ 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, ++ 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, ++ 32, 34, 35, 60, 34, 60, 35 + }; + +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. However, ++ YYFAIL appears to be in use. Nevertheless, it is formally deprecated ++ in Bison 2.4.2's NEWS entry, where a plan to phase it out is ++ discussed. */ ++ ++#define YYFAIL goto yyerrlab ++#if defined YYFAIL ++ /* This is here to suppress warnings from the GCC cpp's ++ -Wunused-macros. Normally we don't worry about that warning, but ++ some users do, and we want to make it easy for users to remove ++ YYFAIL uses, which will produce warnings from Bison 2.5. */ ++#endif + + #define YYRECOVERING() (!!yyerrstatus) + +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- YYPOPSTACK (yylen); \ +- yystate = *yyssp; \ +- goto yybackup; \ +- } \ +- else \ +- { \ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ YYPOPSTACK (1); \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ + yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (0) ++ YYERROR; \ ++ } \ ++while (YYID (0)) ++ + +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 ++#define YYTERROR 1 ++#define YYERRCODE 256 + + + /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + ++#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + #ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (N) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (0) ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ do \ ++ if (YYID (N)) \ ++ { \ ++ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ ++ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ ++ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ ++ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ ++ } \ ++ else \ ++ { \ ++ (Current).first_line = (Current).last_line = \ ++ YYRHSLOC (Rhs, 0).last_line; \ ++ (Current).first_column = (Current).last_column = \ ++ YYRHSLOC (Rhs, 0).last_column; \ ++ } \ ++ while (YYID (0)) + #endif + +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +- +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (0) +- + + /* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know +@@ -779,73 +799,82 @@ do { \ + + #ifndef YY_LOCATION_PRINT + # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++# define YY_LOCATION_PRINT(File, Loc) \ ++ fprintf (File, "%d.%d-%d.%d", \ ++ (Loc).first_line, (Loc).first_column, \ ++ (Loc).last_line, (Loc).last_column) ++# else ++# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++# endif ++#endif + +-/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +-YY_ATTRIBUTE_UNUSED +-static unsigned +-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +-{ +- unsigned res = 0; +- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; +- if (0 <= yylocp->first_line) +- { +- res += YYFPRINTF (yyo, "%d", yylocp->first_line); +- if (0 <= yylocp->first_column) +- res += YYFPRINTF (yyo, ".%d", yylocp->first_column); +- } +- if (0 <= yylocp->last_line) +- { +- if (yylocp->first_line < yylocp->last_line) +- { +- res += YYFPRINTF (yyo, "-%d", yylocp->last_line); +- if (0 <= end_col) +- res += YYFPRINTF (yyo, ".%d", end_col); +- } +- else if (0 <= end_col && yylocp->first_column < end_col) +- res += YYFPRINTF (yyo, "-%d", end_col); +- } +- return res; +- } ++/* YYLEX -- calling `yylex' with the right arguments. */ + +-# define YY_LOCATION_PRINT(File, Loc) \ +- yy_location_print_ (File, &(Loc)) ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (YYLEX_PARAM) ++#else ++# define YYLEX yylex () ++#endif + +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf + # endif +-#endif + ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (YYID (0)) + +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value, Location); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yy_symbol_print (stderr, \ ++ Type, Value, Location); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (YYID (0)) + + +-/*----------------------------------------. +-| Print this symbol's value on YYOUTPUT. | +-`----------------------------------------*/ ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ + ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) ++#else ++static void ++yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ YYLTYPE const * const yylocationp; ++#endif + { +- FILE *yyo = yyoutput; +- YYUSE (yyo); +- YYUSE (yylocationp); + if (!yyvaluep) + return; ++ YYUSE (yylocationp); + # ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# else ++ YYUSE (yyoutput); + # endif +- YYUSE (yytype); ++ switch (yytype) ++ { ++ default: ++ break; ++ } + } + + +@@ -853,11 +882,23 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) ++#else ++static void ++yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ YYLTYPE const * const yylocationp; ++#endif + { +- YYFPRINTF (yyoutput, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); ++ if (yytype < YYNTOKENS) ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); +@@ -870,8 +911,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL + | TOP (included). | + `------------------------------------------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) ++#else ++static void ++yy_stack_print (yybottom, yytop) ++ yytype_int16 *yybottom; ++ yytype_int16 *yytop; ++#endif + { + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) +@@ -882,42 +931,50 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) + YYFPRINTF (stderr, "\n"); + } + +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (0) ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (YYID (0)) + + + /*------------------------------------------------. + | Report that the YYRULE is going to be reduced. | + `------------------------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static void ++yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) ++#else + static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) ++yy_reduce_print (yyvsp, yylsp, yyrule) ++ YYSTYPE *yyvsp; ++ YYLTYPE *yylsp; ++ int yyrule; ++#endif + { +- unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; ++ unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); ++ yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- , &(yylsp[(yyi + 1) - (yynrhs)]) ); ++ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], ++ &(yyvsp[(yyi + 1) - (yynrhs)]) ++ , &(yylsp[(yyi + 1) - (yynrhs)]) ); + YYFPRINTF (stderr, "\n"); + } + } + +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ +-} while (0) ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (yyvsp, yylsp, Rule); \ ++} while (YYID (0)) + + /* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +@@ -931,7 +988,7 @@ int yydebug; + + + /* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH ++#ifndef YYINITDEPTH + # define YYINITDEPTH 200 + #endif + +@@ -954,8 +1011,15 @@ int yydebug; + # define yystrlen strlen + # else + /* Return the length of YYSTR. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static YYSIZE_T + yystrlen (const char *yystr) ++#else ++static YYSIZE_T ++yystrlen (yystr) ++ const char *yystr; ++#endif + { + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) +@@ -971,8 +1035,16 @@ yystrlen (const char *yystr) + # else + /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static char * + yystpcpy (char *yydest, const char *yysrc) ++#else ++static char * ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++#endif + { + char *yyd = yydest; + const char *yys = yysrc; +@@ -1002,27 +1074,27 @@ yytnamerr (char *yyres, const char *yystr) + char const *yyp = yystr; + + for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } ++ switch (*++yyp) ++ { ++ case '\'': ++ case ',': ++ goto do_not_strip_quotes; ++ ++ case '\\': ++ if (*++yyp != '\\') ++ goto do_not_strip_quotes; ++ /* Fall through. */ ++ default: ++ if (yyres) ++ yyres[yyn] = *yyp; ++ yyn++; ++ break; ++ ++ case '"': ++ if (yyres) ++ yyres[yyn] = '\0'; ++ return yyn; ++ } + do_not_strip_quotes: ; + } + +@@ -1045,11 +1117,12 @@ static int + yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) + { +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); ++ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize = yysize0; ++ YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; ++ const char *yyformat = 0; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per +@@ -1057,6 +1130,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + int yycount = 0; + + /* There are many possibilities here to consider: ++ - Assume YYFAIL is not used. It's too flawed to consider. See ++ ++ for details. YYERROR is fine as it does not invoke this ++ function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected +@@ -1105,13 +1182,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + break; + } + yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (! (yysize <= yysize1 +- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } ++ yysize1 = yysize + yytnamerr (0, yytname[yyx]); ++ if (! (yysize <= yysize1 ++ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) ++ return 2; ++ yysize = yysize1; + } + } + } +@@ -1131,12 +1206,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + # undef YYCASE_ + } + +- { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } ++ yysize1 = yysize + yystrlen (yyformat); ++ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) ++ return 2; ++ yysize = yysize1; + + if (*yymsg_alloc < yysize) + { +@@ -1173,21 +1246,50 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + | Release the memory associated to this symbol. | + `-----------------------------------------------*/ + ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) ++#else ++static void ++yydestruct (yymsg, yytype, yyvaluep, yylocationp) ++ const char *yymsg; ++ int yytype; ++ YYSTYPE *yyvaluep; ++ YYLTYPE *yylocationp; ++#endif + { + YYUSE (yyvaluep); + YYUSE (yylocationp); ++ + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- YYUSE (yytype); +- YY_IGNORE_MAYBE_UNINITIALIZED_END ++ switch (yytype) ++ { ++ ++ default: ++ break; ++ } + } + + ++/* Prevent warnings from -Wmissing-prototypes. */ ++#ifdef YYPARSE_PARAM ++#if defined __STDC__ || defined __cplusplus ++int yyparse (void *YYPARSE_PARAM); ++#else ++int yyparse (); ++#endif ++#else /* ! YYPARSE_PARAM */ ++#if defined __STDC__ || defined __cplusplus ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ + + + /* The lookahead symbol. */ +@@ -1195,12 +1297,10 @@ int yychar; + + /* The semantic value of the lookahead symbol. */ + YYSTYPE yylval; ++ + /* Location data for the lookahead symbol. */ +-YYLTYPE yylloc +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +- = { 1, 1, 1, 1 } +-# endif +-; ++YYLTYPE yylloc; ++ + /* Number of syntax errors so far. */ + int yynerrs; + +@@ -1209,19 +1309,38 @@ int yynerrs; + | yyparse. | + `----------*/ + ++#ifdef YYPARSE_PARAM ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++int ++yyparse (void *YYPARSE_PARAM) ++#else ++int ++yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++#endif ++#else /* ! YYPARSE_PARAM */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + int + yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif + { + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- 'yyls': related to locations. ++ `yyss': related to states. ++ `yyvs': related to semantic values. ++ `yyls': related to locations. + +- Refer to the stacks through separate pointers, to allow yyoverflow ++ Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ +@@ -1247,7 +1366,7 @@ yyparse (void) + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; ++ int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; +@@ -1266,9 +1385,10 @@ yyparse (void) + Keep to zero when no symbol should be popped. */ + int yylen = 0; + +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yylsp = yyls = yylsa; ++ yytoken = 0; ++ yyss = yyssa; ++ yyvs = yyvsa; ++ yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); +@@ -1277,7 +1397,21 @@ yyparse (void) + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ +- yylsp[0] = yylloc; ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ yylsp = yyls; ++ ++#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++ /* Initialize the default location before parsing starts. */ ++ yylloc.first_line = yylloc.last_line = 1; ++ yylloc.first_column = yylloc.last_column = 1; ++#endif ++ + goto yysetstate; + + /*------------------------------------------------------------. +@@ -1298,26 +1432,26 @@ yyparse (void) + + #ifdef yyoverflow + { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- YYLTYPE *yyls1 = yyls; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yyls1, yysize * sizeof (*yylsp), +- &yystacksize); +- +- yyls = yyls1; +- yyss = yyss1; +- yyvs = yyvs1; ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ yytype_int16 *yyss1 = yyss; ++ YYLTYPE *yyls1 = yyls; ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow (YY_("memory exhausted"), ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ &yyls1, yysize * sizeof (*yylsp), ++ &yystacksize); ++ ++ yyls = yyls1; ++ yyss = yyss1; ++ yyvs = yyvs1; + } + #else /* no yyoverflow */ + # ifndef YYSTACK_RELOCATE +@@ -1325,23 +1459,23 @@ yyparse (void) + # else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; ++ goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; ++ yystacksize = YYMAXDEPTH; + + { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); +- YYSTACK_RELOCATE (yyls_alloc, yyls); ++ yytype_int16 *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyexhaustedlab; ++ YYSTACK_RELOCATE (yyss_alloc, yyss); ++ YYSTACK_RELOCATE (yyvs_alloc, yyvs); ++ YYSTACK_RELOCATE (yyls_alloc, yyls); + # undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); + } + # endif + #endif /* no yyoverflow */ +@@ -1351,10 +1485,10 @@ yyparse (void) + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); ++ (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; ++ YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +@@ -1383,7 +1517,7 @@ yybackup: + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = yylex (); ++ yychar = YYLEX; + } + + if (yychar <= YYEOF) +@@ -1423,9 +1557,7 @@ yybackup: + yychar = YYEMPTY; + + yystate = yyn; +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END + *++yylsp = yylloc; + goto yynewstate; + +@@ -1448,7 +1580,7 @@ yyreduce: + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: +- '$$ = $1'. ++ `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison +@@ -1463,273 +1595,322 @@ yyreduce: + switch (yyn) + { + case 2: +-#line 105 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 109 "dtc-parser.y" + { +- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), +- guess_boot_cpuid((yyvsp[0].node))); ++ (yyvsp[(5) - (5)].node)->is_plugin = (yyvsp[(3) - (5)].is_plugin); ++ (yyvsp[(5) - (5)].node)->is_root = 1; ++ the_boot_info = build_boot_info((yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), ++ guess_boot_cpuid((yyvsp[(5) - (5)].node))); + } +-#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 3: +-#line 113 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 119 "dtc-parser.y" + { +- (yyval.re) = NULL; ++ (yyval.is_plugin) = 0; + } +-#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 4: +-#line 117 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 123 "dtc-parser.y" + { +- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); ++ (yyval.is_plugin) = 1; + } +-#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 5: +-#line 124 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 130 "dtc-parser.y" + { +- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); ++ (yyval.re) = NULL; + } +-#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 6: +-#line 128 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 134 "dtc-parser.y" + { +- add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); +- (yyval.re) = (yyvsp[0].re); ++ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); + } +-#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 7: +-#line 136 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 141 "dtc-parser.y" + { +- (yyval.node) = name_node((yyvsp[0].node), ""); ++ (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); + } +-#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 8: +-#line 140 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 145 "dtc-parser.y" + { +- (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); ++ add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.re) = (yyvsp[(2) - (2)].re); + } +-#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 9: +-#line 145 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); + +- add_label(&target->labels, (yyvsp[-2].labelref)); +- if (target) +- merge_nodes(target, (yyvsp[0].node)); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[-3].node); ++/* Line 1806 of yacc.c */ ++#line 153 "dtc-parser.y" ++ { ++ (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); + } +-#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 10: +-#line 156 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); + +- if (target) +- merge_nodes(target, (yyvsp[0].node)); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[-2].node); ++/* Line 1806 of yacc.c */ ++#line 157 "dtc-parser.y" ++ { ++ (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } +-#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 11: +-#line 166 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 162 "dtc-parser.y" + { +- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); ++ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); + ++ add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); + if (target) +- delete_node(target); ++ merge_nodes(target, (yyvsp[(4) - (4)].node)); + else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- +- +- (yyval.node) = (yyvsp[-3].node); ++ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); ++ (yyval.node) = (yyvsp[(1) - (4)].node); + } +-#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 12: +-#line 181 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 173 "dtc-parser.y" + { +- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); ++ struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); ++ ++ if (target) ++ merge_nodes(target, (yyvsp[(3) - (3)].node)); ++ else ++ ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); ++ (yyval.node) = (yyvsp[(1) - (3)].node); + } +-#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 13: +-#line 188 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 183 "dtc-parser.y" + { +- (yyval.proplist) = NULL; ++ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); ++ ++ if (target) ++ delete_node(target); ++ else ++ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); ++ ++ ++ (yyval.node) = (yyvsp[(1) - (4)].node); + } +-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 14: +-#line 192 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 198 "dtc-parser.y" + { +- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); ++ (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); + } +-#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 15: +-#line 199 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 205 "dtc-parser.y" + { +- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); ++ (yyval.proplist) = NULL; + } +-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 16: +-#line 203 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 209 "dtc-parser.y" + { +- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); ++ (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); + } +-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 17: +-#line 207 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 216 "dtc-parser.y" + { +- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); ++ (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); + } +-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 18: +-#line 211 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 220 "dtc-parser.y" + { +- add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); +- (yyval.prop) = (yyvsp[0].prop); ++ (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); + } +-#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 19: +-#line 219 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 224 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); ++ (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); + } +-#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 20: +-#line 223 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 228 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); ++ add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.prop) = (yyvsp[(2) - (2)].prop); + } +-#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 21: +-#line 227 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 236 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); ++ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); + } +-#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 22: +-#line 231 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 240 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); ++ (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); + } +-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 23: +-#line 235 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 244 "dtc-parser.y" + { +- FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); ++ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ++ } ++ break; ++ ++ case 24: ++ ++/* Line 1806 of yacc.c */ ++#line 248 "dtc-parser.y" ++ { ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); ++ } ++ break; ++ ++ case 25: ++ ++/* Line 1806 of yacc.c */ ++#line 252 "dtc-parser.y" ++ { ++ FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); + struct data d; + +- if ((yyvsp[-3].integer) != 0) +- if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) ++ if ((yyvsp[(6) - (9)].integer) != 0) ++ if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) + die("Couldn't seek to offset %llu in \"%s\": %s", +- (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, ++ (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, + strerror(errno)); + +- d = data_copy_file(f, (yyvsp[-1].integer)); ++ d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); + +- (yyval.data) = data_merge((yyvsp[-8].data), d); ++ (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); + fclose(f); + } +-#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 24: +-#line 251 "dtc-parser.y" /* yacc.c:1646 */ ++ case 26: ++ ++/* Line 1806 of yacc.c */ ++#line 268 "dtc-parser.y" + { +- FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); ++ FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); + struct data d = empty_data; + + d = data_copy_file(f, -1); + +- (yyval.data) = data_merge((yyvsp[-4].data), d); ++ (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); + fclose(f); + } +-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 25: +-#line 261 "dtc-parser.y" /* yacc.c:1646 */ ++ case 27: ++ ++/* Line 1806 of yacc.c */ ++#line 278 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 26: +-#line 268 "dtc-parser.y" /* yacc.c:1646 */ ++ case 28: ++ ++/* Line 1806 of yacc.c */ ++#line 285 "dtc-parser.y" + { + (yyval.data) = empty_data; + } +-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 27: +-#line 272 "dtc-parser.y" /* yacc.c:1646 */ ++ case 29: ++ ++/* Line 1806 of yacc.c */ ++#line 289 "dtc-parser.y" + { +- (yyval.data) = (yyvsp[-1].data); ++ (yyval.data) = (yyvsp[(1) - (2)].data); + } +-#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 28: +-#line 276 "dtc-parser.y" /* yacc.c:1646 */ ++ case 30: ++ ++/* Line 1806 of yacc.c */ ++#line 293 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 29: +-#line 283 "dtc-parser.y" /* yacc.c:1646 */ ++ case 31: ++ ++/* Line 1806 of yacc.c */ ++#line 300 "dtc-parser.y" + { + unsigned long long bits; + +- bits = (yyvsp[-1].integer); ++ bits = (yyvsp[(2) - (3)].integer); + + if ((bits != 8) && (bits != 16) && + (bits != 32) && (bits != 64)) { +- ERROR(&(yylsp[-1]), "Array elements must be" ++ ERROR(&(yylsp[(2) - (3)]), "Array elements must be" + " 8, 16, 32 or 64-bits"); + bits = 32; + } +@@ -1737,23 +1918,25 @@ yyreduce: + (yyval.array).data = empty_data; + (yyval.array).bits = bits; + } +-#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 30: +-#line 299 "dtc-parser.y" /* yacc.c:1646 */ ++ case 32: ++ ++/* Line 1806 of yacc.c */ ++#line 316 "dtc-parser.y" + { + (yyval.array).data = empty_data; + (yyval.array).bits = 32; + } +-#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 31: +-#line 304 "dtc-parser.y" /* yacc.c:1646 */ ++ case 33: ++ ++/* Line 1806 of yacc.c */ ++#line 321 "dtc-parser.y" + { +- if ((yyvsp[-1].array).bits < 64) { +- uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; ++ if ((yyvsp[(1) - (2)].array).bits < 64) { ++ uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; + /* + * Bits above mask must either be all zero + * (positive within range of mask) or all one +@@ -1762,258 +1945,293 @@ yyreduce: + * within the mask to one (i.e. | in the + * mask), all bits are one. + */ +- if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) +- ERROR(&(yylsp[0]), "Value out of range for" +- " %d-bit array element", (yyvsp[-1].array).bits); ++ if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) ++ ERROR(&(yylsp[(2) - (2)]), "Value out of range for" ++ " %d-bit array element", (yyvsp[(1) - (2)].array).bits); + } + +- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); ++ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); + } +-#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 32: +-#line 323 "dtc-parser.y" /* yacc.c:1646 */ ++ case 34: ++ ++/* Line 1806 of yacc.c */ ++#line 340 "dtc-parser.y" + { +- uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); ++ uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); + +- if ((yyvsp[-1].array).bits == 32) +- (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, ++ if ((yyvsp[(1) - (2)].array).bits == 32) ++ (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, + REF_PHANDLE, +- (yyvsp[0].labelref)); ++ (yyvsp[(2) - (2)].labelref)); + else +- ERROR(&(yylsp[0]), "References are only allowed in " ++ ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " + "arrays with 32-bit elements."); + +- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); ++ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); + } +-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 33: +-#line 337 "dtc-parser.y" /* yacc.c:1646 */ ++ case 35: ++ ++/* Line 1806 of yacc.c */ ++#line 354 "dtc-parser.y" + { +- (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); ++ (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 36: +-#line 346 "dtc-parser.y" /* yacc.c:1646 */ ++ case 38: ++ ++/* Line 1806 of yacc.c */ ++#line 363 "dtc-parser.y" + { +- (yyval.integer) = (yyvsp[-1].integer); ++ (yyval.integer) = (yyvsp[(2) - (3)].integer); + } +-#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; +- +- case 39: +-#line 357 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } +-#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 41: +-#line 362 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } +-#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 374 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } + break; + + case 43: +-#line 367 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } +-#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 379 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } + break; + + case 45: +-#line 372 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } +-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 384 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } + break; + + case 47: +-#line 377 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } +-#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 389 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } + break; + + case 49: +-#line 382 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } +-#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 394 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } + break; + + case 51: +-#line 387 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } +-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 399 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } + break; + +- case 52: +-#line 388 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } +-#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 53: ++ ++/* Line 1806 of yacc.c */ ++#line 404 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } + break; + + case 54: +-#line 393 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } +-#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; + +- case 55: +-#line 394 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } +-#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1806 of yacc.c */ ++#line 405 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } + break; + + case 56: +-#line 395 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } +-#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 410 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } + break; + + case 57: +-#line 396 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } +-#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 411 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } + break; + + case 58: +-#line 400 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } +-#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 412 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } + break; + + case 59: +-#line 401 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } +-#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 413 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } ++ break; ++ ++ case 60: ++ ++/* Line 1806 of yacc.c */ ++#line 417 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } + break; + + case 61: +-#line 406 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } +-#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 418 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } + break; + +- case 62: +-#line 407 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } +-#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 63: ++ ++/* Line 1806 of yacc.c */ ++#line 423 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } + break; + + case 64: +-#line 412 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } +-#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; + +- case 65: +-#line 413 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } +-#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1806 of yacc.c */ ++#line 424 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } + break; + + case 66: +-#line 414 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } +-#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 429 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } + break; + +- case 69: +-#line 420 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = -(yyvsp[0].integer); } +-#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 67: ++ ++/* Line 1806 of yacc.c */ ++#line 430 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } + break; + +- case 70: +-#line 421 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = ~(yyvsp[0].integer); } +-#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 68: ++ ++/* Line 1806 of yacc.c */ ++#line 431 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } + break; + + case 71: +-#line 422 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = !(yyvsp[0].integer); } +-#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 437 "dtc-parser.y" ++ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } + break; + + case 72: +-#line 427 "dtc-parser.y" /* yacc.c:1646 */ +- { +- (yyval.data) = empty_data; +- } +-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 438 "dtc-parser.y" ++ { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } + break; + + case 73: +-#line 431 "dtc-parser.y" /* yacc.c:1646 */ +- { +- (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); +- } +-#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 439 "dtc-parser.y" ++ { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } + break; + + case 74: +-#line 435 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 444 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); ++ (yyval.data) = empty_data; + } +-#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 75: +-#line 442 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 448 "dtc-parser.y" + { +- (yyval.nodelist) = NULL; ++ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); + } +-#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 76: +-#line 446 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 452 "dtc-parser.y" + { +- (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); + } +-#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 77: +-#line 450 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 459 "dtc-parser.y" + { +- ERROR(&(yylsp[0]), "Properties must precede subnodes"); +- YYERROR; ++ (yyval.nodelist) = NULL; + } +-#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 78: +-#line 458 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 463 "dtc-parser.y" + { +- (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); ++ (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); + } +-#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 79: +-#line 462 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 467 "dtc-parser.y" + { +- (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); ++ ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); ++ YYERROR; + } +-#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 80: +-#line 466 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1806 of yacc.c */ ++#line 475 "dtc-parser.y" + { +- add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[0].node); ++ (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); + } +-#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + ++ case 81: + +-#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1806 of yacc.c */ ++#line 479 "dtc-parser.y" ++ { ++ (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); ++ } ++ break; ++ ++ case 82: ++ ++/* Line 1806 of yacc.c */ ++#line 483 "dtc-parser.y" ++ { ++ add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.node) = (yyvsp[(2) - (2)].node); ++ } ++ break; ++ ++ ++ ++/* Line 1806 of yacc.c */ ++#line 2235 "dtc-parser.tab.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -2036,7 +2254,7 @@ yyreduce: + *++yyvsp = yyval; + *++yylsp = yyloc; + +- /* Now 'shift' the result of the reduction. Determine what state ++ /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + +@@ -2051,9 +2269,9 @@ yyreduce: + goto yynewstate; + + +-/*--------------------------------------. +-| yyerrlab -- here on detecting error. | +-`--------------------------------------*/ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ + yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ +@@ -2104,20 +2322,20 @@ yyerrlab: + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ ++ error, discard it. */ + + if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } ++ { ++ /* Return failure if at end of input. */ ++ if (yychar == YYEOF) ++ YYABORT; ++ } + else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval, &yylloc); +- yychar = YYEMPTY; +- } ++ { ++ yydestruct ("Error: discarding", ++ yytoken, &yylval, &yylloc); ++ yychar = YYEMPTY; ++ } + } + + /* Else will try to reuse lookahead token after shifting the error +@@ -2137,7 +2355,7 @@ yyerrorlab: + goto yyerrorlab; + + yyerror_range[1] = yylsp[1-yylen]; +- /* Do not reclaim the symbols of the rule whose action triggered ++ /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; +@@ -2150,37 +2368,35 @@ yyerrorlab: + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) +- YYABORT; ++ YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", +- yystos[yystate], yyvsp, yylsp); ++ yystos[yystate], yyvsp, yylsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END + + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of +@@ -2209,7 +2425,7 @@ yyabortlab: + yyresult = 1; + goto yyreturn; + +-#if !defined yyoverflow || YYERROR_VERBOSE ++#if !defined(yyoverflow) || YYERROR_VERBOSE + /*-------------------------------------------------. + | yyexhaustedlab -- memory exhaustion comes here. | + `-------------------------------------------------*/ +@@ -2228,14 +2444,14 @@ yyreturn: + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc); + } +- /* Do not reclaim the symbols of the rule whose action triggered ++ /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp, yylsp); ++ yystos[*yyssp], yyvsp, yylsp); + YYPOPSTACK (1); + } + #ifndef yyoverflow +@@ -2246,12 +2462,18 @@ yyreturn: + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + #endif +- return yyresult; ++ /* Make sure YYID is used. */ ++ return YYID (yyresult); + } +-#line 472 "dtc-parser.y" /* yacc.c:1906 */ ++ ++ ++ ++/* Line 2067 of yacc.c */ ++#line 489 "dtc-parser.y" + + + void yyerror(char const *s) + { + ERROR(&yylloc, "%s", s); + } ++ +diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped +index 30867c6..0b22bbb 100644 +--- a/scripts/dtc/dtc-parser.tab.h_shipped ++++ b/scripts/dtc/dtc-parser.tab.h_shipped +@@ -1,19 +1,19 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ ++/* A Bison parser, made by GNU Bison 2.5. */ + + /* Bison interface for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- ++ ++ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. ++ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +@@ -26,55 +26,50 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED +-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif + +-/* Token type. */ ++/* Tokens. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- enum yytokentype +- { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BYTE = 274, +- DT_STRING = 275, +- DT_LABEL = 276, +- DT_REF = 277, +- DT_INCBIN = 278 +- }; ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +-/* Value type. */ ++ ++ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE ++typedef union YYSTYPE + { +-#line 38 "dtc-parser.y" /* yacc.c:1909 */ ++ ++/* Line 2068 of yacc.c */ ++#line 39 "dtc-parser.y" + + char *propnodename; + char *labelref; +@@ -92,30 +87,32 @@ union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; ++ ++ + +-#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ +-}; ++/* Line 2068 of yacc.c */ ++#line 96 "dtc-parser.tab.h" ++} YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-/* Location type. */ ++extern YYSTYPE yylval; ++ + #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +-typedef struct YYLTYPE YYLTYPE; +-struct YYLTYPE ++typedef struct YYLTYPE + { + int first_line; + int first_column; + int last_line; + int last_column; +-}; ++} YYLTYPE; ++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ + # define YYLTYPE_IS_DECLARED 1 + # define YYLTYPE_IS_TRIVIAL 1 + #endif + +- +-extern YYSTYPE yylval; + extern YYLTYPE yylloc; +-int yyparse (void); + +-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y +index 5a897e3..56b9c15 100644 +--- a/scripts/dtc/dtc-parser.y ++++ b/scripts/dtc/dtc-parser.y +@@ -19,6 +19,7 @@ + */ + %{ + #include ++#include + + #include "dtc.h" + #include "srcpos.h" +@@ -52,9 +53,11 @@ extern bool treesource_error; + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + } + + %token DT_V1 ++%token DT_PLUGIN + %token DT_MEMRESERVE + %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR + %token DT_BITS +@@ -71,6 +74,7 @@ extern bool treesource_error; + + %type propdata + %type propdataprefix ++%type plugindecl + %type memreserve + %type memreserves + %type arrayprefix +@@ -101,10 +105,23 @@ extern bool treesource_error; + %% + + sourcefile: +- DT_V1 ';' memreserves devicetree ++ DT_V1 ';' plugindecl memreserves devicetree + { +- the_boot_info = build_boot_info($3, $4, +- guess_boot_cpuid($4)); ++ $5->is_plugin = $3; ++ $5->is_root = 1; ++ the_boot_info = build_boot_info($4, $5, ++ guess_boot_cpuid($5)); ++ } ++ ; ++ ++plugindecl: ++ /* empty */ ++ { ++ $$ = 0; ++ } ++ | DT_PLUGIN ';' ++ { ++ $$ = 1; + } + ; + +diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c +index 8c4add6..0cbb14c 100644 +--- a/scripts/dtc/dtc.c ++++ b/scripts/dtc/dtc.c +@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ + int minsize; /* Minimum blob size */ + int padsize; /* Additional padding to blob */ + int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ ++int symbol_fixup_support = 0; + + static void fill_fullpaths(struct node *tree, const char *prefix) + { +@@ -51,7 +52,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) + #define FDT_VERSION(version) _FDT_VERSION(version) + #define _FDT_VERSION(version) #version + static const char usage_synopsis[] = "dtc [options] "; +-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; ++static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; + static struct option const usage_long_opts[] = { + {"quiet", no_argument, NULL, 'q'}, + {"in-format", a_argument, NULL, 'I'}, +@@ -69,6 +70,7 @@ static struct option const usage_long_opts[] = { + {"phandle", a_argument, NULL, 'H'}, + {"warning", a_argument, NULL, 'W'}, + {"error", a_argument, NULL, 'E'}, ++ {"symbols", a_argument, NULL, '@'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {NULL, no_argument, NULL, 0x0}, +@@ -99,6 +101,7 @@ static const char * const usage_opts_help[] = { + "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", + "\n\tEnable/disable warnings (prefix with \"no-\")", + "\n\tEnable/disable errors (prefix with \"no-\")", ++ "\n\tSymbols and Fixups support", + "\n\tPrint this help and exit", + "\n\tPrint version and exit", + NULL, +@@ -186,7 +189,9 @@ int main(int argc, char *argv[]) + case 'E': + parse_checks_option(false, true, optarg); + break; +- ++ case '@': ++ symbol_fixup_support = 1; ++ break; + case 'h': + usage(NULL); + default: +diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h +index 56212c8..fe45748 100644 +--- a/scripts/dtc/dtc.h ++++ b/scripts/dtc/dtc.h +@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ + extern int minsize; /* Minimum blob size */ + extern int padsize; /* Additional padding to blob */ + extern int phandle_format; /* Use linux,phandle or phandle properties */ ++extern int symbol_fixup_support;/* enable symbols & fixup support */ + + #define PHANDLE_LEGACY 0x1 + #define PHANDLE_EPAPR 0x2 +@@ -132,6 +133,25 @@ struct label { + struct label *next; + }; + ++struct fixup_entry { ++ int offset; ++ struct node *node; ++ struct property *prop; ++ struct fixup_entry *next; ++}; ++ ++struct fixup { ++ char *ref; ++ struct fixup_entry *entries; ++ struct fixup *next; ++}; ++ ++struct symbol { ++ struct label *label; ++ struct node *node; ++ struct symbol *next; ++}; ++ + struct property { + bool deleted; + char *name; +@@ -158,6 +178,12 @@ struct node { + int addr_cells, size_cells; + + struct label *labels; ++ ++ int is_root; ++ int is_plugin; ++ struct fixup *fixups; ++ struct symbol *symbols; ++ struct fixup_entry *local_fixups; + }; + + #define for_each_label_withdel(l0, l) \ +@@ -181,6 +207,18 @@ struct node { + for_each_child_withdel(n, c) \ + if (!(c)->deleted) + ++#define for_each_fixup(n, f) \ ++ for ((f) = (n)->fixups; (f); (f) = (f)->next) ++ ++#define for_each_fixup_entry(f, fe) \ ++ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) ++ ++#define for_each_symbol(n, s) \ ++ for ((s) = (n)->symbols; (s); (s) = (s)->next) ++ ++#define for_each_local_fixup_entry(n, fe) \ ++ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) ++ + void add_label(struct label **labels, char *label); + void delete_labels(struct label **labels); + +diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c +index bd99fa2..f439b40 100644 +--- a/scripts/dtc/flattree.c ++++ b/scripts/dtc/flattree.c +@@ -262,6 +262,12 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + struct property *prop; + struct node *child; + bool seen_name_prop = false; ++ struct symbol *sym; ++ struct fixup *f; ++ struct fixup_entry *fe; ++ char *name, *s; ++ const char *fullpath; ++ int namesz, nameoff, vallen; + + if (tree->deleted) + return; +@@ -276,8 +282,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + emit->align(etarget, sizeof(cell_t)); + + for_each_property(tree, prop) { +- int nameoff; +- + if (streq(prop->name, "name")) + seen_name_prop = true; + +@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + flatten_tree(child, emit, etarget, strbuf, vi); + } + ++ if (!symbol_fixup_support) ++ goto no_symbols; ++ ++ /* add the symbol nodes (if any) */ ++ if (tree->symbols) { ++ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__symbols__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ for_each_symbol(tree, sym) { ++ ++ vallen = strlen(sym->node->fullpath); ++ ++ nameoff = stringtable_insert(strbuf, sym->label->label); ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, sym->node->fullpath, ++ strlen(sym->node->fullpath)); ++ emit->align(etarget, sizeof(cell_t)); ++ } ++ ++ emit->endnode(etarget, NULL); ++ } ++ ++ /* add the fixup nodes */ ++ if (tree->fixups) { ++ ++ /* emit the external fixups */ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__fixups__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ for_each_fixup(tree, f) { ++ ++ namesz = 0; ++ for_each_fixup_entry(f, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ namesz += strlen(fullpath) + 1; ++ namesz += strlen(fe->prop->name) + 1; ++ namesz += 32; /* space for : + '\0' */ ++ } ++ ++ name = xmalloc(namesz); ++ ++ s = name; ++ for_each_fixup_entry(f, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ snprintf(s, name + namesz - s, "%s:%s:%d", ++ fullpath, ++ fe->prop->name, fe->offset); ++ s += strlen(s) + 1; ++ } ++ ++ nameoff = stringtable_insert(strbuf, f->ref); ++ vallen = s - name - 1; ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, name, vallen); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ free(name); ++ } ++ ++ emit->endnode(etarget, tree->labels); ++ } ++ ++ /* add the local fixup property */ ++ if (tree->local_fixups) { ++ ++ /* emit the external fixups */ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__local_fixups__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ namesz = 0; ++ for_each_local_fixup_entry(tree, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ namesz += strlen(fullpath) + 1; ++ namesz += strlen(fe->prop->name) + 1; ++ namesz += 32; /* space for : + '\0' */ ++ } ++ ++ name = xmalloc(namesz); ++ ++ s = name; ++ for_each_local_fixup_entry(tree, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ snprintf(s, name + namesz - s, "%s:%s:%d", ++ fullpath, fe->prop->name, ++ fe->offset); ++ s += strlen(s) + 1; ++ } ++ ++ nameoff = stringtable_insert(strbuf, "fixup"); ++ vallen = s - name - 1; ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, name, vallen); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ free(name); ++ ++ emit->endnode(etarget, tree->labels); ++ } ++ ++no_symbols: + emit->endnode(etarget, tree->labels); + } + +diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h +index 5b8c7d5..86b7338 100644 +--- a/scripts/dtc/version_gen.h ++++ b/scripts/dtc/version_gen.h +@@ -1 +1 @@ +-#define DTC_VERSION "DTC 1.4.1-g9d3649bd" ++#define DTC_VERSION "DTC 1.4.1-g9d3649bd-dirty" + +From 03742881e78586b8a8e10fdbad4371d4d665a9fc Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 122/204] Merge pull request #1043 from XECDesign/sense-4.0 +Subject: [PATCH 089/113] Merge pull request #1043 from XECDesign/sense-4.0 mfd: Add Raspberry Pi Sense HAT core driver --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 +++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - drivers/input/joystick/Kconfig | 8 + - drivers/input/joystick/Makefile | 1 + - drivers/input/joystick/rpisense-js.c | 153 +++++++++++++++ - drivers/mfd/Kconfig | 8 + - drivers/mfd/Makefile | 2 + - drivers/mfd/rpisense-core.c | 157 +++++++++++++++ - drivers/video/fbdev/Kconfig | 13 ++ - drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/rpisense-fb.c | 235 +++++++++++++++++++++++ - include/linux/mfd/rpisense/core.h | 47 +++++ - include/linux/mfd/rpisense/framebuffer.h | 28 +++ - include/linux/mfd/rpisense/joystick.h | 35 ++++ - 17 files changed, 746 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts + drivers/input/joystick/Kconfig | 8 + + drivers/input/joystick/Makefile | 1 + + drivers/input/joystick/rpisense-js.c | 153 ++++++++++++++++ + drivers/mfd/Kconfig | 8 + + drivers/mfd/Makefile | 2 + + drivers/mfd/rpisense-core.c | 157 +++++++++++++++++ + drivers/video/fbdev/Kconfig | 13 ++ + drivers/video/fbdev/Makefile | 1 + + drivers/video/fbdev/rpisense-fb.c | 293 +++++++++++++++++++++++++++++++ + include/linux/mfd/rpisense/core.h | 47 +++++ + include/linux/mfd/rpisense/framebuffer.h | 32 ++++ + include/linux/mfd/rpisense/joystick.h | 35 ++++ + 12 files changed, 750 insertions(+) create mode 100644 drivers/input/joystick/rpisense-js.c create mode 100644 drivers/mfd/rpisense-core.c create mode 100644 drivers/video/fbdev/rpisense-fb.c @@ -140287,133 +138918,11 @@ mfd: Add Raspberry Pi Sense HAT core driver create mode 100644 include/linux/mfd/rpisense/framebuffer.h create mode 100644 include/linux/mfd/rpisense/joystick.h -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4ff9836..5f6082f 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -39,6 +39,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 88ed678..8792f98 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -442,6 +442,12 @@ Load: dtoverlay=rpi-proto - Params: - - -+Name: rpi-sense -+Info: Raspberry Pi Sense HAT -+Load: dtoverlay=rpi-sense -+Params: -+ -+ - Name: sdhost - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock - Load: dtoverlay=sdhost,= -diff --git a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -new file mode 100644 -index 0000000..2715324 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -@@ -0,0 +1,47 @@ -+// rpi-sense HAT -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ rpi-sense@46 { -+ compatible = "rpi,rpi-sense"; -+ reg = <0x46>; -+ keys-int-gpios = <&gpio 23 1>; -+ status = "okay"; -+ }; -+ -+ lsm9ds1-magn@1c { -+ compatible = "st,lsm9ds1-magn"; -+ reg = <0x1c>; -+ status = "okay"; -+ }; -+ -+ lsm9ds1-accel6a { -+ compatible = "st,lsm9ds1-accel"; -+ reg = <0x6a>; -+ status = "okay"; -+ }; -+ -+ lps25h-press@5c { -+ compatible = "st,lps25h-press"; -+ reg = <0x5c>; -+ status = "okay"; -+ }; -+ -+ hts221-humid@5f { -+ compatible = "st,hts221-humid"; -+ reg = <0x5f>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d75b104..f78a483 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -533,6 +533,7 @@ CONFIG_JOYSTICK_IFORCE=m - CONFIG_JOYSTICK_IFORCE_USB=y - CONFIG_JOYSTICK_XPAD=m - CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -@@ -789,6 +790,7 @@ CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 9159892..b9b5bdf 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -526,6 +526,7 @@ CONFIG_JOYSTICK_IFORCE=m - CONFIG_JOYSTICK_IFORCE_USB=y - CONFIG_JOYSTICK_XPAD=m - CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m -@@ -782,6 +783,7 @@ CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig -index 56eb471..73e3a23 100644 +index 4215b53..4364d7c 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig -@@ -329,4 +329,12 @@ config JOYSTICK_MAPLE +@@ -330,4 +330,12 @@ config JOYSTICK_MAPLE To compile this as a module choose M here: the module will be called maplecontrol. @@ -140596,7 +139105,7 @@ index 0000000..9eca897 +MODULE_AUTHOR("Serge Schneider "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index d5ad04d..dfb730e 100644 +index 99d6367..296daf8 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -10,6 +10,14 @@ config MFD_CORE @@ -140615,10 +139124,10 @@ index d5ad04d..dfb730e 100644 tristate "AMD CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 0e5cfeb..9c491fb 100644 +index a59e3fc..205084b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile -@@ -185,3 +185,5 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o +@@ -192,3 +192,5 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o @@ -140788,13 +139297,13 @@ index 0000000..7539547 +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index 15098c5..b89998b7 100644 +index f1b031e..2a28938 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig -@@ -2495,3 +2495,16 @@ config FB_SSD1307 - help - This driver implements support for the Solomon SSD1307 - OLED controller over I2C. +@@ -2503,3 +2503,16 @@ config FB_SM712 + This driver is also available as a module. The module will be + called sm712fb. If you want to compile it as a module, say M + here and read . + +config FB_RPISENSE + tristate "Raspberry Pi Sense HAT framebuffer" @@ -140809,7 +139318,7 @@ index 15098c5..b89998b7 100644 + help + This is the framebuffer driver for the Raspberry Pi Sense HAT diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 57181ad..ee7568b 100644 +index 9b086ac..7101277 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o @@ -140822,10 +139331,10 @@ index 57181ad..ee7568b 100644 obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/fbdev/rpisense-fb.c b/drivers/video/fbdev/rpisense-fb.c new file mode 100644 -index 0000000..99bb8ea +index 0000000..90553fa --- /dev/null +++ b/drivers/video/fbdev/rpisense-fb.c -@@ -0,0 +1,235 @@ +@@ -0,0 +1,293 @@ +/* + * Raspberry Pi Sense HAT framebuffer driver + * http://raspberrypi.org @@ -140847,6 +139356,7 @@ index 0000000..99bb8ea +#include +#include +#include ++#include +#include +#include +#include @@ -140854,22 +139364,35 @@ index 0000000..99bb8ea +#include +#include + ++static bool lowlight; ++module_param(lowlight, bool, 0); ++MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); ++ +struct rpisense *rpisense; + +struct rpisense_fb_param { + char __iomem *vmem; + u8 *vmem_work; + u32 vmemsize; -+ u8 gamma[32]; ++ u8 *gamma; +}; + ++static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, ++ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, ++ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}; ++ ++static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, ++ 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, ++ 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,}; ++ ++static u8 gamma_user[32]; ++ +static struct rpisense_fb_param rpisense_fb_param = { + .vmem = NULL, + .vmemsize = 128, -+ .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -+ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, -+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, -+ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}, ++ .gamma = gamma_default, +}; + +static struct fb_deferred_io rpisense_fb_defio; @@ -140955,6 +139478,46 @@ index 0000000..99bb8ea + .deferred_io = rpisense_fb_deferred_io, +}; + ++static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd, ++ unsigned long arg) ++{ ++ switch (cmd) { ++ case SENSEFB_FBIOGET_GAMMA: ++ if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma, ++ sizeof(u8[32]))) ++ return -EFAULT; ++ return 0; ++ case SENSEFB_FBIOSET_GAMMA: ++ if (copy_from_user(gamma_user, (void __user *)arg, ++ sizeof(u8[32]))) ++ return -EFAULT; ++ rpisense_fb_param.gamma = gamma_user; ++ schedule_delayed_work(&info->deferred_work, ++ rpisense_fb_defio.delay); ++ return 0; ++ case SENSEFB_FBIORESET_GAMMA: ++ switch (arg) { ++ case 0: ++ rpisense_fb_param.gamma = gamma_default; ++ break; ++ case 1: ++ rpisense_fb_param.gamma = gamma_low; ++ break; ++ case 2: ++ rpisense_fb_param.gamma = gamma_user; ++ break; ++ default: ++ return -EINVAL; ++ } ++ schedule_delayed_work(&info->deferred_work, ++ rpisense_fb_defio.delay); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ +static struct fb_ops rpisense_fb_ops = { + .owner = THIS_MODULE, + .fb_read = fb_sys_read, @@ -140962,6 +139525,7 @@ index 0000000..99bb8ea + .fb_fillrect = rpisense_fb_fillrect, + .fb_copyarea = rpisense_fb_copyarea, + .fb_imageblit = rpisense_fb_imageblit, ++ .fb_ioctl = rpisense_fb_ioctl, +}; + +static int rpisense_fb_probe(struct platform_device *pdev) @@ -140999,6 +139563,9 @@ index 0000000..99bb8ea + info->screen_base = rpisense_fb_param.vmem; + info->screen_size = rpisense_fb_param.vmemsize; + ++ if (lowlight) ++ rpisense_fb_param.gamma = gamma_low; ++ + fb_deferred_io_init(info); + + ret = register_framebuffer(info); @@ -141116,10 +139683,10 @@ index 0000000..4856aa3 +#endif diff --git a/include/linux/mfd/rpisense/framebuffer.h b/include/linux/mfd/rpisense/framebuffer.h new file mode 100644 -index 0000000..c4c1118 +index 0000000..2ba95d7 --- /dev/null +++ b/include/linux/mfd/rpisense/framebuffer.h -@@ -0,0 +1,28 @@ +@@ -0,0 +1,32 @@ +/* + * Raspberry Pi Sense HAT framebuffer driver + * http://raspberrypi.org @@ -141138,7 +139705,11 @@ index 0000000..c4c1118 +#ifndef __LINUX_RPISENSE_FB_H_ +#define __LINUX_RPISENSE_FB_H_ + -+#include ++#define SENSEFB_FBIO_IOC_MAGIC 0xF1 ++ ++#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0) ++#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1) ++#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2) + +struct rpisense; + @@ -141190,2846 +139761,10 @@ index 0000000..56196dc + +#endif -From 7ec906836d03f54c2f62372c25a413af323c2564 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 15 Jul 2015 13:46:08 +0100 -Subject: [PATCH 123/204] leds-gpio: Implement the brightness_get method - -The power LED uses some clever logic that means it is driven -by a voltage measuring circuit when configured as input, otherwise -it is driven by the GPIO output value. This patch wires up the -brightness_get method for leds-gpio so that user-space can monitor -the LED value via /sys/class/gpio/led1/brightness. Using the input -trigger this returns an indication of the system power health, -otherwise it is just whatever value the trigger has written most -recently. - -See: https://github.com/raspberrypi/linux/issues/1064 ---- - drivers/leds/leds-gpio.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 3cfbd6a..4e4e132 100644 ---- a/drivers/leds/leds-gpio.c -+++ b/drivers/leds/leds-gpio.c -@@ -82,6 +82,13 @@ static void gpio_led_set(struct led_classdev *led_cdev, - } - } - -+static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) -+{ -+ struct gpio_led_data *led_dat = -+ container_of(led_cdev, struct gpio_led_data, cdev); -+ return gpiod_get_value_cansleep(led_dat->gpiod) ? LED_FULL : LED_OFF; -+} -+ - static int gpio_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, unsigned long *delay_off) - { -@@ -138,6 +145,7 @@ static int create_gpio_led(const struct gpio_led *template, - led_dat->cdev.blink_set = gpio_blink_set; - } - led_dat->cdev.brightness_set = gpio_led_set; -+ led_dat->cdev.brightness_get = gpio_led_get; - if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) - state = !!gpiod_get_value_cansleep(led_dat->gpiod); - else - -From 0cfac48f6780a5038da6e0fc0e37dfc3975f2077 Mon Sep 17 00:00:00 2001 -From: Robert Tiemann -Date: Fri, 17 Jul 2015 09:50:55 +0200 -Subject: [PATCH 124/204] dmaengine: bcm2708-dmaengine: Fix memory leak when - stopping a running transfer - ---- - drivers/dma/bcm2708-dmaengine.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 987ed53..73c6c00 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -964,6 +964,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan) - * c->desc is NULL and exit.) - */ - if (c->desc) { -+ bcm2835_dma_desc_free(&c->desc->vd); - c->desc = NULL; - bcm2835_dma_abort(c->chan_base); - - -From 095268253a866ff43278ff24f4a7502949c6cf92 Mon Sep 17 00:00:00 2001 -From: Robert Tiemann -Date: Mon, 20 Jul 2015 11:01:13 +0200 -Subject: [PATCH 125/204] BCM270X_DT: Fix I2S register map - ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 2dd25f7..728e14a 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -117,8 +117,8 @@ - - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - //dmas = <&dma 2>, - // <&dma 3>; - -From 649b011d757054ad6d9d5702f8d3bf670a42e404 Mon Sep 17 00:00:00 2001 -From: Robert Tiemann -Date: Mon, 20 Jul 2015 11:01:25 +0200 -Subject: [PATCH 126/204] BCM2835_DT: Fix I2S register map - ---- - Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- - Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 4 ++-- - arch/arm/boot/dts/bcm2835.dtsi | 4 ++-- - 3 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt -index 1396078..2db8294 100644 ---- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt -+++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt -@@ -48,8 +48,8 @@ Example: - - bcm2835_i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = < 0x7e203000 0x20>, -- < 0x7e101098 0x02>; -+ reg = < 0x7e203000 0x24>, -+ < 0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; -diff --git a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt -index 65783de..a89fe42 100644 ---- a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt -+++ b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt -@@ -16,8 +16,8 @@ Example: - - bcm2835_i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 4a63704..1135120 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -101,8 +101,8 @@ - - i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; - -From 5076ca8360f9ad0d46a060fcde7eefe7fb10eea1 Mon Sep 17 00:00:00 2001 -From: David Frey -Date: Tue, 14 Jul 2015 15:57:36 +0200 -Subject: [PATCH 127/204] config: Enable SHT drivers for raspberry pi - -The SHT temperature and humidity sensors are often used in weather -station projects. - -Signed-off-by: David Frey ---- - arch/arm/configs/bcm2709_defconfig | 4 +++- - arch/arm/configs/bcmrpi_defconfig | 4 +++- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index f78a483..dd00e7c 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -611,7 +611,9 @@ CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y --# CONFIG_HWMON is not set -+CONFIG_HWMON=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHTC1=m - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index b9b5bdf..7b24274 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -604,7 +604,9 @@ CONFIG_W1_SLAVE_BQ27000=m - CONFIG_BATTERY_DS2760=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y --# CONFIG_HWMON is not set -+CONFIG_HWMON=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHTC1=m - CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y - -From 2e23dd0be7034e7aee9795288d9de1ed151ad5fd Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 14:07:14 +0100 -Subject: [PATCH 128/204] BCM270X_DT: Correct typo in overlays/README - ---- - arch/arm/boot/dts/overlays/README | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 8792f98..ed484ae 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -78,7 +78,7 @@ Name: - Info: Configures the base Raspberry Pi hardware - Load: - Params: -- audio Set to "on" to disable the onboard ALSA audio -+ audio Set to "on" to enable the onboard ALSA audio - interface (default "off") - - i2c_arm Set to "on" to enable the ARM's i2c interface - -From dc0a5bcc935ccc881fb4043dc949af755d3e8f1c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 10:53:26 +0100 -Subject: [PATCH 129/204] bcm2835-sdhost: Add the ERASE capability - -See: https://github.com/raspberrypi/linux/issues/1076 ---- - drivers/mmc/host/bcm2835-sdhost.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index d65870a..57a6ad3 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -1675,7 +1675,7 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - /* host controller capabilities */ - mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -- MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | -+ MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | - (ALLOW_CMD23 * MMC_CAP_CMD23); - - spin_lock_init(&host->lock); - -From 54ef0643fae43fff2cb1583919a34f787ad132af Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 17:32:18 +0100 -Subject: [PATCH 130/204] bcm2835-sdhost: Ignore CRC7 for MMC CMD1 - -It seems that the sdhost interface returns CRC7 errors for CMD1, -which is the MMC-specific SEND_OP_COND. Returning these errors to -the MMC layer causes a downward spiral, but ignoring them seems -to be harmless. ---- - drivers/mmc/host/bcm2835-sdhost.c | 39 +++++++++++++++++++++++---------------- - 1 file changed, 23 insertions(+), 16 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 57a6ad3..84f645f 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -959,25 +959,32 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - mmc_hostname(host->mmc), sdcmd, sdhsts, - bcm2835_sdhost_read(host, SDEDM)); - -- if (sdhsts & SDHSTS_CMD_TIME_OUT) { -- switch (host->cmd->opcode) { -- case 5: case 52: case 53: -- /* Don't warn about SDIO commands */ -- break; -- default: -- pr_err("%s: command timeout\n", -+ if ((sdhsts & SDHSTS_CRC7_ERROR) && -+ (host->cmd->opcode == 1)) { -+ if (host->debug) -+ pr_info("%s: ignoring CRC7 error for CMD1\n", -+ mmc_hostname(host->mmc)); -+ } else { -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) { -+ switch (host->cmd->opcode) { -+ case 5: case 52: case 53: -+ /* Don't warn about SDIO commands */ -+ break; -+ default: -+ pr_err("%s: command timeout\n", -+ mmc_hostname(host->mmc)); -+ break; -+ } -+ host->cmd->error = -ETIMEDOUT; -+ } else { -+ pr_err("%s: unexpected command error\n", - mmc_hostname(host->mmc)); -- break; -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; - } -- host->cmd->error = -ETIMEDOUT; -- } else { -- pr_err("%s: unexpected command error\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; - } -- tasklet_schedule(&host->finish_tasklet); -- return; - } - - if (host->cmd->flags & MMC_RSP_PRESENT) { - -From 24f4ffb4f7a2f5b37197a168485207216b736adb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Jul 2015 14:48:21 +0100 -Subject: [PATCH 131/204] BCM270X_DT: Add unit address to gpio node name - ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 728e14a..cb608df 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -92,7 +92,7 @@ - status = "disabled"; - }; - -- gpio: gpio { -+ gpio: gpio@7e200000 { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; - interrupts = <2 17>, <2 18>; - -From 7d633f69a6cbc12d37782f6ab96e402eb1b18949 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 24 Jul 2015 10:36:32 +0100 -Subject: [PATCH 132/204] BCM270X_DT: Use i2c_arm for rtc and bmp085 overlays - ---- - arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -index b830bf2..782b171 100644 ---- a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -@@ -6,7 +6,7 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -- target = <&i2c1>; -+ target = <&i2c_arm>; - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index 7052c71..fed4bd8 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -6,7 +6,7 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -- target = <&i2c1>; -+ target = <&i2c_arm>; - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; - -From 70694a4073fa62862c93ab409b49d3d86071a6c0 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 24 Jul 2015 12:11:31 +0100 -Subject: [PATCH 133/204] BCM2708_DT: CM dtparams for audio, watchdog and RNG - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 34d4bc6..713e5a2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -17,14 +17,14 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; - -From a36ecdc70162e181fac2f7b7afb952639df22384 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:13:18 +0200 -Subject: [PATCH 134/204] vchiq: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 1 + - .../vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 17 +++++++++-------- - .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 +++++++++++++++++ - 3 files changed, 27 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index cb608df..df66e64 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -225,6 +225,7 @@ - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; - cache-line-size = <32>; -+ firmware = <&firmware>; - }; - - thermal: thermal { -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 56bff05..c9febcc 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -39,11 +39,11 @@ - #include - #include - #include --#include - #include - #include - #include - #include -+#include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - -@@ -89,10 +89,12 @@ free_pagelist(PAGELIST_T *pagelist, int actual); - int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - { - struct device *dev = &pdev->dev; -+ struct rpi_firmware *fw = platform_get_drvdata(pdev); - VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; - struct resource *res; - void *slot_mem; - dma_addr_t slot_phys; -+ u32 channelbase; - int slot_mem_size, frag_mem_size; - int err, irq, i; - -@@ -157,13 +159,12 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - } - - /* Send the base address of the slots to VideoCore */ -- -- dsb(); /* Ensure all writes have completed */ -- -- err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); -- if (err) { -- dev_err(dev, "mailbox write failed\n"); -- return err; -+ channelbase = slot_phys; -+ err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, -+ &channelbase, sizeof(channelbase)); -+ if (err || channelbase) { -+ dev_err(dev, "failed to set channelbase\n"); -+ return err ? : -ENXIO; - } - - vchiq_log_info(vchiq_arm_log_level, -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index 31e2cba..e11c0e0 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -45,7 +45,9 @@ - #include - #include - #include -+#include - #include -+#include - - #include "vchiq_core.h" - #include "vchiq_ioctl.h" -@@ -2793,9 +2795,24 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, - - static int vchiq_probe(struct platform_device *pdev) - { -+ struct device_node *fw_node; -+ struct rpi_firmware *fw; - int err; - void *ptr_err; - -+ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); -+/* Remove comment when booting without Device Tree is no longer supported -+ if (!fw_node) { -+ dev_err(&pdev->dev, "Missing firmware node\n"); -+ return -ENOENT; -+ } -+*/ -+ fw = rpi_firmware_get(fw_node); -+ if (!fw) -+ return -EPROBE_DEFER; -+ -+ platform_set_drvdata(pdev, fw); -+ - /* create debugfs entries */ - err = vchiq_debugfs_init(); - if (err != 0) - -From 97df14a49141d2831362aac3d18875d271b1a97f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:17:10 +0200 -Subject: [PATCH 135/204] thermal: bcm2835: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. -Remove retry loop on failure to read temperature. -Clean up code. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 1 + - drivers/thermal/bcm2835-thermal.c | 197 +++++++++++++--------------------- - 2 files changed, 75 insertions(+), 123 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index df66e64..bd8ac0a 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -230,6 +230,7 @@ - - thermal: thermal { - compatible = "brcm,bcm2835-thermal"; -+ firmware = <&firmware>; - }; - }; - -diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c -index 3bc80f1..c1d8f1b 100644 ---- a/drivers/thermal/bcm2835-thermal.c -+++ b/drivers/thermal/bcm2835-thermal.c -@@ -12,161 +12,113 @@ - * consent. - *****************************************************************************/ - --#include - #include --#include --#include - #include --#include --#include - #include -+#include - -- --/* --- DEFINITIONS --- */ --#define MODULE_NAME "bcm2835_thermal" -- --/*#define THERMAL_DEBUG_ENABLE*/ -- --#ifdef THERMAL_DEBUG_ENABLE --#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) --#else --#define print_debug(fmt,...) --#endif --#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) -- --#define VC_TAG_GET_TEMP 0x00030006 --#define VC_TAG_GET_MAX_TEMP 0x0003000A -- --typedef enum { -- TEMP, -- MAX_TEMP, --} temp_type; -- --/* --- STRUCTS --- */ --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the tag ID for the temperature */ -- uint32_t buffer_size; /* size of the buffer (should be 8) */ -- uint32_t request_code; /* identifies message as a request (should be 0) */ -- uint32_t id; /* extra ID field (should be 0) */ -- uint32_t val; /* returned value of the temperature */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- --struct bcm2835_thermal_data { -- struct thermal_zone_device *thermal_dev; -- struct vc_msg msg; --}; -- --/* --- GLOBALS --- */ --static struct bcm2835_thermal_data bcm2835_data; -- --/* Thermal Device Operations */ --static struct thermal_zone_device_ops ops; -- --/* --- FUNCTIONS --- */ -- --static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id) -+static int bcm2835_thermal_get_property(struct thermal_zone_device *tz, -+ unsigned long *temp, u32 tag) - { -- int result = -1, retry = 3; -- print_debug("IN"); -+ struct rpi_firmware *fw = tz->devdata; -+ struct { -+ u32 id; -+ u32 val; -+ } packet; -+ int ret; - - *temp = 0; -- while (result != 0 && retry-- > 0) { -- /* wipe all previous message data */ -- memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg); -- -- /* prepare message */ -- bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg; -- bcm2835_data.msg.tag.buffer_size = 8; -- bcm2835_data.msg.tag.tag_id = tag_id; -- -- /* send the message */ -- result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg); -- print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code); -- if (!(bcm2835_data.msg.request_code & 0x80000000)) -- result = -1; -+ packet.id = 0; -+ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); -+ if (ret) { -+ dev_err(&tz->device, "Failed to get temperature\n"); -+ return ret; - } - -- /* check if it was all ok and return the rate in milli degrees C */ -- if (result == 0) -- *temp = (uint)bcm2835_data.msg.tag.val; -- else -- print_err("Failed to get temperature! (%x:%d)\n", tag_id, result); -- print_debug("OUT"); -- return result; -+ *temp = packet.val; -+ dev_dbg(&tz->device, "%stemp=%lu\n", -+ tag == RPI_FIRMWARE_GET_MAX_TEMPERATURE ? "max" : "", *temp); -+ -+ return 0; - } - --static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp) -+static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz, -+ unsigned long *temp) - { -- return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP); -+ return bcm2835_thermal_get_property(tz, temp, -+ RPI_FIRMWARE_GET_TEMPERATURE); - } - --static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp) -+static int bcm2835_thermal_get_max_temp(struct thermal_zone_device *tz, -+ int trip, unsigned long *temp) - { -- return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP); -+ /* -+ * The maximum safe temperature of the SoC. -+ * Overclock may be disabled above this temperature. -+ */ -+ return bcm2835_thermal_get_property(tz, temp, -+ RPI_FIRMWARE_GET_MAX_TEMPERATURE); - } - --static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type) -+static int bcm2835_thermal_get_trip_type(struct thermal_zone_device *tz, -+ int trip, enum thermal_trip_type *type) - { -- *trip_type = THERMAL_TRIP_HOT; -+ *type = THERMAL_TRIP_HOT; -+ - return 0; - } - -- --static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode) -+static int bcm2835_thermal_get_mode(struct thermal_zone_device *tz, -+ enum thermal_device_mode *mode) - { -- *dev_mode = THERMAL_DEVICE_ENABLED; -+ *mode = THERMAL_DEVICE_ENABLED; -+ - return 0; - } - -+static struct thermal_zone_device_ops ops = { -+ .get_temp = bcm2835_thermal_get_temp, -+ .get_trip_temp = bcm2835_thermal_get_max_temp, -+ .get_trip_type = bcm2835_thermal_get_trip_type, -+ .get_mode = bcm2835_thermal_get_mode, -+}; - - static int bcm2835_thermal_probe(struct platform_device *pdev) - { -- print_debug("IN"); -- print_debug("THERMAL Driver has been probed!"); -- -- /* check that the device isn't null!*/ -- if(pdev == NULL) -- { -- print_debug("Platform device is empty!"); -- return -ENODEV; -+ struct device_node *fw_np; -+ struct rpi_firmware *fw; -+ struct thermal_zone_device *tz; -+ -+ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0); -+/* Remove comment when booting without Device Tree is no longer supported -+ if (!fw_np) { -+ dev_err(&pdev->dev, "Missing firmware node\n"); -+ return -ENOENT; - } -- -- if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0))) -- { -- print_debug("Unable to register the thermal device!"); -- return -EFAULT; -+*/ -+ fw = rpi_firmware_get(fw_np); -+ if (!fw) -+ return -EPROBE_DEFER; -+ -+ tz = thermal_zone_device_register("bcm2835_thermal", 1, 0, fw, &ops, -+ NULL, 0, 0); -+ if (IS_ERR(tz)) { -+ dev_err(&pdev->dev, "Failed to register the thermal device\n"); -+ return PTR_ERR(tz); - } -+ -+ platform_set_drvdata(pdev, tz); -+ - return 0; - } - -- - static int bcm2835_thermal_remove(struct platform_device *pdev) - { -- print_debug("IN"); -- -- thermal_zone_device_unregister(bcm2835_data.thermal_dev); -- -- print_debug("OUT"); -+ thermal_zone_device_unregister(platform_get_drvdata(pdev)); - - return 0; - } - --static struct thermal_zone_device_ops ops = { -- .get_temp = bcm2835_get_temp, -- .get_trip_temp = bcm2835_get_max_temp, -- .get_trip_type = bcm2835_get_trip_type, -- .get_mode = bcm2835_get_mode, --}; -- - static const struct of_device_id bcm2835_thermal_of_match_table[] = { - { .compatible = "brcm,bcm2835-thermal", }, - {}, -@@ -177,14 +129,13 @@ static struct platform_driver bcm2835_thermal_driver = { - .probe = bcm2835_thermal_probe, - .remove = bcm2835_thermal_remove, - .driver = { -- .name = "bcm2835_thermal", -- .owner = THIS_MODULE, -- .of_match_table = bcm2835_thermal_of_match_table, -- }, -+ .name = "bcm2835_thermal", -+ .of_match_table = bcm2835_thermal_of_match_table, -+ }, - }; -+module_platform_driver(bcm2835_thermal_driver); - --MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Dorian Peake"); -+MODULE_AUTHOR("Noralf Trønnes"); - MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); -- --module_platform_driver(bcm2835_thermal_driver); -+MODULE_LICENSE("GPL"); - -From c2e3b884a9498adb58d4d403465e2d99ddd79e61 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:18:36 +0200 -Subject: [PATCH 136/204] cpufreq: bcm2835: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. - -Signed-off-by: Noralf Trønnes ---- - drivers/cpufreq/bcm2835-cpufreq.c | 117 +++++++++++++++++--------------------- - 1 file changed, 53 insertions(+), 64 deletions(-) - -diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c -index 6735da9..3eb9e93 100644 ---- a/drivers/cpufreq/bcm2835-cpufreq.c -+++ b/drivers/cpufreq/bcm2835-cpufreq.c -@@ -26,7 +26,7 @@ - #include - #include - #include --#include -+#include - - /* ---------- DEFINES ---------- */ - /*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ -@@ -43,23 +43,6 @@ - #define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) - #define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__) - --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the message id */ -- uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -- uint32_t data_size; /* amount of data being sent or received */ -- uint32_t dev_id; /* the ID of the clock/voltage to get or set */ -- uint32_t val; /* the value (e.g. rate (in Hz)) to set */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- - /* ---------- GLOBALS ---------- */ - static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */ - -@@ -74,62 +57,63 @@ static struct cpufreq_frequency_table bcm2835_freq_table[] = { - clk_rate either gets or sets the clock rates. - =============================================== - */ --static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) -+ -+static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) - { -- int s, actual_rate=0; -- struct vc_msg msg; -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); -+ struct { -+ u32 id; -+ u32 val; -+ } packet; -+ int ret; -+ -+ packet.id = id; -+ packet.val = *val; -+ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); -+ if (ret) -+ return ret; - -- /* wipe all previous message data */ -- memset(&msg, 0, sizeof msg); -+ *val = packet.val; - -- msg.msg_size = sizeof msg; -+ return 0; -+} - -- msg.tag.tag_id = VCMSG_SET_CLOCK_RATE; -- msg.tag.buffer_size = 8; -- msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */ -- msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; -- msg.tag.val = arm_rate * 1000; -+static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) -+{ -+ u32 rate = arm_rate * 1000; -+ int ret; - -- /* send the message */ -- s = bcm_mailbox_property(&msg, sizeof msg); -+ ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate); -+ if (ret) { -+ print_err("Failed to set clock: %d (%d)\n", arm_rate, ret); -+ return 0; -+ } - -- /* check if it was all ok and return the rate in KHz */ -- if (s == 0 && (msg.request_code & 0x80000000)) -- actual_rate = msg.tag.val/1000; -+ rate /= 1000; -+ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate); - -- print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate); -- return actual_rate; -+ return rate; - } - - static uint32_t bcm2835_cpufreq_get_clock(int tag) - { -- int s; -- int arm_rate = 0; -- struct vc_msg msg; -- -- /* wipe all previous message data */ -- memset(&msg, 0, sizeof msg); -- -- msg.msg_size = sizeof msg; -- msg.tag.tag_id = tag; -- msg.tag.buffer_size = 8; -- msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */ -- msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; -+ u32 rate; -+ int ret; - -- /* send the message */ -- s = bcm_mailbox_property(&msg, sizeof msg); -- -- /* check if it was all ok and return the rate in KHz */ -- if (s == 0 && (msg.request_code & 0x80000000)) -- arm_rate = msg.tag.val/1000; -+ ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate); -+ if (ret) { -+ print_err("Failed to get clock (%d)\n", ret); -+ return 0; -+ } - -- print_debug("%s frequency = %d\n", -- tag == VCMSG_GET_CLOCK_RATE ? "Current": -- tag == VCMSG_GET_MIN_CLOCK ? "Min": -- tag == VCMSG_GET_MAX_CLOCK ? "Max": -- "Unexpected", arm_rate); -+ rate /= 1000; -+ print_debug("%s frequency = %u\n", -+ tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current": -+ tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min": -+ tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max": -+ "Unexpected", rate); - -- return arm_rate; -+ return rate; - } - - /* -@@ -165,9 +149,14 @@ static int bcm2835_cpufreq_driver_init(struct cpufreq_policy *policy) - /* measured value of how long it takes to change frequency */ - const unsigned int transition_latency = 355000; /* ns */ - -+ if (!rpi_firmware_get(NULL)) { -+ print_err("Firmware is not available\n"); -+ return -ENODEV; -+ } -+ - /* now find out what the maximum and minimum frequencies are */ -- bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK); -- bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK); -+ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); - - print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency); - return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency); -@@ -201,8 +190,8 @@ static int bcm2835_cpufreq_driver_target_index(struct cpufreq_policy *policy, un - - static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu) - { -- unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE); -- print_debug("%d: freq=%d\n", cpu, actual_rate); -+ unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ print_debug("cpu%d: freq=%d\n", cpu, actual_rate); - return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency; - } - - -From 1ef7396bd8f7fa5452d762b9c534552604c0ec35 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:20:59 +0200 -Subject: [PATCH 137/204] fbdev: bcm2708: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the new firmware API instead of the legacy mailbox API. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 1 + - drivers/video/fbdev/bcm2708_fb.c | 273 +++++++++++++++++++--------------- - 2 files changed, 152 insertions(+), 122 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index bd8ac0a..d1c3bdf 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -217,6 +217,7 @@ - - fb: fb { - compatible = "brcm,bcm2708-fb"; -+ firmware = <&firmware>; - status = "disabled"; - }; - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index f6ac7da..06a96d16 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -25,7 +25,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -34,6 +33,7 @@ - #include - #include - #include -+#include - - //#define BCM2708_FB_DEBUG - #define MODULE_NAME "bcm2708_fb" -@@ -58,15 +58,19 @@ static u32 dma_busy_wait_threshold = 1<<15; - module_param(dma_busy_wait_threshold, int, 0644); - MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); - --/* this data structure describes each frame buffer device we find */ -- --struct fbinfo_s { -- u32 xres, yres, xres_virtual, yres_virtual; -- u32 pitch, bpp; -+struct fb_alloc_tags { -+ struct rpi_firmware_property_tag_header tag1; -+ u32 xres, yres; -+ struct rpi_firmware_property_tag_header tag2; -+ u32 xres_virtual, yres_virtual; -+ struct rpi_firmware_property_tag_header tag3; -+ u32 bpp; -+ struct rpi_firmware_property_tag_header tag4; - u32 xoffset, yoffset; -- u32 base; -- u32 screen_size; -- u16 cmap[256]; -+ struct rpi_firmware_property_tag_header tag5; -+ u32 base, screen_size; -+ struct rpi_firmware_property_tag_header tag6; -+ u32 pitch; - }; - - struct bcm2708_fb_stats { -@@ -78,9 +82,9 @@ struct bcm2708_fb_stats { - struct bcm2708_fb { - struct fb_info fb; - struct platform_device *dev; -- struct fbinfo_s *info; -- dma_addr_t dma; -+ struct rpi_firmware *fw; - u32 cmap[16]; -+ u32 gpu_cmap[256]; - int dma_chan; - int dma_irq; - void __iomem *dma_chan_base; -@@ -270,69 +274,71 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, - - static int bcm2708_fb_set_par(struct fb_info *info) - { -- uint32_t val = 0; - struct bcm2708_fb *fb = to_bcm2708(info); -- volatile struct fbinfo_s *fbinfo = fb->info; -- fbinfo->xres = info->var.xres; -- fbinfo->yres = info->var.yres; -- fbinfo->xres_virtual = info->var.xres_virtual; -- fbinfo->yres_virtual = info->var.yres_virtual; -- fbinfo->bpp = info->var.bits_per_pixel; -- fbinfo->xoffset = info->var.xoffset; -- fbinfo->yoffset = info->var.yoffset; -- fbinfo->base = 0; /* filled in by VC */ -- fbinfo->pitch = 0; /* filled in by VC */ -+ struct fb_alloc_tags fbinfo = { -+ .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ .xres = info->var.xres, -+ .yres = info->var.yres, -+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ .xres_virtual = info->var.xres_virtual, -+ .yres_virtual = info->var.yres_virtual, -+ .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, -+ .bpp = info->var.bits_per_pixel, -+ .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, -+ .xoffset = info->var.xoffset, -+ .yoffset = info->var.yoffset, -+ .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -+ .base = 0, -+ .screen_size = 0, -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, -+ .pitch = 0, -+ }; -+ int ret; - - print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, - info->var.xres, info->var.yres, info->var.xres_virtual, - info->var.yres_virtual, (int)info->screen_size, - info->var.bits_per_pixel); - -- /* ensure last write to fbinfo is visible to GPU */ -- wmb(); -- -- /* inform vc about new framebuffer */ -- bcm_mailbox_write(MBOX_CHAN_FB, fb->dma); -- -- /* TODO: replace fb driver with vchiq version */ -- /* wait for response */ -- bcm_mailbox_read(MBOX_CHAN_FB, &val); -- -- /* ensure GPU writes are visible to us */ -- rmb(); -- -- if (val == 0) { -- fb->fb.fix.line_length = fbinfo->pitch; -- -- if (info->var.bits_per_pixel <= 8) -- fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; -- else -- fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; -- -- fb->fb_bus_address = fbinfo->base; -- fbinfo->base &= ~0xc0000000; -- fb->fb.fix.smem_start = fbinfo->base; -- fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; -- fb->fb.screen_size = fbinfo->screen_size; -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- fb->fb.screen_base = -- (void *)ioremap_wc(fbinfo->base, fb->fb.screen_size); -- if (!fb->fb.screen_base) { -- /* the console may currently be locked */ -- console_trylock(); -- console_unlock(); -- pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); -- return -EIO; -- } -+ ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); -+ if (ret) { -+ dev_err(info->device, -+ "Failed to allocate GPU framebuffer (%d)\n", ret); -+ return ret; - } -+ -+ if (info->var.bits_per_pixel <= 8) -+ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ else -+ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; -+ -+ fb->fb.fix.line_length = fbinfo.pitch; -+ fbinfo.base |= 0x40000000; -+ fb->fb_bus_address = fbinfo.base; -+ fbinfo.base &= ~0xc0000000; -+ fb->fb.fix.smem_start = fbinfo.base; -+ fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; -+ fb->fb.screen_size = fbinfo.screen_size; -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); -+ if (!fb->fb.screen_base) { -+ /* the console may currently be locked */ -+ console_trylock(); -+ console_unlock(); -+ dev_err(info->device, "Failed to set screen_base\n"); -+ return -ENOMEM; -+ } -+ - print_debug -- ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", -+ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", - (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, -- fbinfo->xres, fbinfo->yres, fbinfo->bpp, -- fbinfo->pitch, (int)fb->fb.screen_size, val); -+ fbinfo.xres, fbinfo.yres, fbinfo.bpp, -+ fbinfo.pitch, (int)fb->fb.screen_size); - -- return val; -+ return 0; - } - - static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) -@@ -352,15 +358,34 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, - /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ - if (fb->fb.var.bits_per_pixel <= 8) { - if (regno < 256) { -- /* blue [0:4], green [5:10], red [11:15] */ -- fb->info->cmap[regno] = ((red >> (16-5)) & 0x1f) << 11 | -- ((green >> (16-6)) & 0x3f) << 5 | -- ((blue >> (16-5)) & 0x1f) << 0; -+ /* blue [23:16], green [15:8], red [7:0] */ -+ fb->gpu_cmap[regno] = ((red >> 8) & 0xff) << 0 | -+ ((green >> 8) & 0xff) << 8 | -+ ((blue >> 8) & 0xff) << 16; - } - /* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */ - /* So just call it for what looks like the last colour in a list for now. */ -- if (regno == 15 || regno == 255) -- bcm2708_fb_set_par(info); -+ if (regno == 15 || regno == 255) { -+ struct packet { -+ u32 offset; -+ u32 length; -+ u32 cmap[256]; -+ } *packet; -+ int ret; -+ -+ packet = kmalloc(sizeof(*packet), GFP_KERNEL); -+ if (!packet) -+ return -ENOMEM; -+ packet->offset = 0; -+ packet->length = regno + 1; -+ memcpy(packet->cmap, fb->gpu_cmap, sizeof(packet->cmap)); -+ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, -+ packet, (2 + packet->length) * sizeof(u32)); -+ if (ret || packet->offset) -+ dev_err(info->device, "Failed to set palette (%d,%u)\n", -+ ret, packet->offset); -+ kfree(packet); -+ } - } else if (regno < 16) { - fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | - convert_bitfield(blue, &fb->fb.var.blue) | -@@ -372,27 +397,31 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, - - static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) - { -- s32 result = -1; -- u32 p[7]; -- if ( (blank_mode == FB_BLANK_NORMAL) || -- (blank_mode == FB_BLANK_UNBLANK)) { -- -- p[0] = 28; // size = sizeof u32 * length of p -- p[1] = VCMSG_PROCESS_REQUEST; // process request -- p[2] = VCMSG_SET_BLANK_SCREEN; // (the tag id) -- p[3] = 4; // (size of the response buffer) -- p[4] = 4; // (size of the request data) -- p[5] = blank_mode; -- p[6] = VCMSG_PROPERTY_END; // end tag -- -- bcm_mailbox_property(&p, p[0]); -- -- if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -- result = 0; -- else -- pr_err("bcm2708_fb_blank(%d) returns=%d p[1]=0x%x\n", blank_mode, p[5], p[1]); -+ struct bcm2708_fb *fb = to_bcm2708(info); -+ u32 value; -+ int ret; -+ -+ switch (blank_mode) { -+ case FB_BLANK_UNBLANK: -+ value = 0; -+ break; -+ case FB_BLANK_NORMAL: -+ case FB_BLANK_VSYNC_SUSPEND: -+ case FB_BLANK_HSYNC_SUSPEND: -+ case FB_BLANK_POWERDOWN: -+ value = 1; -+ break; -+ default: -+ return -EINVAL; - } -- return result; -+ -+ ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, -+ &value, sizeof(value)); -+ if (ret) -+ dev_err(info->device, "bcm2708_fb_blank(%d) failed: %d\n", -+ blank_mode, ret); -+ -+ return ret; - } - - static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) -@@ -408,25 +437,25 @@ static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info - - static int bcm2708_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) - { -- s32 result = -1; -- u32 p[7]; -- if (cmd == FBIO_WAITFORVSYNC) { -- p[0] = 28; // size = sizeof u32 * length of p -- p[1] = VCMSG_PROCESS_REQUEST; // process request -- p[2] = VCMSG_SET_VSYNC; // (the tag id) -- p[3] = 4; // (size of the response buffer) -- p[4] = 4; // (size of the request data) -- p[5] = 0; // dummy -- p[6] = VCMSG_PROPERTY_END; // end tag -- -- bcm_mailbox_property(&p, p[0]); -- -- if ( p[1] == VCMSG_REQUEST_SUCCESSFUL ) -- result = 0; -- else -- pr_err("bcm2708_fb_ioctl %x,%lx returns=%d p[1]=0x%x\n", cmd, arg, p[5], p[1]); -+ struct bcm2708_fb *fb = to_bcm2708(info); -+ u32 dummy = 0; -+ int ret; -+ -+ switch (cmd) { -+ case FBIO_WAITFORVSYNC: -+ ret = rpi_firmware_property(fb->fw, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC, -+ &dummy, sizeof(dummy)); -+ break; -+ default: -+ dev_err(info->device, "Unknown ioctl 0x%x\n", cmd); -+ return -EINVAL; - } -- return result; -+ -+ if (ret) -+ dev_err(info->device, "ioctl 0x%x failed (%d)\n", cmd, ret); -+ -+ return ret; - } - static void bcm2708_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -@@ -621,20 +650,7 @@ static struct fb_ops bcm2708_fb_ops = { - static int bcm2708_fb_register(struct bcm2708_fb *fb) - { - int ret; -- dma_addr_t dma; -- void *mem; -- -- mem = -- dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, -- GFP_KERNEL); - -- if (NULL == mem) { -- pr_err(": unable to allocate fbinfo buffer\n"); -- ret = -ENOMEM; -- } else { -- fb->info = (struct fbinfo_s *)mem; -- fb->dma = dma; -- } - fb->fb.fbops = &bcm2708_fb_ops; - fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA; - fb->fb.pseudo_palette = fb->cmap; -@@ -693,9 +709,22 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - - static int bcm2708_fb_probe(struct platform_device *dev) - { -+ struct device_node *fw_np; -+ struct rpi_firmware *fw; - struct bcm2708_fb *fb; - int ret; - -+ fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0); -+/* Remove comment when booting without Device Tree is no longer supported -+ if (!fw_np) { -+ dev_err(&dev->dev, "Missing firmware node\n"); -+ return -ENOENT; -+ } -+*/ -+ fw = rpi_firmware_get(fw_np); -+ if (!fw) -+ return -EPROBE_DEFER; -+ - fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); - if (!fb) { - dev_err(&dev->dev, -@@ -704,6 +733,7 @@ static int bcm2708_fb_probe(struct platform_device *dev) - goto free_region; - } - -+ fb->fw = fw; - bcm2708_fb_debugfs_init(fb); - - fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, -@@ -737,6 +767,7 @@ static int bcm2708_fb_probe(struct platform_device *dev) - fb->dma_chan, fb->dma_chan_base); - - fb->dev = dev; -+ fb->fb.device = &dev->dev; - - ret = bcm2708_fb_register(fb); - if (ret == 0) { -@@ -769,8 +800,6 @@ static int bcm2708_fb_remove(struct platform_device *dev) - dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); - bcm_dma_chan_free(fb->dma_chan); - -- dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, -- fb->dma); - bcm2708_fb_debugfs_deinit(fb); - - free_irq(fb->dma_irq, fb); - -From e24a0ff68aeded060486f55911653aec60ea87c7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 20 Jul 2015 12:27:17 +0200 -Subject: [PATCH 138/204] bcm2835: Add firmware property to affected devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Also move firmware depending devices to the rpi dtsi file since -they depend on the Pi specific firmware. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 22 ++++++++++++++++++---- - arch/arm/boot/dts/bcm2835.dtsi | 15 --------------- - 2 files changed, 18 insertions(+), 19 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index 5cdfd5a..6c3daaf 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -32,6 +32,24 @@ - compatible = "raspberrypi,bcm2835-firmware"; - mboxes = <&mailbox>; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ firmware = <&firmware>; -+ }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ firmware = <&firmware>; -+ }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ cache-line-size = <32>; -+ firmware = <&firmware>; -+ }; - }; - - /* Onboard audio */ -@@ -101,10 +119,6 @@ - bus-width = <4>; - }; - --&fb { -- status = "okay"; --}; -- - / { - __overrides__ { - i2s = <&i2s>,"status"; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 1135120..807264d 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -160,21 +160,6 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -- -- fb: fb { -- compatible = "brcm,bcm2708-fb"; -- status = "disabled"; -- }; -- -- vchiq: vchiq { -- compatible = "brcm,bcm2835-vchiq"; -- reg = <0x7e00b840 0xf>; -- interrupts = <0 2>; -- }; -- -- thermal: thermal { -- compatible = "brcm,bcm2835-thermal"; -- }; - }; - - clocks { - -From 4fa2f3a62adf17ef122476d8fc63b132a717d71f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 21 Jul 2015 19:09:39 +0200 -Subject: [PATCH 139/204] rpi-ft5406: Use firmware API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 1 + - drivers/input/touchscreen/rpi-ft5406.c | 74 ++++++++++------------- - 2 files changed, 32 insertions(+), 43 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -index 40deab5..2e53a17 100644 ---- a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -@@ -9,6 +9,7 @@ - __overlay__ { - rpi_ft5406: rpi_ft5406 { - compatible = "rpi,rpi-ft5406"; -+ firmware = <&firmware>; - status = "okay"; - }; - }; -diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c -index d41851d..c08817e 100644 ---- a/drivers/input/touchscreen/rpi-ft5406.c -+++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -21,7 +21,7 @@ - #include - #include - #include --#include -+#include - - #define MAXIMUM_SUPPORTED_POINTS 10 - struct ft5406_regs { -@@ -49,23 +49,6 @@ struct ft5406 { - struct task_struct * thread; - }; - -- --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the message id */ -- uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ -- uint32_t data_size; /* amount of data being sent or received */ -- uint32_t val; /* data buffer */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- - /* Thread to poll for touchscreen events - * - * This thread polls the memory based register copy of the ft5406 registers -@@ -136,11 +119,37 @@ static int ft5406_probe(struct platform_device *pdev) - { - int ret; - struct input_dev * input_dev = input_allocate_device(); -- struct vc_msg request; - struct ft5406 * ts; -+ struct device_node *fw_node; -+ struct rpi_firmware *fw; -+ u32 touchbuf; - - dev_info(&pdev->dev, "Probing device\n"); - -+ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); -+ if (!fw_node) { -+ dev_err(&pdev->dev, "Missing firmware node\n"); -+ return -ENOENT; -+ } -+ -+ fw = rpi_firmware_get(fw_node); -+ if (!fw) -+ return -EPROBE_DEFER; -+ -+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF, -+ &touchbuf, sizeof(touchbuf)); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to get touch buffer\n"); -+ return ret; -+ } -+ -+ if (!touchbuf) { -+ dev_err(&pdev->dev, "Touchscreen not detected\n"); -+ return -ENODEV; -+ } -+ -+ dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", touchbuf); -+ - ts = kzalloc(sizeof(struct ft5406), GFP_KERNEL); - - if (!ts || !input_dev) { -@@ -174,36 +183,15 @@ static int ft5406_probe(struct platform_device *pdev) - return ret; - } - -- memset(&request, 0, sizeof request); -- -- request.msg_size = sizeof request; -- request.request_code = VCMSG_PROCESS_REQUEST; -- request.tag.tag_id = VCMSG_GET_TOUCHBUF; -- request.tag.buffer_size = 4; -- request.tag.data_size = 4; -- -- bcm_mailbox_property(&request, sizeof(request)); -- -- if(request.request_code == VCMSG_REQUEST_SUCCESSFUL && request.tag.val != 0) -- { -- dev_dbg(&pdev->dev, "Got TS buffer 0x%x\n", request.tag.val); -- } -- else -- { -- input_unregister_device(input_dev); -- kzfree(ts); -- return -1; -- } -- - // mmap the physical memory -- request.tag.val &= ~0xc0000000; -- ts->ts_base = ioremap(request.tag.val, sizeof(*ts->regs)); -+ touchbuf &= ~0xc0000000; -+ ts->ts_base = ioremap(touchbuf, sizeof(*ts->regs)); - if(ts->ts_base == NULL) - { - dev_err(&pdev->dev, "Failed to map physical address\n"); - input_unregister_device(input_dev); - kzfree(ts); -- return -1; -+ return -ENOMEM; - } - - ts->regs = (struct ft5406_regs *) ts->ts_base; - -From 70b5d66ef90adc3ee74708ecf15fd5fd3c6a3f9e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 12 Jun 2015 19:01:05 +0200 -Subject: [PATCH 140/204] irqchip: bcm2835: Add FIQ support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a duplicate irq range with an offset on the hwirq's so the -driver can detect that enable_fiq() is used. -Tested with downstream dwc_otg USB controller driver. - -Signed-off-by: Noralf Trønnes -Reviewed-by: Eric Anholt -Acked-by: Stephen Warren ---- - arch/arm/mach-bcm/Kconfig | 1 + - drivers/irqchip/irq-bcm2835.c | 53 ++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 48 insertions(+), 6 deletions(-) - -diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig -index 8b11f44..7cfef7b 100644 ---- a/arch/arm/mach-bcm/Kconfig -+++ b/arch/arm/mach-bcm/Kconfig -@@ -114,6 +114,7 @@ config ARCH_BCM2835 - select ARM_ERRATA_411920 - select ARM_TIMER_SP804 - select CLKSRC_OF -+ select FIQ - select PINCTRL - select PINCTRL_BCM2835 - help -diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c -index 5916d6c..db66246 100644 ---- a/drivers/irqchip/irq-bcm2835.c -+++ b/drivers/irqchip/irq-bcm2835.c -@@ -56,7 +56,7 @@ - #include "irqchip.h" - - /* Put the bank and irq (32 bits) into the hwirq */ --#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) -+#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) - #define HWIRQ_BANK(i) (i >> 5) - #define HWIRQ_BIT(i) BIT(i & 0x1f) - -@@ -72,9 +72,13 @@ - | SHORTCUT1_MASK | SHORTCUT2_MASK) - - #define REG_FIQ_CONTROL 0x0c -+#define REG_FIQ_ENABLE 0x80 -+#define REG_FIQ_DISABLE 0 - - #define NR_BANKS 3 - #define IRQS_PER_BANK 32 -+#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) -+#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) - - static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; - static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; -@@ -98,14 +102,38 @@ static struct armctrl_ic intc __read_mostly; - static void __exception_irq_entry bcm2835_handle_irq( - struct pt_regs *regs); - -+static inline unsigned int hwirq_to_fiq(unsigned long hwirq) -+{ -+ hwirq -= NUMBER_IRQS; -+ /* -+ * The hwirq numbering used in this driver is: -+ * BASE (0-7) GPU1 (32-63) GPU2 (64-95). -+ * This differ from the one used in the FIQ register: -+ * GPU1 (0-31) GPU2 (32-63) BASE (64-71) -+ */ -+ if (hwirq >= 32) -+ return hwirq - 32; -+ -+ return hwirq + 64; -+} -+ - static void armctrl_mask_irq(struct irq_data *d) - { -- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); -+ if (d->hwirq >= NUMBER_IRQS) -+ writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); -+ else -+ writel_relaxed(HWIRQ_BIT(d->hwirq), -+ intc.disable[HWIRQ_BANK(d->hwirq)]); - } - - static void armctrl_unmask_irq(struct irq_data *d) - { -- writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); -+ if (d->hwirq >= NUMBER_IRQS) -+ writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), -+ intc.base + REG_FIQ_CONTROL); -+ else -+ writel_relaxed(HWIRQ_BIT(d->hwirq), -+ intc.enable[HWIRQ_BANK(d->hwirq)]); - } - - static struct irq_chip armctrl_chip = { -@@ -150,8 +178,9 @@ static int __init armctrl_of_init(struct device_node *node, - panic("%s: unable to map IC registers\n", - node->full_name); - -- intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), -- &armctrl_ops, NULL); -+ intc.base = base; -+ intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2, -+ &armctrl_ops, NULL); - if (!intc.domain) - panic("%s: unable to create IRQ domain\n", node->full_name); - -@@ -168,8 +197,20 @@ static int __init armctrl_of_init(struct device_node *node, - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - } -- - set_handle_irq(bcm2835_handle_irq); -+ -+ /* Make a duplicate irq range which is used to enable FIQ */ -+ for (b = 0; b < NR_BANKS; b++) { -+ for (i = 0; i < bank_irqs[b]; i++) { -+ irq = irq_create_mapping(intc.domain, -+ MAKE_HWIRQ(b, i) + NUMBER_IRQS); -+ BUG_ON(irq <= 0); -+ irq_set_chip(irq, &armctrl_chip); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -+ } -+ } -+ init_FIQ(FIQ_START); -+ - return 0; - } - - -From 48ff5ec47ad9778a6d2eb5d75ee2e161302673fa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 15:50:04 +0200 -Subject: [PATCH 141/204] dwc_otg: Add ARCH_BCM2835 support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1 + - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 1 - - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 4 ++++ - 3 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -index 53307f0..95edadf 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -723,6 +723,7 @@ static int dwc_otg_driver_probe( - - memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); - dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF; -+ dwc_otg_device->os_dep.platformdev = _dev; - - /* - * Map the DWC_otg Core memory into virtual address space. -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index 8a31562..3f71f29 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -36,7 +36,6 @@ - #include "dwc_otg_regs.h" - - #include --#include - #include - - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -index 0f4ebcd..5c83309 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -445,7 +445,11 @@ static void hcd_init_fiq(void *cookie) - DWC_WARN("MPHI periph has NOT been enabled"); - #endif - // Enable FIQ interrupt from USB peripheral -+#ifdef CONFIG_ARCH_BCM2835 -+ enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1)); -+#else - enable_fiq(INTERRUPT_VC_USB); -+#endif - local_fiq_enable(); - } - - -From 28a1fd2b8afaf5524cca8890394f9fc07c8a8b71 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 15:50:24 +0200 -Subject: [PATCH 142/204] bcm2835: Use DWC_OTG -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 8 +++++--- - arch/arm/configs/bcm2835_defconfig | 1 + - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 807264d..8a5d6ec 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -152,9 +152,11 @@ - }; - - usb: usb@7e980000 { -- compatible = "brcm,bcm2835-usb"; -- reg = <0x7e980000 0x10000>; -- interrupts = <1 9>; -+ compatible = "brcm,bcm2708-usb"; -+ reg = <0x7e980000 0x10000>, -+ <0x7e006000 0x1000>; -+ interrupts = <2 0>, -+ <1 9>; - }; - - arm-pmu { -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index c284414..14ef294 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -869,6 +869,7 @@ CONFIG_USB_HIDDEV=y - CONFIG_USB=y - CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_MON=m -+CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m - CONFIG_USB_STORAGE=y - CONFIG_USB_STORAGE_REALTEK=m - -From cf7a056866fba1d602de661a47cd0548dfe2304b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:33:16 +0200 -Subject: [PATCH 143/204] Fix RASPBERRYPI_FIRMWARE dependents -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If forgot this when converting the drivers. - -Signed-off-by: Noralf Trønnes ---- - drivers/cpufreq/Kconfig.arm | 2 +- - drivers/input/touchscreen/Kconfig | 2 +- - drivers/misc/vc04_services/Kconfig | 2 +- - drivers/thermal/Kconfig | 2 +- - drivers/video/fbdev/Kconfig | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index a1039f0..0037516 100644 ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -259,7 +259,7 @@ config ARM_SPEAR_CPUFREQ - This adds the CPUFreq driver support for SPEAr SOCs. - - config ARM_BCM2835_CPUFREQ -- depends on BCM2708_MBOX -+ depends on RASPBERRYPI_FIRMWARE - bool "BCM2835 Driver" - default y - help -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 5848562..d7e74a1 100644 ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -585,7 +585,7 @@ config TOUCHSCREEN_EDT_FT5X06 - - config TOUCHSCREEN_RPI_FT5406 - tristate "Raspberry Pi FT5406 driver" -- depends on ARCH_BCM2708 || ARCH_BCM2709 -+ depends on RASPBERRYPI_FIRMWARE - help - Say Y here to enable the Raspberry Pi memory based FT5406 device - -diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig -index c5ba283..db8e1be 100644 ---- a/drivers/misc/vc04_services/Kconfig -+++ b/drivers/misc/vc04_services/Kconfig -@@ -1,6 +1,6 @@ - config BCM2708_VCHIQ - tristate "Videocore VCHIQ" -- depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX -+ depends on RASPBERRYPI_FIRMWARE - default y - help - Kernel to VideoCore communication interface for the -diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index ddc77ad..b911213 100644 ---- a/drivers/thermal/Kconfig -+++ b/drivers/thermal/Kconfig -@@ -239,7 +239,7 @@ config INTEL_POWERCLAMP - user interface is exposed via generic thermal framework. - - config THERMAL_BCM2835 -- depends on BCM2708_MBOX -+ depends on RASPBERRYPI_FIRMWARE - tristate "BCM2835 Thermal Driver" - help - This will enable temperature monitoring for the Broadcom BCM2835 -diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index b89998b7..08678b9 100644 ---- a/drivers/video/fbdev/Kconfig -+++ b/drivers/video/fbdev/Kconfig -@@ -226,7 +226,7 @@ comment "Frame buffer hardware drivers" - - config FB_BCM2708 - tristate "BCM2708 framebuffer support" -- depends on FB && ARM && BCM2708_MBOX -+ depends on FB && RASPBERRYPI_FIRMWARE - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - -From 16b9943dbfbc7d7f19f44e91808dc1450ca9d4b4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:33:46 +0200 -Subject: [PATCH 144/204] vc_mem: Remove unnecessary include -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - drivers/char/broadcom/vc_mem.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c -index fcde6b1..be64f23 100644 ---- a/drivers/char/broadcom/vc_mem.c -+++ b/drivers/char/broadcom/vc_mem.c -@@ -22,7 +22,6 @@ - #include - #include - #include --#include - #include - - #define DRIVER_NAME "vc-mem" - -From d98428b8e2a5bb9815aaa3eed3e0777f50f55196 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:34:06 +0200 -Subject: [PATCH 145/204] configs: Remove BCM2708_MBOX -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 1 - - arch/arm/configs/bcm2835_defconfig | 1 - - arch/arm/configs/bcmrpi_defconfig | 1 - - 3 files changed, 3 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index dd00e7c..e3155da 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1078,7 +1078,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y --CONFIG_BCM2708_MBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 14ef294..24d4df6 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -1065,7 +1065,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y --CONFIG_BCM2708_MBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 7b24274..0859113 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1071,7 +1071,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y --CONFIG_BCM2708_MBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - -From b3b0ebfd9dd4bcd6fe8d787aa7740a47f419da9f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:34:31 +0200 -Subject: [PATCH 146/204] bcm2708-vcio: Remove module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -All drivers have been converted to the new firmware API, so this -module is not needed anymore. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 6 -- - drivers/mailbox/Makefile | 2 - - drivers/mailbox/bcm2708-vcio.c | 86 ----------------- - include/linux/platform_data/mailbox-bcm2708.h | 127 -------------------------- - 4 files changed, 221 deletions(-) - delete mode 100644 drivers/mailbox/bcm2708-vcio.c - delete mode 100644 include/linux/platform_data/mailbox-bcm2708.h - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index d1a6671..3965e10 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -7,12 +7,6 @@ menuconfig MAILBOX - - if MAILBOX - --config BCM2708_MBOX -- bool "Broadcom BCM2708 Mailbox (vcio)" -- depends on BCM2835_MBOX -- help -- Broadcom BCM2708 Mailbox (vcio) -- - config ARM_MHU - tristate "ARM MHU Mailbox" - depends on ARM_AMBA -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index c86bc91..8e6d822 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -2,8 +2,6 @@ - - obj-$(CONFIG_MAILBOX) += mailbox.o - --obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o -- - obj-$(CONFIG_ARM_MHU) += arm_mhu.o - - obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -deleted file mode 100644 -index 2e4031b..0000000 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ /dev/null -@@ -1,86 +0,0 @@ --/* -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for writing to the mailboxes, -- * semaphores, doorbells etc. that are shared between the ARM and the -- * VideoCore processor -- */ -- --#include --#include --#include --#include --#include --#include -- --#define DRIVER_NAME "bcm2708_vcio" -- --extern int bcm_mailbox_write(unsigned chan, uint32_t data28) --{ -- struct rpi_firmware *fw = rpi_firmware_get(NULL); -- -- if (!fw) -- return -ENODEV; -- -- return rpi_firmware_transaction(fw, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_write); -- --extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) --{ -- struct rpi_firmware *fw = rpi_firmware_get(NULL); -- -- if (!fw) -- return -ENODEV; -- -- *data28 = rpi_firmware_transaction_received(fw); -- -- return 0; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -- --static DEFINE_MUTEX(mailbox_lock); --extern int bcm_mailbox_property(void *data, int size) --{ -- uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -- int s = 0; -- -- mutex_lock(&mailbox_lock); -- /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -- GFP_KERNEL); -- if (mem_kern) { -- /* create the message */ -- memcpy(mem_kern, data, size); -- -- /* send the message */ -- wmb(); -- s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) -- s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- if (s == 0) { -- /* copy the response */ -- rmb(); -- memcpy(data, mem_kern, size); -- } -- dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -- } else { -- s = -ENOMEM; -- } -- if (s != 0) -- pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -- -- mutex_unlock(&mailbox_lock); -- return s; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_property); -- --MODULE_AUTHOR("Gray Girling"); --MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); --MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -deleted file mode 100644 -index d3ea839..0000000 ---- a/include/linux/platform_data/mailbox-bcm2708.h -+++ /dev/null -@@ -1,127 +0,0 @@ --/* -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- */ --#ifndef _PLAT_MAILBOX_BCM2708_H --#define _PLAT_MAILBOX_BCM2708_H -- --/* Routines to handle I/O via the VideoCore "ARM control" registers -- * (semaphores, doorbells, mailboxes) -- */ -- --/* Constants shared with the ARM identifying separate mailbox channels */ --#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ --#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ --#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ --#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ --#define MBOX_CHAN_COUNT 9 -- --enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 --}; -- --enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 --}; -- --/* Mailbox property tags */ --enum { -- VCMSG_PROPERTY_END = 0x00000000, -- VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -- VCMSG_GET_BOARD_MODEL = 0x00010001, -- VCMSG_GET_BOARD_REVISION = 0x00010002, -- VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -- VCMSG_GET_BOARD_SERIAL = 0x00010004, -- VCMSG_GET_ARM_MEMORY = 0x00010005, -- VCMSG_GET_VC_MEMORY = 0x00010006, -- VCMSG_GET_CLOCKS = 0x00010007, -- VCMSG_GET_COMMAND_LINE = 0x00050001, -- VCMSG_GET_DMA_CHANNELS = 0x00060001, -- VCMSG_GET_POWER_STATE = 0x00020001, -- VCMSG_GET_TIMING = 0x00020002, -- VCMSG_SET_POWER_STATE = 0x00028001, -- VCMSG_GET_CLOCK_STATE = 0x00030001, -- VCMSG_SET_CLOCK_STATE = 0x00038001, -- VCMSG_GET_CLOCK_RATE = 0x00030002, -- VCMSG_SET_CLOCK_RATE = 0x00038002, -- VCMSG_GET_VOLTAGE = 0x00030003, -- VCMSG_SET_VOLTAGE = 0x00038003, -- VCMSG_GET_MAX_CLOCK = 0x00030004, -- VCMSG_GET_MAX_VOLTAGE = 0x00030005, -- VCMSG_GET_TEMPERATURE = 0x00030006, -- VCMSG_GET_MIN_CLOCK = 0x00030007, -- VCMSG_GET_MIN_VOLTAGE = 0x00030008, -- VCMSG_GET_TURBO = 0x00030009, -- VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -- VCMSG_GET_STC = 0x0003000b, -- VCMSG_SET_TURBO = 0x00038009, -- VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -- VCMSG_SET_LOCK_MEM = 0x0003000d, -- VCMSG_SET_UNLOCK_MEM = 0x0003000e, -- VCMSG_SET_RELEASE_MEM = 0x0003000f, -- VCMSG_SET_EXECUTE_CODE = 0x00030010, -- VCMSG_SET_EXECUTE_QPU = 0x00030011, -- VCMSG_SET_ENABLE_QPU = 0x00030012, -- VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -- VCMSG_GET_EDID_BLOCK = 0x00030020, -- VCMSG_GET_CUSTOMER_OTP = 0x00030021, -- VCMSG_SET_CUSTOMER_OTP = 0x00038021, -- VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -- VCMSG_SET_RELEASE_BUFFER = 0x00048001, -- VCMSG_SET_BLANK_SCREEN = 0x00040002, -- VCMSG_TST_BLANK_SCREEN = 0x00044002, -- VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -- VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -- VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -- VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -- VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -- VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -- VCMSG_GET_DEPTH = 0x00040005, -- VCMSG_TST_DEPTH = 0x00044005, -- VCMSG_SET_DEPTH = 0x00048005, -- VCMSG_GET_PIXEL_ORDER = 0x00040006, -- VCMSG_TST_PIXEL_ORDER = 0x00044006, -- VCMSG_SET_PIXEL_ORDER = 0x00048006, -- VCMSG_GET_ALPHA_MODE = 0x00040007, -- VCMSG_TST_ALPHA_MODE = 0x00044007, -- VCMSG_SET_ALPHA_MODE = 0x00048007, -- VCMSG_GET_PITCH = 0x00040008, -- VCMSG_TST_PITCH = 0x00044008, -- VCMSG_SET_PITCH = 0x00048008, -- VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -- VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -- VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -- VCMSG_GET_OVERSCAN = 0x0004000a, -- VCMSG_TST_OVERSCAN = 0x0004400a, -- VCMSG_SET_OVERSCAN = 0x0004800a, -- VCMSG_GET_PALETTE = 0x0004000b, -- VCMSG_TST_PALETTE = 0x0004400b, -- VCMSG_SET_PALETTE = 0x0004800b, -- VCMSG_GET_LAYER = 0x0004000c, -- VCMSG_TST_LAYER = 0x0004400c, -- VCMSG_SET_LAYER = 0x0004800c, -- VCMSG_GET_TRANSFORM = 0x0004000d, -- VCMSG_TST_TRANSFORM = 0x0004400d, -- VCMSG_SET_TRANSFORM = 0x0004800d, -- VCMSG_TST_VSYNC = 0x0004400e, -- VCMSG_SET_VSYNC = 0x0004800e, -- VCMSG_GET_TOUCHBUF = 0x0004000f, -- VCMSG_SET_CURSOR_INFO = 0x00008010, -- VCMSG_SET_CURSOR_STATE = 0x00008011, --}; -- --int bcm_mailbox_read(unsigned chan, uint32_t *data28); --int bcm_mailbox_write(unsigned chan, uint32_t data28); --int bcm_mailbox_property(void *data, int size); -- --#endif - -From 6fadac31b6bf0690059342642ff4453d6d95a2d8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 24 Jul 2015 19:34:55 +0200 -Subject: [PATCH 147/204] Revert "firmware: bcm2835: Support legacy mailbox - API" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 40aa3c4f0c430cd5c574498f4d1d5e9f0bc1cf11. - -The legacy mailbox API has been removed so this is not needed. - -Signed-off-by: Noralf Trønnes ---- - drivers/firmware/raspberrypi.c | 15 ++------------- - include/soc/bcm2835/raspberrypi-firmware.h | 2 -- - 2 files changed, 2 insertions(+), 15 deletions(-) - -diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c -index 89421a9..b980d53 100644 ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -19,7 +19,6 @@ - #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) - #define MBOX_CHAN(msg) ((msg) & 0xf) - #define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_CHAN_VCHIQ 3 - #define MBOX_CHAN_PROPERTY 8 - - struct rpi_firmware { -@@ -27,7 +26,6 @@ struct rpi_firmware { - struct mbox_chan *chan; /* The property channel. */ - struct completion c; - u32 enabled; -- u32 received; - }; - - static struct platform_device *g_pdev; -@@ -37,7 +35,6 @@ static DEFINE_MUTEX(transaction_lock); - static void response_callback(struct mbox_client *cl, void *msg) - { - struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl); -- fw->received = *(u32 *)msg; - complete(&fw->c); - } - -@@ -45,7 +42,7 @@ static void response_callback(struct mbox_client *cl, void *msg) - * Sends a request to the firmware through the BCM2835 mailbox driver, - * and synchronously waits for the reply. - */ --int -+static int - rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - { - u32 message = MBOX_MSG(chan, data); -@@ -57,8 +54,7 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - reinit_completion(&fw->c); - ret = mbox_send_message(fw->chan, &message); - if (ret >= 0) { -- if (chan != MBOX_CHAN_VCHIQ) -- wait_for_completion(&fw->c); -+ wait_for_completion(&fw->c); - ret = 0; - } else { - dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); -@@ -67,13 +63,6 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) - - return ret; - } --EXPORT_SYMBOL(rpi_firmware_transaction); -- --u32 rpi_firmware_transaction_received(struct rpi_firmware *fw) --{ -- return MBOX_DATA28(fw->received); --} --EXPORT_SYMBOL(rpi_firmware_transaction_received); - - /** - * rpi_firmware_property_list - Submit firmware property list -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index 9a08cf1..d3933af 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -116,8 +116,6 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - }; - --int rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data); --u32 rpi_firmware_transaction_received(struct rpi_firmware *fw); - int rpi_firmware_property(struct rpi_firmware *fw, - u32 tag, void *data, size_t len); - int rpi_firmware_property_list(struct rpi_firmware *fw, - -From 9418fab5167ef4095a62ba3b11d9e420595cf559 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 30 Jun 2015 12:35:39 +0100 -Subject: [PATCH 148/204] pinctrl: bcm2835: Clear the event latch register when - disabling interrupts - -It's possible to hit a race condition if interrupts are generated on a GPIO -pin when the IRQ line in question is being disabled. - -If the interrupt is freed, bcm2835_gpio_irq_disable() is called which -disables the event generation sources (edge, level). If an event occurred -between the last disabling of hard IRQs and the write to the event -source registers, a bit would be set in the GPIO event detect register -(GPEDSn) which goes unacknowledged by bcm2835_gpio_irq_handler() -so Linux complains loudly. - -There is no per-GPIO mask register, so when disabling GPIO interrupts -write 1 to the relevant bit in GPEDSn to clear out any stale events. - -Signed-off-by: Jonathan Bell -Acked-by: Stephen Warren -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 986779a..61ef002 100644 ---- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -@@ -503,6 +503,8 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data) - - spin_lock_irqsave(&pc->irq_lock[bank], flags); - bcm2835_gpio_irq_config(pc, gpio, false); -+ /* Clear events that were latched prior to clearing event sources */ -+ bcm2835_gpio_set_bit(pc, GPEDS0, gpio); - clear_bit(offset, &pc->enabled_irq_map[bank]); - spin_unlock_irqrestore(&pc->irq_lock[bank], flags); - } - -From 1a099cd189c09d3dc5d2e0ed2061cb9b0dcd2a0b Mon Sep 17 00:00:00 2001 -From: P33M -Date: Tue, 4 Aug 2015 01:15:20 +0100 -Subject: [PATCH 149/204] dwc_otg: fiq_fsm: Make high-speed isochronous strided - transfers work properly - -Certain low-bandwidth high-speed USB devices (specialist audio devices, -compressed-frame webcams) have packet intervals > 1 microframe. - -Stride these transfers in the FIQ by using the start-of-frame interrupt -to restart the channel at the right time. ---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 17 +++++++++++++---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 5 ++++- - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 7 ++++++- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 6 ++++-- - 4 files changed, 27 insertions(+), 8 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -index 7e0c726..85d82f3 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -615,8 +615,11 @@ static int notrace noinline fiq_fsm_do_sof(struct fiq_state *state, int num_chan - break; - - case FIQ_HS_ISOC_SLEEPING: -- state->channel[n].fsm = FIQ_HS_ISOC_TURBO; -- fiq_fsm_restart_channel(state, n, 0); -+ /* Is it time to wake this channel yet? */ -+ if (--state->channel[n].uframe_sleeps == 0) { -+ state->channel[n].fsm = FIQ_HS_ISOC_TURBO; -+ fiq_fsm_restart_channel(state, n, 0); -+ } - break; - - case FIQ_PER_SSPLIT_QUEUED: -@@ -624,7 +627,7 @@ static int notrace noinline fiq_fsm_do_sof(struct fiq_state *state, int num_chan - break; - if(!fiq_fsm_tt_in_use(state, num_channels, n)) { - if (!fiq_fsm_too_late(state, n)) { -- fiq_print(FIQDBG_INT, st, "SOF GO %01d", n); -+ fiq_print(FIQDBG_INT, state, "SOF GO %01d", n); - fiq_fsm_restart_channel(state, n, 0); - state->channel[n].fsm = FIQ_PER_SSPLIT_STARTED; - } else { -@@ -1069,8 +1072,14 @@ static int notrace noinline fiq_fsm_do_hcintr(struct fiq_state *state, int num_c - if (fiq_fsm_update_hs_isoc(state, n, hcint)) { - /* more transactions to come */ - handled = 1; -- restart = 1; - fiq_print(FIQDBG_INT, state, "HSISO M "); -+ /* For strided transfers, put ourselves to sleep */ -+ if (st->hs_isoc_info.stride > 1) { -+ st->uframe_sleeps = st->hs_isoc_info.stride - 1; -+ st->fsm = FIQ_HS_ISOC_SLEEPING; -+ } else { -+ restart = 1; -+ } - } else { - st->fsm = FIQ_HS_ISOC_DONE; - fiq_print(FIQDBG_INT, state, "HSISO F "); -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -index 8455324..f9fddfb 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -260,12 +260,13 @@ struct fiq_dma_blob { - * @iso_frame: Pointer to the array of OTG URB iso_frame_descs. - * @nrframes: Total length of iso_frame_desc array - * @index: Current index (FIQ-maintained) -- * -+ * @stride: Interval in uframes between HS isoc transactions - */ - struct fiq_hs_isoc_info { - struct dwc_otg_hcd_iso_packet_desc *iso_desc; - unsigned int nrframes; - unsigned int index; -+ unsigned int stride; - }; - - /** -@@ -296,6 +297,8 @@ struct fiq_channel_state { - /* Hardware bug workaround: sometimes channel halt interrupts are - * delayed until the next SOF. Keep track of when we expected to get interrupted. */ - unsigned int expected_uframe; -+ /* number of uframes remaining (for interval > 1 HS isoc transfers) before next transfer */ -+ unsigned int uframe_sleeps; - /* in/out for communicating number of dma buffers used, or number of ISOC to do */ - unsigned int nrpackets; - struct fiq_dma_info dma_info; -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -index 4d7c7bb..135b611 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -1678,6 +1678,9 @@ int fiq_fsm_queue_isoc_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) - } - } - -+ st->hs_isoc_info.stride = qh->interval; -+ st->uframe_sleeps = 0; -+ - fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d ", hc->hc_num); - fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hcchar_copy.d32); - fiq_print(FIQDBG_INT, hcd->fiq_state, "%08x", st->hctsiz_copy.d32); -@@ -1692,9 +1695,11 @@ int fiq_fsm_queue_isoc_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) - DWC_WRITE_REG32(&hc_regs->hcintmsk, st->hcintmsk_copy.d32); - if (hfnum.b.frrem < PERIODIC_FRREM_BACKOFF) { - /* Prevent queueing near EOF1. Bad things happen if a periodic -- * split transaction is queued very close to EOF. -+ * split transaction is queued very close to EOF. SOF interrupt handler -+ * will wake this channel at the next interrupt. - */ - st->fsm = FIQ_HS_ISOC_SLEEPING; -+ st->uframe_sleeps = 1; - } else { - st->fsm = FIQ_HS_ISOC_TURBO; - st->hcchar_copy.b.chen = 1; -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index 3f71f29..8db3dfc 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -2297,10 +2297,10 @@ void dwc_otg_fiq_unmangle_isoc(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, dwc_otg_qtd - dwc_urb->error_count++; - } - } -+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval * (nr_frames - 1)); -+ - //printk_ratelimited(KERN_INFO "%s: HS isochronous of %d/%d frames with %d errors complete\n", - // __FUNCTION__, i, dwc_urb->packet_count, dwc_urb->error_count); -- hcd->fops->complete(hcd, dwc_urb->priv, dwc_urb, 0); -- release_channel(hcd, qh->channel, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); - } - - /** -@@ -2543,6 +2543,8 @@ void dwc_otg_hcd_handle_hc_fsm(dwc_otg_hcd_t *hcd, uint32_t num) - * fail. - */ - dwc_otg_fiq_unmangle_isoc(hcd, qh, qtd, num); -+ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); -+ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); - break; - - case FIQ_PER_SPLIT_LS_ABORTED: - -From 671205b0f0ec871b8fcabbab6d9a2ffb3444378c Mon Sep 17 00:00:00 2001 -From: Uli Middelberg -Date: Wed, 17 Jun 2015 10:36:56 +0200 -Subject: [PATCH 150/204] added basic docker support - ---- - arch/arm/configs/bcm2709_defconfig | 3 +++ - arch/arm/configs/bcmrpi_defconfig | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index e3155da..661f09a 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -17,6 +17,7 @@ CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y - CONFIG_MEMCG=y - CONFIG_BLK_CGROUP=y -@@ -418,6 +419,7 @@ CONFIG_MD_RAID0=m - CONFIG_BLK_DEV_DM=m - CONFIG_DM_CRYPT=m - CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m - CONFIG_DM_MIRROR=m - CONFIG_DM_LOG_USERSPACE=m - CONFIG_DM_RAID=m -@@ -1115,6 +1117,7 @@ CONFIG_QFMT_V2=m - CONFIG_AUTOFS4_FS=y - CONFIG_FUSE_FS=m - CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m - CONFIG_FSCACHE=y - CONFIG_FSCACHE_STATS=y - CONFIG_FSCACHE_HISTOGRAM=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0859113..06e7529 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -16,6 +16,7 @@ CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y - CONFIG_MEMCG=y - CONFIG_BLK_CGROUP=y -@@ -411,6 +412,7 @@ CONFIG_MD_RAID0=m - CONFIG_BLK_DEV_DM=m - CONFIG_DM_CRYPT=m - CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m - CONFIG_DM_MIRROR=m - CONFIG_DM_LOG_USERSPACE=m - CONFIG_DM_RAID=m -@@ -1108,6 +1110,7 @@ CONFIG_QFMT_V2=m - CONFIG_AUTOFS4_FS=y - CONFIG_FUSE_FS=m - CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m - CONFIG_FSCACHE=y - CONFIG_FSCACHE_STATS=y - CONFIG_FSCACHE_HISTOGRAM=y - -From 1621191b72eef418410908e1b789381f2956275e Mon Sep 17 00:00:00 2001 -From: Garrett -Date: Thu, 2 Jul 2015 19:32:04 -0500 -Subject: [PATCH 151/204] bcm2835 camera planar/packed stride length - -Added a field to the mmal_fmt struct used to compute the bytes per line -when using a particular format. This results in the correct stride being -calculated even when the format is planar. - -Signed-off-by: Garrett Wilson ---- - drivers/media/platform/bcm2835/bcm2835-camera.c | 26 +++++++++++++++++++------ - drivers/media/platform/bcm2835/mmal-common.h | 1 + - 2 files changed, 21 insertions(+), 6 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c -index eb4d831..04a1711 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.c -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -88,12 +88,13 @@ static const struct v4l2_fract - /* video formats */ - static struct mmal_fmt formats[] = { - { -- .name = "4:2:0, packed YUV", -+ .name = "4:2:0, planar, YUV", - .fourcc = V4L2_PIX_FMT_YUV420, - .flags = 0, - .mmal = MMAL_ENCODING_I420, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { - .name = "4:2:2, packed, YUYV", -@@ -102,6 +103,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_YUYV, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { - .name = "RGB24 (LE)", -@@ -110,6 +112,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_BGR24, - .depth = 24, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 3, - }, - { - .name = "JPEG", -@@ -118,6 +121,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_JPEG, - .depth = 8, - .mmal_component = MMAL_COMPONENT_IMAGE_ENCODE, -+ .ybbp = 0, - }, - { - .name = "H264", -@@ -126,6 +130,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_H264, - .depth = 8, - .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, -+ .ybbp = 0, - }, - { - .name = "MJPEG", -@@ -134,6 +139,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_MJPEG, - .depth = 8, - .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, -+ .ybbp = 0, - }, - { - .name = "4:2:2, packed, YVYU", -@@ -142,6 +148,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_YVYU, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { - .name = "4:2:2, packed, VYUY", -@@ -150,6 +157,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_VYUY, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { - .name = "4:2:2, packed, UYVY", -@@ -158,14 +166,16 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_UYVY, - .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 2, - }, - { -- .name = "4:2:0, packed, NV12", -+ .name = "4:2:0, planar, NV12", - .fourcc = V4L2_PIX_FMT_NV12, - .flags = 0, - .mmal = MMAL_ENCODING_NV12, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { - .name = "RGB24 (BE)", -@@ -174,22 +184,25 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_RGB24, - .depth = 24, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 3, - }, - { -- .name = "4:2:0, packed YVU", -+ .name = "4:2:0, planar, YVU", - .fourcc = V4L2_PIX_FMT_YVU420, - .flags = 0, - .mmal = MMAL_ENCODING_YV12, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { -- .name = "4:2:0, packed, NV21", -+ .name = "4:2:0, planar, NV21", - .fourcc = V4L2_PIX_FMT_NV21, - .flags = 0, - .mmal = MMAL_ENCODING_NV21, - .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 1, - }, - { - .name = "RGB32 (BE)", -@@ -198,6 +211,7 @@ static struct mmal_fmt formats[] = { - .mmal = MMAL_ENCODING_BGRA, - .depth = 32, - .mmal_component = MMAL_COMPONENT_CAMERA, -+ .ybbp = 4, - }, - }; - -@@ -771,7 +785,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, - a->fmt.width = preview_port->es.video.width; - a->fmt.height = preview_port->es.video.height; - a->fmt.pixelformat = V4L2_PIX_FMT_YUV420; -- a->fmt.bytesperline = (preview_port->es.video.width * 3)>>1; -+ a->fmt.bytesperline = preview_port->es.video.width; - a->fmt.sizeimage = (preview_port->es.video.width * - preview_port->es.video.height * 3)>>1; - a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; -@@ -894,7 +908,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - - v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1, - &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0); -- f->fmt.pix.bytesperline = (f->fmt.pix.width * mfmt->depth)>>3; -+ f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; - - /* Image buffer has to be padded to allow for alignment, even though - * we then remove that padding before delivering the buffer. -diff --git a/drivers/media/platform/bcm2835/mmal-common.h b/drivers/media/platform/bcm2835/mmal-common.h -index 35698c8..15788a1 100644 ---- a/drivers/media/platform/bcm2835/mmal-common.h -+++ b/drivers/media/platform/bcm2835/mmal-common.h -@@ -30,6 +30,7 @@ struct mmal_fmt { - u32 mmal; - int depth; - u32 mmal_component; /* MMAL component index to be used to encode */ -+ u32 ybbp; /* depth of first Y plane for planar formats */ - }; - - /* buffer for one video frame */ - -From 86b0488fa249c00bd7c381fe637026a7f33a6ffa Mon Sep 17 00:00:00 2001 +From 1b74d2a8ea6ab1741caa2e2a0d0f477366f640d6 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 17 Aug 2015 10:49:44 +0100 -Subject: [PATCH 154/204] BCM270X_DT: Add pwm and pwm-2chan overlays +Subject: [PATCH 090/113] BCM270X_DT: Add pwm and pwm-2chan overlays From the README entries: Legal pin,function combinations for each channel: @@ -144046,243 +139781,11 @@ From the README entries: See: https://github.com/raspberrypi/linux/issues/756 --- - arch/arm/boot/dts/bcm2708_common.dtsi | 16 +++++++++ - arch/arm/boot/dts/overlays/Makefile | 2 ++ - arch/arm/boot/dts/overlays/README | 41 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 46 ++++++++++++++++++++++++ - arch/arm/boot/dts/overlays/pwm-overlay.dts | 42 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/pwm/Kconfig | 2 +- - 8 files changed, 150 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts + drivers/pwm/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index d1c3bdf..ea3bd9ca 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -154,6 +154,14 @@ - status = "disabled"; - }; - -+ pwm: pwm@7e20c000 { -+ compatible = "brcm,bcm2835-pwm"; -+ reg = <0x7e20c000 0x28>; -+ clocks = <&clk_pwm>; -+ #pwm-cells = <2>; -+ status = "disabled"; -+ }; -+ - uart1: uart@7e215040 { - compatible = "brcm,bcm2835-aux-uart", "ns16550"; - reg = <0x7e215040 0x40>; -@@ -279,6 +287,14 @@ - clock-output-names = "apb_pclk"; - clock-frequency = <126000000>; - }; -+ -+ clk_pwm: clock@5 { -+ compatible = "fixed-clock"; -+ reg = <3>; -+ #clock-cells = <0>; -+ clock-output-names = "pwm"; -+ clock-frequency = <100000000>; -+ }; - }; - - __overrides__ { -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 5f6082f..753554b 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -35,6 +35,8 @@ dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index ed484ae..1cd2140 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -410,6 +410,47 @@ Load: dtoverlay=pps-gpio,= - Params: gpiopin Input GPIO (default "18") - - -+Name: pwm -+Info: Configures a single PWM channel -+ Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+ 4) Currently the clock must have been enabled and configured -+ by other means. -+Load: dtoverlay=pwm-2chan,= -+Load: dtoverlay=pwm,= -+Params: pin Output pin (default 18) - see table -+ func Pin function (default 2 = Alt5) - see above -+ clock PWM clock frequency (informational) -+ -+ -+Name: pwm-2chan -+Info: Configures both PWM channels -+ Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+ 4) Currently the clock must have been enabled and configured -+ by other means. -+Load: dtoverlay=pwm-2chan,= -+Params: pin Output pin (default 18) - see table -+ pin2 Output pin for other channel (default 19) -+ func Pin function (default 2 = Alt5) - see above -+ func2 Function for pin2 (default 2 = Alt5) -+ clock PWM clock frequency (informational) -+ -+ - Name: rpi-dac - Info: Configures the RPi DAC audio card - Load: dtoverlay=rpi-dac -diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -new file mode 100644 -index 0000000..957e1a4 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -@@ -0,0 +1,46 @@ -+/dts-v1/; -+/plugin/; -+ -+/* -+This is the 2-channel overlay - only use it if you need both channels. -+ -+Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ -+N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+*/ -+ -+/ { -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <18 19>; -+ brcm,function = <2 2>; /* Alt5 */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pwm>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ pin = <&pwm_pins>,"brcm,pins:0"; -+ pin2 = <&pwm_pins>,"brcm,pins:4"; -+ func = <&pwm_pins>,"brcm,function:0"; -+ func2 = <&pwm_pins>,"brcm,function:4"; -+ clock = <&clk_pwm>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts -new file mode 100644 -index 0000000..ddd67ff ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts -@@ -0,0 +1,42 @@ -+/dts-v1/; -+/plugin/; -+ -+/* -+Legal pin,function combinations for each channel: -+ PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) -+ PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) -+ -+N.B.: -+ 1) Pin 18 is the only one available on all platforms, and -+ it is the one used by the I2S audio interface. -+ Pins 12 and 13 might be better choices on an A+, B+ or Pi2. -+ 2) The onboard analogue audio output uses both PWM channels. -+ 3) So be careful mixing audio and PWM. -+*/ -+ -+/ { -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <18>; -+ brcm,function = <2>; /* Alt5 */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pwm>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ pin = <&pwm_pins>,"brcm,pins:0"; -+ func = <&pwm_pins>,"brcm,function:0"; -+ clock = <&clk_pwm>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index e5af037..d7457fc 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1091,6 +1091,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index a377222..59b2fdd 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1084,6 +1084,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=y - CONFIG_IIO_KFIFO_BUF=m - CONFIG_DHT11=m -+CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig -index b1541f4..90591a9 100644 +index 062630a..30b0186 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -85,7 +85,7 @@ config PWM_BCM_KONA @@ -144295,1217 +139798,243 @@ index b1541f4..90591a9 100644 PWM framework driver for BCM2835 controller (Raspberry Pi) -From 0d1f86de027a4406151de275663b2cb68d3b39f5 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 22 Apr 2015 07:33:03 +0000 -Subject: [PATCH 155/204] spi: bcm2835: fallback to interrupt for polling - timeouts exceeding 2 jiffies - -The polling mode of the driver is designed for transfers that run -less than 30us - it will only execute under those circumstances. -So it should run comfortably without getting interrupted by the -scheduler. - -But there are situations where the raspberry pi is so overloaded -that it can take up to 80 jiffies until the polling thread gets -rescheduled - this has been observed especially under heavy -IO situations. - -In such a situation we now fall back to the interrupt handler and -log the situation at debug level. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit a750b124cfd27bae1a12df22318db5a2083dfb12) ---- - drivers/spi/spi-bcm2835.c | 87 +++++++++++++++++++++++++++-------------------- - 1 file changed, 50 insertions(+), 37 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index cf3190f..505a993 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -69,7 +69,7 @@ - #define BCM2835_SPI_CS_CS_01 0x00000001 - - #define BCM2835_SPI_POLLING_LIMIT_US 30 --#define BCM2835_SPI_TIMEOUT_MS 30000 -+#define BCM2835_SPI_POLLING_JIFFIES 2 - #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_NO_CS | SPI_3WIRE) - -@@ -157,42 +157,6 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - return IRQ_HANDLED; - } - --static int bcm2835_spi_transfer_one_poll(struct spi_master *master, -- struct spi_device *spi, -- struct spi_transfer *tfr, -- u32 cs, -- unsigned long xfer_time_us) --{ -- struct bcm2835_spi *bs = spi_master_get_devdata(master); -- /* set timeout to 1 second of maximum polling */ -- unsigned long timeout = jiffies + HZ; -- -- /* enable HW block without interrupts */ -- bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); -- -- /* loop until finished the transfer */ -- while (bs->rx_len) { -- /* read from fifo as much as possible */ -- bcm2835_rd_fifo(bs); -- /* fill in tx fifo as much as possible */ -- bcm2835_wr_fifo(bs); -- /* if we still expect some data after the read, -- * check for a possible timeout -- */ -- if (bs->rx_len && time_after(jiffies, timeout)) { -- /* Transfer complete - reset SPI HW */ -- bcm2835_spi_reset_hw(master); -- /* and return timeout */ -- return -ETIMEDOUT; -- } -- } -- -- /* Transfer complete - reset SPI HW */ -- bcm2835_spi_reset_hw(master); -- /* and return without waiting for completion */ -- return 0; --} -- - static int bcm2835_spi_transfer_one_irq(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr, -@@ -229,6 +193,55 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master, - return 1; - } - -+static int bcm2835_spi_transfer_one_poll(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs, -+ unsigned long xfer_time_us) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ unsigned long timeout; -+ -+ /* enable HW block without interrupts */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); -+ -+ /* fill in the fifo before timeout calculations -+ * if we are interrupted here, then the data is -+ * getting transferred by the HW while we are interrupted -+ */ -+ bcm2835_wr_fifo(bs); -+ -+ /* set the timeout */ -+ timeout = jiffies + BCM2835_SPI_POLLING_JIFFIES; -+ -+ /* loop until finished the transfer */ -+ while (bs->rx_len) { -+ /* fill in tx fifo with remaining data */ -+ bcm2835_wr_fifo(bs); -+ -+ /* read from fifo as much as possible */ -+ bcm2835_rd_fifo(bs); -+ -+ /* if there is still data pending to read -+ * then check the timeout -+ */ -+ if (bs->rx_len && time_after(jiffies, timeout)) { -+ dev_dbg_ratelimited(&spi->dev, -+ "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n", -+ jiffies - timeout, -+ bs->tx_len, bs->rx_len); -+ /* fall back to interrupt mode */ -+ return bcm2835_spi_transfer_one_irq(master, spi, -+ tfr, cs); -+ } -+ } -+ -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* and return without waiting for completion */ -+ return 0; -+} -+ - static int bcm2835_spi_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr) - -From 9a96e7390f5bb3db6138d07ffe6145c17e53246d Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 10 May 2015 20:47:28 +0000 -Subject: [PATCH 156/204] spi: bcm2835: enable dma modes for transfers meeting - certain conditions +From 8b83f4fc351924e62e52b4cdc5e9f8711ccb4274 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:44:02 +0200 +Subject: [PATCH 091/113] lirc-rpi: Make buildable on bcm2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Conditions per spi_transfer are: -* transfer.len >= 96 bytes (to avoid mapping overhead costs) -* transfer.len < 65536 bytes (limitaion by spi-hw block - could get extended) -* an individual scatter/gather transfer length must be a multiple of 4 - for anything but the last transfer - spi-hw block limit. - (some shortcut has been taken in can_dma to avoid unnecessary mapping of - pages which, for which there is a chance that there is a split with a - transfer length not a multiple of 4) - -If it becomes a necessity these restrictions can get removed by additional -code. - -Note that this patch requires a patch to dma-bcm2835.c by Noralf to -enable scatter-gather mode inside the dmaengine, which has not been -merged yet. - -That is why no patch to arch/arm/boot/dts/bcm2835.dtsi is included - the -code works as before without dma when tx/rx are not set, but it writes -a message warning about dma not used: -spi-bcm2835 20204000.spi: no tx-dma configuration found - not using dma mode - -To enable dma-mode add the following lines to the device-tree: - dmas = <&dma 6>, <&dma 7>; - dma-names = "tx", "rx"; - -Tested-by: Noralf Trønnes (private communication) -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit 3ecd37edaa2a6ba3246e2c35714be9316b1087fe) +Signed-off-by: Noralf Trønnes --- - drivers/spi/spi-bcm2835.c | 303 +++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 301 insertions(+), 2 deletions(-) + drivers/staging/media/lirc/lirc_rpi.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 505a993..27fb5b0 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -23,15 +23,18 @@ - #include - #include +diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c +index 24563ec..e1c3cb6 100644 +--- a/drivers/staging/media/lirc/lirc_rpi.c ++++ b/drivers/staging/media/lirc/lirc_rpi.c +@@ -39,11 +39,12 @@ + #include + #include + #include +-#include + #include + #include +- + #include ++#ifndef CONFIG_ARCH_BCM2835 ++#include ++#endif + + #define LIRC_DRIVER_NAME "lirc_rpi" + #define RBUF_LEN 256 +@@ -388,6 +389,10 @@ static int init_port(void) + } + else + { ++#ifdef CONFIG_ARCH_BCM2835 ++ ret = -EINVAL; ++ goto exit_init_port; ++#else + if (gpio_in_pin >= BCM2708_NR_GPIOS || + gpio_out_pin >= BCM2708_NR_GPIOS) { + ret = -EINVAL; +@@ -413,6 +418,7 @@ static int init_port(void) + bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); + gpiochip->direction_input(gpiochip, gpio_in_pin); + gpiochip->direction_output(gpiochip, gpio_out_pin, 1); ++#endif + } + + gpiochip->set(gpiochip, gpio_out_pin, invert); + +From 12c4848d2b2a44c1953b7bf560f21eab68d5ede3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:44:36 +0200 +Subject: [PATCH 092/113] i2c-bcm2708: Make buildable on bcm2835 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + drivers/i2c/busses/Kconfig | 2 +- + drivers/i2c/busses/i2c-bcm2708.c | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index eb5f729..aab0b52 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -10,7 +10,7 @@ comment "PC SMBus host controller drivers" + + config I2C_BCM2708 + tristate "BCM2708 BSC" +- depends on MACH_BCM2708 || MACH_BCM2709 ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 + help + Enabling this option will add BSC (Broadcom Serial Controller) + support for the BCM2708. BSC is a Broadcom proprietary bus compatible +diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c +index 8b8762d..5b4fd7b 100644 +--- a/drivers/i2c/busses/i2c-bcm2708.c ++++ b/drivers/i2c/busses/i2c-bcm2708.c +@@ -96,6 +96,9 @@ struct bcm2708_i2c { + bool error; + }; + ++#ifdef CONFIG_ARCH_BCM2835 ++static void bcm2708_i2c_init_pinmode(int id) { } ++#else + /* + * This function sets the ALT mode on the I2C pins so that we can use them with + * the BSC hardware. +@@ -123,6 +126,7 @@ static void bcm2708_i2c_init_pinmode(int id) + #undef INP_GPIO + #undef SET_GPIO_ALT + } ++#endif + + static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) + { + +From 13a84b674bb9f073f129d948dab08852ac2124f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:45:08 +0200 +Subject: [PATCH 093/113] bcm2708-i2s: Make buildable on bcm2835 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Noralf Trønnes +--- + sound/soc/bcm/Kconfig | 2 +- + sound/soc/bcm/bcm2708-i2s.c | 6 ++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index fc151ea..257faa78 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -10,7 +10,7 @@ config SND_BCM2835_SOC_I2S + + config SND_BCM2708_SOC_I2S + tristate "SoC Audio support for the Broadcom BCM2708 I2S module" +- depends on MACH_BCM2708 || MACH_BCM2709 ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 + select REGMAP_MMIO + select SND_SOC_DMAENGINE_PCM + select SND_SOC_GENERIC_DMAENGINE_PCM +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +index 5e93cd6..ad9ca2c 100644 +--- a/sound/soc/bcm/bcm2708-i2s.c ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -40,7 +40,9 @@ #include -+#include -+#include - #include - #include #include - #include - #include - #include --#include --#include -+#include - #include -+#include -+#include - #include - - /* SPI register offsets */ -@@ -70,6 +73,7 @@ - - #define BCM2835_SPI_POLLING_LIMIT_US 30 - #define BCM2835_SPI_POLLING_JIFFIES 2 -+#define BCM2835_SPI_DMA_MIN_LENGTH 96 - #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_NO_CS | SPI_3WIRE) - -@@ -83,6 +87,7 @@ struct bcm2835_spi { - u8 *rx_buf; - int tx_len; - int rx_len; -+ bool dma_pending; - }; - - static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg) -@@ -128,12 +133,15 @@ static void bcm2835_spi_reset_hw(struct spi_master *master) - /* Disable SPI interrupts and transfer */ - cs &= ~(BCM2835_SPI_CS_INTR | - BCM2835_SPI_CS_INTD | -+ BCM2835_SPI_CS_DMAEN | - BCM2835_SPI_CS_TA); - /* and reset RX/TX FIFOS */ - cs |= BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX; - - /* and reset the SPI_HW */ - bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+ /* as well as DLEN */ -+ bcm2835_wr(bs, BCM2835_SPI_DLEN, 0); - } - - static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) -@@ -193,6 +201,279 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master, - return 1; - } - -+/* -+ * DMA support -+ * -+ * this implementation has currently a few issues in so far as it does -+ * not work arrount limitations of the HW. -+ * -+ * the main one being that DMA transfers are limited to 16 bit -+ * (so 0 to 65535 bytes) by the SPI HW due to BCM2835_SPI_DLEN -+ * -+ * also we currently assume that the scatter-gather fragments are -+ * all multiple of 4 (except the last) - otherwise we would need -+ * to reset the FIFO before subsequent transfers... -+ * this also means that tx/rx transfers sg's need to be of equal size! -+ * -+ * there may be a few more border-cases we may need to address as well -+ * but unfortunately this would mean splitting up the scatter-gather -+ * list making it slightly unpractical... -+ */ -+static void bcm2835_spi_dma_done(void *data) -+{ -+ struct spi_master *master = data; -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ -+ /* reset fifo and HW */ -+ bcm2835_spi_reset_hw(master); -+ -+ /* and terminate tx-dma as we do not have an irq for it -+ * because when the rx dma will terminate and this callback -+ * is called the tx-dma must have finished - can't get to this -+ * situation otherwise... -+ */ -+ dmaengine_terminate_all(master->dma_tx); -+ -+ /* mark as no longer pending */ -+ bs->dma_pending = 0; -+ -+ /* and mark as completed */; -+ complete(&master->xfer_completion); -+} -+ -+static int bcm2835_spi_prepare_sg(struct spi_master *master, -+ struct spi_transfer *tfr, -+ bool is_tx) -+{ -+ struct dma_chan *chan; -+ struct scatterlist *sgl; -+ unsigned int nents; -+ enum dma_transfer_direction dir; -+ unsigned long flags; -+ -+ struct dma_async_tx_descriptor *desc; -+ dma_cookie_t cookie; -+ -+ if (is_tx) { -+ dir = DMA_MEM_TO_DEV; -+ chan = master->dma_tx; -+ nents = tfr->tx_sg.nents; -+ sgl = tfr->tx_sg.sgl; -+ flags = 0 /* no tx interrupt */; -+ -+ } else { -+ dir = DMA_DEV_TO_MEM; -+ chan = master->dma_rx; -+ nents = tfr->rx_sg.nents; -+ sgl = tfr->rx_sg.sgl; -+ flags = DMA_PREP_INTERRUPT; -+ } -+ /* prepare the channel */ -+ desc = dmaengine_prep_slave_sg(chan, sgl, nents, dir, flags); -+ if (!desc) -+ return -EINVAL; -+ -+ /* set callback for rx */ -+ if (!is_tx) { -+ desc->callback = bcm2835_spi_dma_done; -+ desc->callback_param = master; -+ } -+ -+ /* submit it to DMA-engine */ -+ cookie = dmaengine_submit(desc); -+ -+ return dma_submit_error(cookie); -+} -+ -+static inline int bcm2835_check_sg_length(struct sg_table *sgt) -+{ -+ int i; -+ struct scatterlist *sgl; -+ -+ /* check that the sg entries are word-sized (except for last) */ -+ for_each_sg(sgt->sgl, sgl, (int)sgt->nents - 1, i) { -+ if (sg_dma_len(sgl) % 4) -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_spi_transfer_one_dma(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ int ret; -+ -+ /* check that the scatter gather segments are all a multiple of 4 */ -+ if (bcm2835_check_sg_length(&tfr->tx_sg) || -+ bcm2835_check_sg_length(&tfr->rx_sg)) { -+ dev_warn_once(&spi->dev, -+ "scatter gather segment length is not a multiple of 4 - falling back to interrupt mode\n"); -+ return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); -+ } -+ -+ /* setup tx-DMA */ -+ ret = bcm2835_spi_prepare_sg(master, tfr, true); -+ if (ret) -+ return ret; -+ -+ /* start TX early */ -+ dma_async_issue_pending(master->dma_tx); -+ -+ /* mark as dma pending */ -+ bs->dma_pending = 1; -+ -+ /* set the DMA length */ -+ bcm2835_wr(bs, BCM2835_SPI_DLEN, tfr->len); -+ -+ /* start the HW */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, -+ cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN); -+ -+ /* setup rx-DMA late - to run transfers while -+ * mapping of the rx buffers still takes place -+ * this saves 10us or more. -+ */ -+ ret = bcm2835_spi_prepare_sg(master, tfr, false); -+ if (ret) { -+ /* need to reset on errors */ -+ dmaengine_terminate_all(master->dma_tx); -+ bcm2835_spi_reset_hw(master); -+ return ret; -+ } -+ -+ /* start rx dma late */ -+ dma_async_issue_pending(master->dma_rx); -+ -+ /* wait for wakeup in framework */ -+ return 1; -+} -+ -+static bool bcm2835_spi_can_dma(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr) -+{ -+ /* only run for gpio_cs */ -+ if (!gpio_is_valid(spi->cs_gpio)) -+ return false; -+ -+ /* we start DMA efforts only on bigger transfers */ -+ if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH) -+ return false; -+ -+ /* BCM2835_SPI_DLEN has defined a max transfer size as -+ * 16 bit, so max is 65535 -+ * we can revisit this by using an alternative transfer -+ * method - ideally this would get done without any more -+ * interaction... -+ */ -+ if (tfr->len > 65535) { -+ dev_warn_once(&spi->dev, -+ "transfer size of %d too big for dma-transfer\n", -+ tfr->len); -+ return false; -+ } -+ -+ /* if we run rx/tx_buf with word aligned addresses then we are OK */ -+ if (((u32)tfr->tx_buf % 4 == 0) && ((u32)tfr->tx_buf % 4 == 0)) -+ return true; -+ -+ /* otherwise we only allow transfers within the same page -+ * to avoid wasting time on dma_mapping when it is not practical -+ */ -+ if (((u32)tfr->tx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ dev_warn_once(&spi->dev, -+ "Unaligned spi tx-transfer bridging page\n"); -+ return false; -+ } -+ if (((u32)tfr->rx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ dev_warn_once(&spi->dev, -+ "Unaligned spi tx-transfer bridging page\n"); -+ return false; -+ } -+ -+ /* return OK */ -+ return true; -+} -+ -+void bcm2835_dma_release(struct spi_master *master) -+{ -+ if (master->dma_tx) { -+ dmaengine_terminate_all(master->dma_tx); -+ dma_release_channel(master->dma_tx); -+ master->dma_tx = NULL; -+ } -+ if (master->dma_rx) { -+ dmaengine_terminate_all(master->dma_rx); -+ dma_release_channel(master->dma_rx); -+ master->dma_rx = NULL; -+ } -+} -+ -+void bcm2835_dma_init(struct spi_master *master, struct device *dev) -+{ -+ struct dma_slave_config slave_config; -+ const __be32 *addr; -+ dma_addr_t dma_reg_base; -+ int ret; -+ -+ /* base address in dma-space */ -+ addr = of_get_address(master->dev.of_node, 0, NULL, NULL); -+ if (!addr) { -+ dev_err(dev, "could not get DMA-register address - not using dma mode\n"); -+ goto err; -+ } -+ dma_reg_base = be32_to_cpup(addr); -+ -+ /* get tx/rx dma */ -+ master->dma_tx = dma_request_slave_channel(dev, "tx"); -+ if (!master->dma_tx) { -+ dev_err(dev, "no tx-dma configuration found - not using dma mode\n"); -+ goto err; -+ } -+ master->dma_rx = dma_request_slave_channel(dev, "rx"); -+ if (!master->dma_rx) { -+ dev_err(dev, "no rx-dma configuration found - not using dma mode\n"); -+ goto err_release; -+ } -+ -+ /* configure DMAs */ -+ slave_config.direction = DMA_MEM_TO_DEV; -+ slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO); -+ slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ -+ ret = dmaengine_slave_config(master->dma_tx, &slave_config); -+ if (ret) -+ goto err_config; -+ -+ slave_config.direction = DMA_DEV_TO_MEM; -+ slave_config.src_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO); -+ slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ -+ ret = dmaengine_slave_config(master->dma_rx, &slave_config); -+ if (ret) -+ goto err_config; -+ -+ /* all went well, so set can_dma */ -+ master->can_dma = bcm2835_spi_can_dma; -+ master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */ -+ /* need to do TX AND RX DMA, so we need dummy buffers */ -+ master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; -+ -+ return; -+ -+err_config: -+ dev_err(dev, "issue configuring dma: %d - not using DMA mode\n", -+ ret); -+err_release: -+ bcm2835_dma_release(master); -+err: -+ return; -+} -+ - static int bcm2835_spi_transfer_one_poll(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr, -@@ -299,6 +580,11 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - return bcm2835_spi_transfer_one_poll(master, spi, tfr, - cs, xfer_time_us); - -+ /* run in dma mode if conditions are right */ -+ if (master->can_dma && bcm2835_spi_can_dma(master, spi, tfr)) -+ return bcm2835_spi_transfer_one_dma(master, spi, tfr, cs); -+ -+ /* run in interrupt-mode */ - return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); - } - -@@ -324,6 +610,15 @@ static int bcm2835_spi_prepare_message(struct spi_master *master, - static void bcm2835_spi_handle_err(struct spi_master *master, - struct spi_message *msg) - { -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ -+ /* if an error occurred and we have an active dma, then terminate */ -+ if (bs->dma_pending) { -+ dmaengine_terminate_all(master->dma_tx); -+ dmaengine_terminate_all(master->dma_rx); -+ bs->dma_pending = 0; -+ } -+ /* and reset */ - bcm2835_spi_reset_hw(master); - } - -@@ -523,6 +818,8 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - goto out_clk_disable; - } - -+ bcm2835_dma_init(master, &pdev->dev); -+ - /* initialise the hardware with the default polarities */ - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); -@@ -553,6 +850,8 @@ static int bcm2835_spi_remove(struct platform_device *pdev) - - clk_disable_unprepare(bs->clk); - -+ bcm2835_dma_release(master); -+ - return 0; - } - - -From 6e92fd1644001ba7827e2706c0ed4fd4c2d85bc1 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Tue, 12 May 2015 10:32:08 +0000 -Subject: [PATCH 157/204] spi: bcm2835: fix kbuild compile warnings/errors and - a typo - -fixes several warnings/error emmitted by the kbuild system: -* warn: cast from pointer to integer of different size - using size_t instead of u32 -* error: 'SZ_4K' undeclared - moved to PAGE_SIZE and PAGE_MASK instead - -Review showed also a typo in the same code where tx_buff -was checked twice instead of checking both rx and tx_buff. - -Reported by: Stephen Rothwell -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit 7e52be0d576e8f7bc99a606f07b9d000c4340f04) ---- - drivers/spi/spi-bcm2835.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 27fb5b0..52aaf2d 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -20,6 +20,7 @@ - * GNU General Public License for more details. - */ - -+#include #include - #include - #include -@@ -378,18 +379,19 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, - } ++#ifndef CONFIG_ARCH_BCM2835 + #include ++#endif - /* if we run rx/tx_buf with word aligned addresses then we are OK */ -- if (((u32)tfr->tx_buf % 4 == 0) && ((u32)tfr->tx_buf % 4 == 0)) -+ if ((((size_t)tfr->rx_buf & 3) == 0) && -+ (((size_t)tfr->tx_buf & 3) == 0)) - return true; - - /* otherwise we only allow transfers within the same page - * to avoid wasting time on dma_mapping when it is not practical - */ -- if (((u32)tfr->tx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); - return false; - } -- if (((u32)tfr->rx_buf % SZ_4K) + tfr->len > SZ_4K) { -+ if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); - return false; - -From 63ad0b9f2b638c3968473d46f732de9f28ad184b Mon Sep 17 00:00:00 2001 -From: kbuild test robot -Date: Tue, 12 May 2015 19:43:59 +0800 -Subject: [PATCH 158/204] spi: bcm2835: bcm2835_dma_release() can be static - -Signed-off-by: Fengguang Wu -Signed-off-by: Mark Brown -(cherry picked from commit 29ad1a7a9e08f1d2b6795c5278a0c0fd23679ded) ---- - drivers/spi/spi-bcm2835.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 52aaf2d..bad36c5 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -401,7 +401,7 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, - return true; + #include + #include +@@ -320,6 +322,9 @@ static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, } --void bcm2835_dma_release(struct spi_master *master) -+static void bcm2835_dma_release(struct spi_master *master) + ++#ifdef CONFIG_ARCH_BCM2835 ++static void bcm2708_i2s_setup_gpio(void) { } ++#else + static int bcm2708_i2s_set_function(unsigned offset, int function) { - if (master->dma_tx) { - dmaengine_terminate_all(master->dma_tx); -@@ -415,7 +415,7 @@ void bcm2835_dma_release(struct spi_master *master) + #define GPIOFSEL(x) (0x00+(x)*4) +@@ -379,6 +384,7 @@ static void bcm2708_i2s_setup_gpio(void) + bcm2708_i2s_set_function(pin, alt); } } ++#endif --void bcm2835_dma_init(struct spi_master *master, struct device *dev) -+static void bcm2835_dma_init(struct spi_master *master, struct device *dev) - { - struct dma_slave_config slave_config; - const __be32 *addr; + static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, -From f3260b7d15164b1ddd0f080592defb79949db0aa Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 22 Jul 2015 08:34:41 +0000 -Subject: [PATCH 159/204] dt-overlay to enable dma for spi driver +From f876ec23ff9316417ab43b252c989992984922f4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Sat, 15 Aug 2015 20:50:02 +0200 +Subject: [PATCH 094/113] bcm2835: Add support for uart1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit -Signed-off-by: Martin Sperl +This is a hack until a proper solution is agreed upon. +Martin Sperl is doing some work in this area. + +Signed-off-by: Noralf Trønnes --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/spi-dma-overlay.dts | 20 ++++++++++++++++++++ - 2 files changed, 21 insertions(+) - create mode 100755 arch/arm/boot/dts/overlays/spi-dma-overlay.dts + arch/arm/mach-bcm/board_bcm2835.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 753554b..956e395 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -45,6 +45,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/spi-dma-overlay.dts b/arch/arm/boot/dts/overlays/spi-dma-overlay.dts -new file mode 100755 -index 0000000..266cf9d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-dma-overlay.dts -@@ -0,0 +1,20 @@ -+/* -+ * Device tree overlay for spi-bcm2835 to allow dma -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ dmas = <&dma 6>, <&dma 7>; -+ dma-names = "tx", "rx"; -+ }; -+ }; -+ }; - -From 67c4106248a6d4eaee1de239e8f18da5e08ed8fd Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 22 Jul 2015 12:41:54 +0000 -Subject: [PATCH 160/204] dt: overlay: added documentation of spi-dma overlay - -Signed-off-by: Martin Sperl ---- - arch/arm/boot/dts/overlays/README | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1cd2140..bda8c14 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -515,6 +515,12 @@ Load: dtoverlay=spi-bcm2835 - Params: +diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c +index 1e6f1cf9..ea36eec 100644 +--- a/arch/arm/mach-bcm/board_bcm2835.c ++++ b/arch/arm/mach-bcm/board_bcm2835.c +@@ -22,6 +22,29 @@ + #include + #include - -+Name: spi-dma -+Info: enables dma modes for spi-bcm2835 -+Load: dtoverlay=spi-dma -+Params: -+ -+ - Name: tinylcd35 - Info: 3.5" Color TFT Display by www.tinylcd.com - Options: Touch, RTC, keypad - -From 1981274d8b58c613e5f3f0f40068f25ffcdbe481 Mon Sep 17 00:00:00 2001 -From: Serge Schneider -Date: Mon, 17 Aug 2015 18:06:16 +0100 -Subject: [PATCH 161/204] rpisense-fb: add low-light mode and gamma control - ---- - drivers/video/fbdev/rpisense-fb.c | 68 +++++++++++++++++++++++++++++--- - include/linux/mfd/rpisense/framebuffer.h | 6 ++- - 2 files changed, 68 insertions(+), 6 deletions(-) - -diff --git a/drivers/video/fbdev/rpisense-fb.c b/drivers/video/fbdev/rpisense-fb.c -index 99bb8ea..90553fa 100644 ---- a/drivers/video/fbdev/rpisense-fb.c -+++ b/drivers/video/fbdev/rpisense-fb.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -26,22 +27,35 @@ - #include - #include - -+static bool lowlight; -+module_param(lowlight, bool, 0); -+MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); -+ - struct rpisense *rpisense; - - struct rpisense_fb_param { - char __iomem *vmem; - u8 *vmem_work; - u32 vmemsize; -- u8 gamma[32]; -+ u8 *gamma; - }; - -+static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -+ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, -+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, -+ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}; -+ -+static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, -+ 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, -+ 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,}; -+ -+static u8 gamma_user[32]; -+ - static struct rpisense_fb_param rpisense_fb_param = { - .vmem = NULL, - .vmemsize = 128, -- .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -- 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, -- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, -- 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}, -+ .gamma = gamma_default, - }; - - static struct fb_deferred_io rpisense_fb_defio; -@@ -127,6 +141,46 @@ static struct fb_deferred_io rpisense_fb_defio = { - .deferred_io = rpisense_fb_deferred_io, - }; - -+static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd, -+ unsigned long arg) ++/* Use this hack until a proper solution is agreed upon */ ++static void __init bcm2835_init_uart1(void) +{ -+ switch (cmd) { -+ case SENSEFB_FBIOGET_GAMMA: -+ if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma, -+ sizeof(u8[32]))) -+ return -EFAULT; -+ return 0; -+ case SENSEFB_FBIOSET_GAMMA: -+ if (copy_from_user(gamma_user, (void __user *)arg, -+ sizeof(u8[32]))) -+ return -EFAULT; -+ rpisense_fb_param.gamma = gamma_user; -+ schedule_delayed_work(&info->deferred_work, -+ rpisense_fb_defio.delay); -+ return 0; -+ case SENSEFB_FBIORESET_GAMMA: -+ switch (arg) { -+ case 0: -+ rpisense_fb_param.gamma = gamma_default; -+ break; -+ case 1: -+ rpisense_fb_param.gamma = gamma_low; -+ break; -+ case 2: -+ rpisense_fb_param.gamma = gamma_user; -+ break; -+ default: -+ return -EINVAL; ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); ++ if (of_device_is_available(np)) { ++ np = of_find_compatible_node(NULL, NULL, ++ "bcrm,bcm2835-aux-enable"); ++ if (np) { ++ void __iomem *base = of_iomap(np, 0); ++ ++ if (!base) { ++ pr_err("bcm2835: Failed enabling Mini UART\n"); ++ return; ++ } ++ ++ writel(1, base); ++ pr_info("bcm2835: Mini UART enabled\n"); + } -+ schedule_delayed_work(&info->deferred_work, -+ rpisense_fb_defio.delay); -+ break; -+ default: -+ return -EINVAL; + } -+ return 0; +} + - static struct fb_ops rpisense_fb_ops = { - .owner = THIS_MODULE, - .fb_read = fb_sys_read, -@@ -134,6 +188,7 @@ static struct fb_ops rpisense_fb_ops = { - .fb_fillrect = rpisense_fb_fillrect, - .fb_copyarea = rpisense_fb_copyarea, - .fb_imageblit = rpisense_fb_imageblit, -+ .fb_ioctl = rpisense_fb_ioctl, - }; - - static int rpisense_fb_probe(struct platform_device *pdev) -@@ -171,6 +226,9 @@ static int rpisense_fb_probe(struct platform_device *pdev) - info->screen_base = rpisense_fb_param.vmem; - info->screen_size = rpisense_fb_param.vmemsize; - -+ if (lowlight) -+ rpisense_fb_param.gamma = gamma_low; + static void __init bcm2835_init(void) + { + struct device_node *np = of_find_node_by_path("/system"); +@@ -42,6 +65,8 @@ static void __init bcm2835_init(void) + system_rev = val; + if (!of_property_read_u64(np, "linux,serial", &val64)) + system_serial_low = val64; + - fb_deferred_io_init(info); - - ret = register_framebuffer(info); -diff --git a/include/linux/mfd/rpisense/framebuffer.h b/include/linux/mfd/rpisense/framebuffer.h -index c4c1118..2ba95d7 100644 ---- a/include/linux/mfd/rpisense/framebuffer.h -+++ b/include/linux/mfd/rpisense/framebuffer.h -@@ -16,7 +16,11 @@ - #ifndef __LINUX_RPISENSE_FB_H_ - #define __LINUX_RPISENSE_FB_H_ - --#include -+#define SENSEFB_FBIO_IOC_MAGIC 0xF1 -+ -+#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0) -+#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1) -+#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2) - - struct rpisense; - - -From 82bd9aca8c50e84e17b9c62a6d5c528aa8f0e490 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 19 Aug 2015 11:38:10 +0100 -Subject: [PATCH 162/204] BCM270X_DT: README - add note on indentation - ---- - arch/arm/boot/dts/overlays/README | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index bda8c14..ac9c427 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -74,6 +74,10 @@ behaviour. See the list of overlays below for a description of the parameters an - The Overlay and Parameter Reference - =================================== - -+N.B. When editing this file, please preserve the indentation levels to make it simple to parse -+programmatically. NO HARD TABS. -+ -+ - Name: - Info: Configures the base Raspberry Pi hardware - Load: - -From b6277bf87e266469ee14448d41209f79f3caa8d1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 20 Aug 2015 13:50:18 +0100 -Subject: [PATCH 163/204] bcm2708-dmaengine: Use more DMA channels (but not 12) - -1) Only the bcm2708_fb drivers uses the legacy DMA API, and -it requires a BULK-capable channel, so all other types -(FAST, NORMAL and LITE) can be made available to the regular -DMA API. - -2) DMA channels 11-14 share an interrupt. The driver can't -handle this, so don't use channels 12-14 (12 was used, probably -because it appears to have an interrupt, but in reality that -interrupt is for activity on ANY channel). This may explain -a lockup encountered when running out of DMA channels. - -The combined effect of this patch is to leave 7 DMA channels -available + channel 0 for bcm2708_fb via the legacy API. - -See: https://github.com/raspberrypi/linux/issues/1110 - https://github.com/raspberrypi/linux/issues/1108 ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 ++-- - drivers/dma/bcm2708-dmaengine.c | 43 +++++++++++++++++++++++------------ - 2 files changed, 31 insertions(+), 17 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index ea3bd9ca..f096f45 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -59,11 +59,10 @@ - <1 24>, - <1 25>, - <1 26>, -- <1 27>, -- <1 28>; -+ <1 27>; - - #dma-cells = <1>; -- brcm,dma-channel-mask = <0x7f35>; -+ brcm,dma-channel-mask = <0x0f35>; - }; - - intc: interrupt-controller { -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 73c6c00..85ce18b 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -184,7 +184,7 @@ static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, ++ bcm2835_init_uart1(); } - static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -- unsigned preferred_feature_set) -+ unsigned required_feature_set) - { - u32 chans; - int chan = 0; -@@ -193,10 +193,8 @@ static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, - chans = dmaman->chan_available; - for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) - /* select the subset of available channels with the desired -- feature so long as some of the candidate channels have that -- feature */ -- if ((preferred_feature_set & (1 << feature)) && -- (chans & dmaman->has_feature[feature])) -+ features */ -+ if (required_feature_set & (1 << feature)) - chans &= dmaman->has_feature[feature]; - - if (!chans) -@@ -228,7 +226,7 @@ static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) - - /* DMA Manager Monitor */ - --extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+extern int bcm_dma_chan_alloc(unsigned required_feature_set, - void __iomem **out_dma_base, int *out_dma_irq) - { - struct vc_dmaman *dmaman = g_dmaman; -@@ -240,7 +238,7 @@ extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, - return -ENODEV; - - mutex_lock(&dmaman->lock); -- chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ chan = vc_dmaman_chan_alloc(dmaman, required_feature_set); - if (chan < 0) - goto out; - -@@ -442,6 +440,7 @@ static inline struct bcm2835_desc *to_bcm2835_dma_desc( - return container_of(t, struct bcm2835_desc, vd.tx); - } - -+#if 0 - static void dma_dumpregs(struct bcm2835_chan *c) - { - pr_debug("-------------DMA DUMPREGS-------------\n"); -@@ -457,6 +456,7 @@ static void dma_dumpregs(struct bcm2835_chan *c) - readl(c->chan_base + BCM2835_DMA_NEXTCB)); - pr_debug("--------------------------------------\n"); - } -+#endif - - static void bcm2835_dma_desc_free(struct virt_dma_desc *vd) - { -@@ -862,6 +862,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( - uint32_t len = sg_dma_len(sgent); - - for (j = 0; j < len; j += max_size) { -+ u32 waits; - struct bcm2835_dma_cb *control_block = - &d->control_block_base[i+splitct]; - -@@ -879,7 +880,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( - } - - /* Common part */ -- u32 waits = SDHCI_BCM_DMA_WAITS; -+ waits = SDHCI_BCM_DMA_WAITS; - if ((dma_debug >> 0) & 0x1f) - waits = (dma_debug >> 0) & 0x1f; - control_block->info |= BCM2835_DMA_WAITS(waits); -@@ -1074,6 +1075,14 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - int rc; - int i; - int irq; -+#ifdef CONFIG_DMA_BCM2708_LEGACY -+ static const u32 wanted_features[] = { -+ BCM_DMA_FEATURE_FAST, -+ BCM_DMA_FEATURE_NORMAL, -+ BCM_DMA_FEATURE_LITE -+ }; -+ int j; -+#endif - - - if (!pdev->dev.dma_mask) -@@ -1120,20 +1129,24 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, od); - -- for (i = 0; i < 5; i++) { -+ for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) { -+ - void __iomem *chan_base; - int chan_id; - -- chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE, -- &chan_base, -- &irq); -+ chan_id = bcm_dma_chan_alloc(wanted_features[j], -+ &chan_base, -+ &irq); - -- if (chan_id < 0) -- break; -+ if (chan_id < 0) { -+ j++; -+ continue; -+ } - - rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq); - if (rc) - goto err_no_dma; -+ i++; - } - - if (pdev->dev.of_node) { -@@ -1146,6 +1159,8 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - } - } - -+ dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i); -+ - #else - rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (rc) + static const char * const bcm2835_compat[] = { -From 72de9ce92b348a0f4f9230affa0e27d3f775342e Mon Sep 17 00:00:00 2001 +From 00cc274f98a714532579d62a113b3b48a6a341c1 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:03:47 +0100 -Subject: [PATCH 164/204] RaspiDAC3 support +Subject: [PATCH 095/113] RaspiDAC3 support Signed-off-by: Jan Grulich --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - sound/soc/bcm/Kconfig | 8 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/raspidac3.c | 191 +++++++++++++++++++++++ - 8 files changed, 255 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts + sound/soc/bcm/Kconfig | 8 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/raspidac3.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 201 insertions(+) create mode 100644 sound/soc/bcm/raspidac3.c -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 956e395..9b03b1f 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -37,6 +37,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index ac9c427..7e38eb3 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -455,6 +455,12 @@ Params: pin Output pin (default 18) - see table - clock PWM clock frequency (informational) - - -+Name: raspidac3 -+Info: Configures the RaspiDAV Rev.3x audio card -+Load: dtoverlay=raspidac3 -+Params: -+ -+ - Name: rpi-dac - Info: Configures the RPi DAC audio card - Load: dtoverlay=rpi-dac -diff --git a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts -new file mode 100644 -index 0000000..1bd8054 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts -@@ -0,0 +1,45 @@ -+// Definitions for RaspiDACv3 -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "jg,raspidacv3"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ -+ tpa6130a2: tpa6130a2@60 { -+ compatible = "ti,tpa6130a2"; -+ reg = <0x60>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d7457fc..0d457a3 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -832,6 +832,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 59b2fdd..8979f23 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -825,6 +825,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index fc151ea..3db2852 100644 +index 257faa78..f465dd2 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -67,3 +67,11 @@ config SND_BCM2708_SOC_IQAUDIO_DAC @@ -145735,537 +140264,10 @@ index 0000000..fddaeec +MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x"); +MODULE_LICENSE("GPL v2"); -From 5639b22eb081048b07152c5bd90d25d7768cb1cf Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 14 Jul 2015 16:55:02 +0100 -Subject: [PATCH 165/204] config: Add SND_SOC_ADAU1701 module - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 0d457a3..16a8354 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -833,6 +833,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m -+CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 8979f23..7dd4fd4 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -826,6 +826,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m -+CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - -From 6a0f88404b8cc24c073b1d157be02fbc9007788a Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 29 Jul 2015 07:34:10 +0000 -Subject: [PATCH 166/204] spi: bcm2835: fix overflow in calculation of transfer - time - -This resulted in the use of polling mode when other approaches -(dma or interrupts) would have been more appropriate. - -Happened for transfers longer than 477 bytes. - -Reported-by: Noralf Tronnes -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -(cherry picked from commit 0122a5183088e3117bb9c8fbe248914efb502f3f) ---- - drivers/spi/spi-bcm2835.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index bad36c5..b68991c 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr, - u32 cs, -- unsigned long xfer_time_us) -+ unsigned long long xfer_time_us) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long timeout; -@@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long spi_hz, clk_hz, cdiv; -- unsigned long spi_used_hz, xfer_time_us; -+ unsigned long spi_used_hz; -+ unsigned long long xfer_time_us; - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - - /* set clock */ -@@ -573,9 +574,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - bs->rx_len = tfr->len; - - /* calculate the estimated time in us the transfer runs */ -- xfer_time_us = tfr->len -+ xfer_time_us = (unsigned long long)tfr->len - * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */ -- * 1000000 / spi_used_hz; -+ * 1000000; -+ do_div(xfer_time_us, spi_used_hz); - - /* for short requests run polling*/ - if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US) - -From 74f48a53e476a7d34ab0a58c883149b19e5bbdec Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 8 Sep 2015 15:14:50 +0100 -Subject: [PATCH 167/204] BCM270X_DT: Add SDIO overlay - -Enable SDIO from MMC interface via GPIOs 22-27. Includes the sdhost -overlay to free up the MMC interface. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 15 +++++++++++++++ - arch/arm/boot/dts/overlays/sdio-overlay.dts | 29 +++++++++++++++++++++++++++++ - 3 files changed, 45 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 9b03b1f..43e9c96 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -44,6 +44,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7e38eb3..a749ff7 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -513,6 +513,21 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - debug Enable debug output (default off) - - -+Name: sdio -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, -+ and enables SDIO via GPIOs 22-27. -+Load: dtoverlay=sdio,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 1) -+ -+ debug Enable debug output (default off) -+ -+ - Name: spi-bcm2708 - Info: Selects the bcm2708-spi SPI driver - Load: dtoverlay=spi-bcm2708 -diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts -new file mode 100644 -index 0000000..164f269 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -0,0 +1,29 @@ -+/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ -+ -+/include/ "sdhost-overlay.dts" -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@3 { -+ target = <&mmc>; -+ __overlay__ { -+ compatible = "brcm,bcm2835-mmc"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ non-removable; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ sdio_pins: sdio_pins { -+ brcm,pins = <22 23 24 25 26 27>; -+ brcm,function = <7 7 7 7 7 7>; /* ALT3 = SD1 */ -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ }; -+ }; -+}; - -From a216fc64bde9a95901c92deb7bcd7f3fe4567f75 Mon Sep 17 00:00:00 2001 -From: Luke Wren -Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 168/204] Add /dev/gpiomem device for rootless user GPIO access - -Signed-off-by: Luke Wren ---- - arch/arm/boot/dts/bcm2708.dtsi | 6 + - arch/arm/boot/dts/bcm2709.dtsi | 6 + - drivers/char/broadcom/Kconfig | 9 ++ - drivers/char/broadcom/Makefile | 3 + - drivers/char/broadcom/bcm2835-gpiomem.c | 265 ++++++++++++++++++++++++++++++++ - 5 files changed, 289 insertions(+) - create mode 100644 drivers/char/broadcom/bcm2835-gpiomem.c - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 0d47427..3bed0a6 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -15,5 +15,11 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -+ -+ gpiomem { -+ compatible = "brcm,bcm2835-gpiomem"; -+ reg = <0x7e200000 0x1000>; -+ status = "okay"; -+ }; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index 5e0b935..811d825 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -16,6 +16,12 @@ - compatible = "arm,cortex-a7-pmu"; - interrupts = <3 9>; - }; -+ -+ gpiomem { -+ compatible = "brcm,bcm2835-gpiomem"; -+ reg = <0x7e200000 0x1000>; -+ status = "okay"; -+ }; - }; - - timer { -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index fc40846..bc2eb1e 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -38,3 +38,12 @@ config BCM_VC_SM - help - Support for the VC shared memory on the Broadcom reference - design. Uses the VCHIQ stack. -+ -+config BCM2835_DEVGPIOMEM -+ tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835" -+ default m -+ help -+ Provides users with root-free access to the GPIO registers -+ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO -+ register page to the user's pointer. -+ -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 18171e2..664e2c4 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -2,3 +2,6 @@ obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o - obj-$(CONFIG_BCM_VCIO) += vcio.o - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ -+ -+obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o -+ -diff --git a/drivers/char/broadcom/bcm2835-gpiomem.c b/drivers/char/broadcom/bcm2835-gpiomem.c -new file mode 100644 -index 0000000..0085e13 ---- /dev/null -+++ b/drivers/char/broadcom/bcm2835-gpiomem.c -@@ -0,0 +1,265 @@ -+/** -+ * GPIO memory device driver -+ * -+ * Creates a chardev /dev/gpiomem which will provide user access to -+ * the BCM2835's GPIO registers when it is mmap()'d. -+ * No longer need root for user GPIO access, but without relaxing permissions -+ * on /dev/mem. -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DEVICE_NAME "bcm2835-gpiomem" -+#define DRIVER_NAME "gpiomem-bcm2835" -+#define DEVICE_MINOR 0 -+ -+struct bcm2835_gpiomem_instance { -+ unsigned long gpio_regs_phys; -+ struct device *dev; -+}; -+ -+static struct cdev bcm2835_gpiomem_cdev; -+static dev_t bcm2835_gpiomem_devid; -+static struct class *bcm2835_gpiomem_class; -+static struct device *bcm2835_gpiomem_dev; -+static struct bcm2835_gpiomem_instance *inst; -+ -+ -+/**************************************************************************** -+* -+* GPIO mem chardev file ops -+* -+***************************************************************************/ -+ -+static int bcm2835_gpiomem_open(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ int ret = 0; -+ -+ dev_info(inst->dev, "gpiomem device opened."); -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, "Unknown minor device: %d", dev); -+ ret = -ENXIO; -+ } -+ return ret; -+} -+ -+static int bcm2835_gpiomem_release(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ int ret = 0; -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, "Unknown minor device %d", dev); -+ ret = -ENXIO; -+ } -+ return ret; -+} -+ -+static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = { -+#ifdef CONFIG_HAVE_IOREMAP_PROT -+ .access = generic_access_phys -+#endif -+}; -+ -+static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ /* Ignore what the user says - they're getting the GPIO regs -+ whether they like it or not! */ -+ unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT; -+ -+ vma->vm_page_prot = phys_mem_access_prot(file, gpio_page, -+ PAGE_SIZE, -+ vma->vm_page_prot); -+ vma->vm_ops = &bcm2835_gpiomem_vm_ops; -+ if (remap_pfn_range(vma, vma->vm_start, -+ gpio_page, -+ PAGE_SIZE, -+ vma->vm_page_prot)) { -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+static const struct file_operations -+bcm2835_gpiomem_fops = { -+ .owner = THIS_MODULE, -+ .open = bcm2835_gpiomem_open, -+ .release = bcm2835_gpiomem_release, -+ .mmap = bcm2835_gpiomem_mmap, -+}; -+ -+ -+ /**************************************************************************** -+* -+* Probe and remove functions -+* -+***************************************************************************/ -+ -+ -+static int bcm2835_gpiomem_probe(struct platform_device *pdev) -+{ -+ int err; -+ void *ptr_err; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct resource *ioresource; -+ -+ /* Allocate buffers and instance data */ -+ -+ inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL); -+ -+ if (!inst) { -+ err = -ENOMEM; -+ goto failed_inst_alloc; -+ } -+ -+ inst->dev = dev; -+ -+ /* Create character device entries */ -+ -+ err = alloc_chrdev_region(&bcm2835_gpiomem_devid, -+ DEVICE_MINOR, 1, DEVICE_NAME); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to allocate device number"); -+ goto failed_alloc_chrdev; -+ } -+ cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops); -+ bcm2835_gpiomem_cdev.owner = THIS_MODULE; -+ err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to register device"); -+ goto failed_cdev_add; -+ } -+ -+ /* Create sysfs entries */ -+ -+ bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME); -+ ptr_err = bcm2835_gpiomem_class; -+ if (IS_ERR(ptr_err)) -+ goto failed_class_create; -+ -+ bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL, -+ bcm2835_gpiomem_devid, NULL, -+ "gpiomem"); -+ ptr_err = bcm2835_gpiomem_dev; -+ if (IS_ERR(ptr_err)) -+ goto failed_device_create; -+ -+ /* Get address from device tree if available (*_resource() correctly -+ converts the bus address in device tree to a physical address), -+ or use hardcoded offset + BCM2708_PERI_BASE if not. -+ (In spite of its name 2708 actually seems to have the correct -+ mach-dependent value on 2709 etc, as it is defined in -+ mach-bcm270x/platform.h) */ -+ -+ if (node) { -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ inst->gpio_regs_phys = ioresource->start; -+ } else { -+ inst->gpio_regs_phys = GPIO_BASE; -+ } -+ -+ dev_info(inst->dev, "Initialised: Registers at 0x%08lx", -+ inst->gpio_regs_phys); -+ -+ return 0; -+ -+failed_device_create: -+ class_destroy(bcm2835_gpiomem_class); -+failed_class_create: -+ cdev_del(&bcm2835_gpiomem_cdev); -+ err = PTR_ERR(ptr_err); -+failed_cdev_add: -+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); -+failed_alloc_chrdev: -+ kfree(inst); -+failed_inst_alloc: -+ dev_err(inst->dev, "could not load bcm2835_gpiomem"); -+ return err; -+} -+ -+static int bcm2835_gpiomem_remove(struct platform_device *pdev) -+{ -+ struct device *dev = inst->dev; -+ -+ kfree(inst); -+ device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid); -+ class_destroy(bcm2835_gpiomem_class); -+ cdev_del(&bcm2835_gpiomem_cdev); -+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1); -+ -+ dev_info(dev, "GPIO mem driver removed - OK"); -+ return 0; -+} -+ -+ /**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_gpiomem_of_match[] = { -+ {.compatible = "brcm,bcm2835-gpiomem",}, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match); -+ -+static struct platform_driver bcm2835_gpiomem_driver = { -+ .probe = bcm2835_gpiomem_probe, -+ .remove = bcm2835_gpiomem_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_gpiomem_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_gpiomem_driver); -+ -+MODULE_ALIAS("platform:gpiomem-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); -+MODULE_AUTHOR("Luke Wren "); - -From 4e9cf1447a7ef0f8f46c6a8170f44c78c1690a96 Mon Sep 17 00:00:00 2001 +From d1de66724543ef739151e4d9af7e46c1fce5044a Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:02:34 +0100 -Subject: [PATCH 169/204] tpa6130a2: Add headphone switch control +Subject: [PATCH 096/113] tpa6130a2: Add headphone switch control Signed-off-by: Jan Grulich --- @@ -146273,7 +140275,7 @@ Signed-off-by: Jan Grulich 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c -index 6fac9e0..f60ebe1c 100644 +index 11d85c5..3caaa17 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -4,6 +4,7 @@ @@ -146334,8 +140336,8 @@ index 6fac9e0..f60ebe1c 100644 + * TPA6130 volume. From -59.5 to +4.0 dB with increasing step size when going * down in gain. */ - static const unsigned int tpa6130_tlv[] = { -@@ -278,6 +295,9 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = { + static const DECLARE_TLV_DB_RANGE(tpa6130_tlv, +@@ -277,6 +294,9 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = { TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0, tpa6130a2_get_volsw, tpa6130a2_put_volsw, tpa6130_tlv), @@ -146344,8 +140346,8 @@ index 6fac9e0..f60ebe1c 100644 + tpa6130a2_get_volsw, tpa6130a2_put_hp_sw), }; - static const unsigned int tpa6140_tlv[] = { -@@ -292,6 +312,9 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = { + static const DECLARE_TLV_DB_RANGE(tpa6140_tlv, +@@ -290,6 +310,9 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = { TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0, tpa6130a2_get_volsw, tpa6130a2_put_volsw, tpa6140_tlv), @@ -146356,3901 +140358,250 @@ index 6fac9e0..f60ebe1c 100644 /* -From bdad59048f5910ea3c4439ba40a4a14ca8f1be90 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 11 Jul 2015 18:48:10 +0200 -Subject: [PATCH 170/204] staging: fbtft: Add reset to fbtft_init_display_dt() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +From 04e1e096a209d02766e03e576637171b3a749246 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 28 Sep 2015 17:28:01 +0100 +Subject: [PATCH 097/113] vchiq: hack: Add include depecated dma include file -When an init sequence is present in the Device Tree, -fbtft_init_display_dt() is used to initialize the display. -Add missing reset function call and activation of -chip select for parallel bus. - -Signed-off-by: Noralf Trønnes --- - drivers/staging/fbtft/fbtft-core.c | 5 +++++ - 1 file changed, 5 insertions(+) + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c -index 53b748b..4f165d3 100644 ---- a/drivers/staging/fbtft/fbtft-core.c -+++ b/drivers/staging/fbtft/fbtft-core.c -@@ -1074,6 +1074,11 @@ static int fbtft_init_display_dt(struct fbtft_par *par) - p = of_prop_next_u32(prop, NULL, &val); - if (!p) - return -EINVAL; +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index c9febcc..c29040f 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -45,6 +45,12 @@ + #include + #include + ++#define dmac_map_area __glue(_CACHE,_dma_map_area) ++#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area) + -+ par->fbtftops.reset(par); -+ if (par->gpio.cs != -1) -+ gpio_set_value(par->gpio.cs, 0); /* Activate chip */ ++extern void dmac_map_area(const void *, size_t, int); ++extern void dmac_unmap_area(const void *, size_t, int); + - while (p) { - if (val & FBTFT_OF_INIT_CMD) { - val &= 0xFFFF; + #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + + #define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset)) -From 928b8dbc73acdb75d3f03ef7d5cf9fc639e0280c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 19 Jul 2015 18:57:06 +0200 -Subject: [PATCH 171/204] BCM270X_DT: mz61581: Revert to spi-bcm2708 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +From 0701ed82c6c110f9415476289e94bf773e32d2f6 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 28 Sep 2015 19:06:42 +0100 +Subject: [PATCH 098/113] bcm2709: Remove custom barrier implementation it is + no different to default -The MZ61581 display does not work with spi-bcm2835 and software -chip select. It works before the commit: -spi: bcm2835: transform native-cs to gpio-cs on first spi_setup - -Revert to spi-bcm2708 until the cause has been detected and the -issue resolved. - -Signed-off-by: Noralf Trønnes --- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++ - 1 file changed, 2 insertions(+) + arch/arm/Kconfig | 1 - + arch/arm/mach-bcm2709/include/mach/barriers.h | 3 --- + 2 files changed, 4 deletions(-) + delete mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index c06fe12..f674a66 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -12,6 +12,8 @@ - fragment@0 { - target = <&spi0>; - __overlay__ { -+ /* does not work with spi-bcm2835 using software chip selects */ -+ compatible = "brcm,bcm2708-spi"; - status = "okay"; +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index f40e621..063454c 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -337,7 +337,6 @@ config ARCH_BCM2708 - spidev@0{ + config ARCH_BCM2709 + bool "Broadcom BCM2709 family" +- select ARCH_HAS_BARRIERS if SMP + select CPU_V7 + select HAVE_SMP + select ARM_AMBA +diff --git a/arch/arm/mach-bcm2709/include/mach/barriers.h b/arch/arm/mach-bcm2709/include/mach/barriers.h +deleted file mode 100644 +index 723cdad..0000000 +--- a/arch/arm/mach-bcm2709/include/mach/barriers.h ++++ /dev/null +@@ -1,3 +0,0 @@ +-#define mb() dsb() +-#define rmb() dsb() +-#define wmb() mb() -From 707866acc48470ec677f1fb6befdfd928d9994f1 Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Tue, 1 Sep 2015 16:52:34 +0000 -Subject: [PATCH 172/204] vchiq: fix NULL pointer dereference when closing - driver +From ccab1d0a335b48bcbd1fd3d53a03e0d70f6661b4 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 28 Sep 2015 23:38:59 +0100 +Subject: [PATCH 099/113] irq-bcm2835: Fix building with 2708 -The following code run as root will cause a null pointer dereference oops: - - int fd = open("/dev/vc-cma", O_RDONLY); - if (fd < 0) - err(1, "open failed"); - (void)close(fd); - -[ 1704.877721] Unable to handle kernel NULL pointer dereference at virtual address 00000000 -[ 1704.877725] pgd = b899c000 -[ 1704.877736] [00000000] *pgd=37fab831, *pte=00000000, *ppte=00000000 -[ 1704.877748] Internal error: Oops: 817 [#1] PREEMPT SMP ARM -[ 1704.877765] Modules linked in: evdev i2c_bcm2708 uio_pdrv_genirq uio -[ 1704.877774] CPU: 2 PID: 3656 Comm: stress-ng-fstat Not tainted 3.19.1-12-generic-bcm2709 #12-Ubuntu -[ 1704.877777] Hardware name: BCM2709 -[ 1704.877783] task: b8ab9b00 ti: b7e68000 task.ti: b7e68000 -[ 1704.877798] PC is at __down_interruptible+0x50/0xec -[ 1704.877806] LR is at down_interruptible+0x5c/0x68 -[ 1704.877813] pc : [<80630ee8>] lr : [<800704b0>] psr: 60080093 -sp : b7e69e50 ip : b7e69e88 fp : b7e69e84 -[ 1704.877817] r10: b88123c8 r9 : 00000010 r8 : 00000001 -[ 1704.877822] r7 : b8ab9b00 r6 : 7fffffff r5 : 80a1cc34 r4 : 80a1cc34 -[ 1704.877826] r3 : b7e69e50 r2 : 00000000 r1 : 00000000 r0 : 80a1cc34 -[ 1704.877833] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user -[ 1704.877838] Control: 10c5387d Table: 3899c06a DAC: 00000015 -[ 1704.877843] Process do-oops (pid: 3656, stack limit = 0xb7e68238) -[ 1704.877848] Stack: (0xb7e69e50 to 0xb7e6a000) -[ 1704.877856] 9e40: 80a1cc3c 00000000 00000010 b88123c8 -[ 1704.877865] 9e60: b7e69e84 80a1cc34 fff9fee9 ffffffff b7e68000 00000009 b7e69ea4 b7e69e88 -[ 1704.877874] 9e80: 800704b0 80630ea4 fff9fee9 60080013 80a1cc28 fff9fee9 b7e69edc b7e69ea8 -[ 1704.877884] 9ea0: 8040f558 80070460 fff9fee9 ffffffff 00000000 00000000 00000009 80a1cb7c -[ 1704.877893] 9ec0: 00000000 80a1cb7c 00000000 00000010 b7e69ef4 b7e69ee0 803e1ba4 8040f514 -[ 1704.877902] 9ee0: 00000e48 80a1cb7c b7e69f14 b7e69ef8 803e1c9c 803e1b74 b88123c0 b92acb18 -[ 1704.877911] 9f00: b8812790 b8d815d8 b7e69f24 b7e69f18 803e2250 803e1bc8 b7e69f5c b7e69f28 -[ 1704.877921] 9f20: 80167bac 803e222c 00000000 00000000 b7e69f54 b8ab9ffc 00000000 8098c794 -[ 1704.877930] 9f40: b8ab9b00 8000efc4 b7e68000 00000000 b7e69f6c b7e69f60 80167d6c 80167b28 -[ 1704.877939] 9f60: b7e69f8c b7e69f70 80047d38 80167d60 b7e68000 b7e68010 8000efc4 b7e69fb0 -[ 1704.877949] 9f80: b7e69fac b7e69f90 80012820 80047c84 01155490 011549a8 00000001 00000006 -[ 1704.877957] 9fa0: 00000000 b7e69fb0 8000ee5c 80012790 00000000 353d8c0f 7efc4308 00000000 -[ 1704.877966] 9fc0: 01155490 011549a8 00000001 00000006 00000000 00000000 76cf3ba0 00000003 -[ 1704.877975] 9fe0: 00000000 7efc42e4 0002272f 76e2ed66 60080030 00000003 00000000 00000000 -[ 1704.877998] [<80630ee8>] (__down_interruptible) from [<800704b0>] (down_interruptible+0x5c/0x68) -[ 1704.878015] [<800704b0>] (down_interruptible) from [<8040f558>] (vchiu_queue_push+0x50/0xd8) -[ 1704.878032] [<8040f558>] (vchiu_queue_push) from [<803e1ba4>] (send_worker_msg+0x3c/0x54) -[ 1704.878045] [<803e1ba4>] (send_worker_msg) from [<803e1c9c>] (vc_cma_set_reserve+0xe0/0x1c4) -[ 1704.878057] [<803e1c9c>] (vc_cma_set_reserve) from [<803e2250>] (vc_cma_release+0x30/0x38) -[ 1704.878069] [<803e2250>] (vc_cma_release) from [<80167bac>] (__fput+0x90/0x1e0) -[ 1704.878082] [<80167bac>] (__fput) from [<80167d6c>] (____fput+0x18/0x1c) -[ 1704.878094] [<80167d6c>] (____fput) from [<80047d38>] (task_work_run+0xc0/0xf8) -[ 1704.878109] [<80047d38>] (task_work_run) from [<80012820>] (do_work_pending+0x9c/0xc4) -[ 1704.878123] [<80012820>] (do_work_pending) from [<8000ee5c>] (work_pending+0xc/0x20) -[ 1704.878133] Code: e50b1034 e3a01000 e50b2030 e580300c (e5823000) - -..the fix is to ensure that we have actually initialized the queue before we attempt -to push any items onto it. This occurs if we do an open() followed by a close() without -any activity in between. - -Signed-off-by: Colin Ian King --- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c | 4 ++++ - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h | 1 + - 2 files changed, 5 insertions(+) + drivers/irqchip/irq-bcm2835.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -index 05e7979..384acb8 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c -@@ -46,6 +46,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size) - queue->size = size; - queue->read = 0; - queue->write = 0; -+ queue->initialized = 1; +diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c +index 3f601f9..3478e75 100644 +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -77,6 +77,7 @@ + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 + #define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) ++#undef FIQ_START + #define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) - sema_init(&queue->pop, 0); - sema_init(&queue->push, 0); -@@ -76,6 +77,9 @@ int vchiu_queue_is_full(VCHIU_QUEUE_T *queue) - - void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) - { -+ if (!queue->initialized) -+ return; -+ - while (queue->write == queue->read + queue->size) { - if (down_interruptible(&queue->pop) != 0) { - flush_signals(current); -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -index f4d0b66..4055d4b 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h -@@ -60,6 +60,7 @@ typedef struct { - int size; - int read; - int write; -+ int initialized; - - struct semaphore pop; - struct semaphore push; - -From 2c90639076be957e3e5eb9f44e0c09719db83f7e Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:13:17 -0400 -Subject: [PATCH 173/204] bcm2708_fb: remove redundant code as detected by - static analysis - -static analysis with cppcheck detected some redundant code which -should probably be removed: - -[drivers/video/fbdev/bcm2708_fb.c:269]: (style) Variable 'yres' - is assigned a value that is never used. - -Signed-off-by: Colin Ian King ---- - drivers/video/fbdev/bcm2708_fb.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 06a96d16..fed0672 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -263,12 +263,6 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, - if (var->yoffset > var->yres_virtual - var->yres) - var->yoffset = var->yres_virtual - var->yres - 1; - -- yres = var->yres; -- if (var->vmode & FB_VMODE_DOUBLE) -- yres *= 2; -- else if (var->vmode & FB_VMODE_INTERLACED) -- yres = (yres + 1) / 2; -- - return 0; - } - - -From 473b4d43abe530f11f07dbdd9be666a90d75313c Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:15:38 -0400 -Subject: [PATCH 174/204] bcm2708_fb: remove unnecessary initialization of - result - -static analysis by cppcheck detected an unnecessary initialization -of variable 'result' which is re-assigned almost immediately after -the initialization. Remove the redundant initialization. - -[drivers/video/fbdev/bcm2708_fb.c:406]: (performance) Variable - 'result' is reassigned a value before the old one has been used. - -Signed-off-by: Colin Ian King ---- - drivers/video/fbdev/bcm2708_fb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index fed0672..0f62d76 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -420,7 +420,7 @@ static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) - - static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) - { -- s32 result = -1; -+ s32 result; - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - result = bcm2708_fb_set_par(info); - -From 94946643df81ee3acaeed9a5e0eb8944ab8492fe Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:27:36 -0400 -Subject: [PATCH 175/204] vcsm: increment res_stats MAP_FAIL stats before we - potentially release the resource - -resource can be kfree'd when the reference count is zero, so we should -not bump the res_stats of the resource after the vmcs_sm_release_resource -call since the resource may have been kfree'd by this call. Instead, bump -the stats before we call vmcs_sm_release_resource to avoid a potential -NULL pointer derefernce. - -Bug found using cppcheck static analysis: - -[drivers/char/broadcom/vc_sm/vmcs_sm.c:1373]: (error) Dereferencing - 'resource' after it is deallocated / released - -Signed-off-by: Colin Ian King ---- - drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index 0bfb42e..b62a3b2 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -1368,8 +1368,8 @@ static int vc_sm_mmap(struct file *file, struct vm_area_struct *vma) - return 0; - - error: -- vmcs_sm_release_resource(resource, 0); - resource->res_stats[MAP_FAIL]++; -+ vmcs_sm_release_resource(resource, 0); - return ret; - } - - -From 874c6177f126c4fdb31ed9234fe053581ff632fb Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:33:39 -0400 -Subject: [PATCH 176/204] bcm2835: camera: check for scene not being found - -static analysis by cppcheck detected some potential NULL pointer -dereference issues: - -[drivers/media/platform/bcm2835/controls.c:854]: (error) Possible null - pointer dereference: scene - (and lines 858, 859 too) - -it is possible that scene is not found because of an invalue ctrl->val -and is therefore NULL and hence causing a null pointer dereference. - -Signed-off-by: Colin Ian King ---- - drivers/media/platform/bcm2835/controls.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c -index 3017b94..f9f903f 100644 ---- a/drivers/media/platform/bcm2835/controls.c -+++ b/drivers/media/platform/bcm2835/controls.c -@@ -845,6 +845,8 @@ static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev, - break; - } + static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; +@@ -218,7 +219,7 @@ static int __init armctrl_of_init(struct device_node *node, + MAKE_HWIRQ(b, i) + NUMBER_IRQS); + BUG_ON(irq <= 0); + irq_set_chip(irq, &armctrl_chip); +- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); } -+ if (!scene) -+ return -EINVAL; - if (i >= ARRAY_SIZE(scene_configs)) - return -EINVAL; - + } + init_FIQ(FIQ_START); -From a255eb898f2ff3d63de6dbc201797ff732499dca Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Wed, 2 Sep 2015 07:47:51 -0400 -Subject: [PATCH 177/204] bcm2835: memcpy port data to m rather than rmsg - -static analysis by cppcheck detected a memcpy to rmsg which is -not actually initialized at that point. The memcpy should be copying -to variable m instead. - -Signed-off-by: Colin Ian King ---- - drivers/media/platform/bcm2835/mmal-vchiq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c -index 76f249e..7813225 100644 ---- a/drivers/media/platform/bcm2835/mmal-vchiq.c -+++ b/drivers/media/platform/bcm2835/mmal-vchiq.c -@@ -851,7 +851,7 @@ static int port_info_set(struct vchiq_mmal_instance *instance, - sizeof(union mmal_es_specific_format)); - - m.u.port_info_set.format.extradata_size = port->format.extradata_size; -- memcpy(rmsg->u.port_info_set.extradata, port->format.extradata, -+ memcpy(&m.u.port_info_set.extradata, port->format.extradata, - port->format.extradata_size); - - ret = send_synchronous_mmal_msg(instance, &m, - -From bd4d78dcb66955bc2ea1c81232db499e1f662ac6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 13 Sep 2015 15:54:28 +0200 -Subject: [PATCH 178/204] Revert "BCM270X_DT: mz61581: Revert to spi-bcm2708" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 1820cd05d93b2d465d1616202772efe5bf0d11fe. - -The spi-bcm2835 driver has been fixed, so now we can use it again. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index f674a66..c06fe12 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -12,8 +12,6 @@ - fragment@0 { - target = <&spi0>; - __overlay__ { -- /* does not work with spi-bcm2835 using software chip selects */ -- compatible = "brcm,bcm2708-spi"; - status = "okay"; - - spidev@0{ - -From 63103cf8b12f79c02f1a6d7a851fbb6727528d33 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 13 Sep 2015 17:17:14 +0200 -Subject: [PATCH 179/204] BCM270X_DT: mz61581: Set txbuflen to 32k -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Because of the spi dma mapping/engine overhead with spi-bcm2835, -txbuflen has to be increased from 4096 to 32768 to maximize -throughput (11MB/s at 128MHz). - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index a749ff7..0aa5aa1 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -368,6 +368,8 @@ Params: speed Display SPI bus speed - - fps Delay between frame updates - -+ txbuflen Transmit buffer length (default 32768) -+ - debug Debug output level {0-7} - - xohms Touchpanel sensitivity (X-plate resistance) -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index c06fe12..9242a6e 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -57,6 +57,7 @@ - bgr; - fps = <30>; - buswidth = <8>; -+ txbuflen = <32768>; - - reset-gpios = <&gpio 15 0>; - dc-gpios = <&gpio 25 0>; -@@ -103,6 +104,7 @@ - speed = <&mz61581>, "spi-max-frequency:0"; - rotate = <&mz61581>, "rotate:0"; - fps = <&mz61581>, "fps:0"; -+ txbuflen = <&mz61581>, "txbuflen:0"; - debug = <&mz61581>, "debug:0"; - xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; - }; - -From 6881996989b77354049455c95e8af67f278cfa48 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 11 Sep 2015 12:10:15 +0100 -Subject: [PATCH 180/204] bcm2835-mmc: Don't overwrite MMC capabilities from DT +From a7362ad916d411d3a9df4af0a8261a1baea83f80 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 30 Sep 2015 13:58:30 +0100 +Subject: [PATCH 100/113] dwc_otg: Remove duplicate gadget probe/unregister + function --- - drivers/mmc/host/bcm2835-mmc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) + drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 84 +--------------------------- + 1 file changed, 2 insertions(+), 82 deletions(-) -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index b7c4883..164bfad 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1327,8 +1327,9 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; - #endif - /* host controller capabilities */ -- mmc->caps = MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ | -- MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; -+ mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | -+ MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | -+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; - - host->flags = SDHCI_AUTO_CMD23; - - -From 7bbc4815e21230a8a011d3f3cf794d765cdacb35 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 11 Sep 2015 09:14:01 +0100 -Subject: [PATCH 181/204] BCM270X_DT: Use fixed-factor-clock for uart1 - -The BCM2835 mini-UART is almost 8250-compatible, but there is -a factor-of-two difference in the clock divider for the baud rate. -The standard 8250 driver can be used unmodified provided we lie to it -about the clock frequency, pretending it is double the actual value. -The mini-UART block shares the core clock, and the current firmware -uses a DT-parameter to update the clock-frequency property. Although it -works, this isn't ideal because it exposes the firmware to a driver -problem. - -This patch uses the fixed-factor-clock module to create a clock that is -always twice the frequency of the core clock. (N.B. These "fixed" clocks -just describe an existing clock, rather than changing any hardware -settings.) ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 - - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 - - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 - - arch/arm/boot/dts/bcm2708_common.dtsi | 10 +++++++++- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 - - 5 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 3ad2e0d..e3ae8e6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -103,7 +103,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e2b1491..2adc248 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -97,7 +97,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 96d8b97..bddc369 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -79,7 +79,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index f096f45..4d1cc67 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -165,7 +165,7 @@ - compatible = "brcm,bcm2835-aux-uart", "ns16550"; - reg = <0x7e215040 0x40>; - interrupts = <1 29>; -- clock-frequency = <500000000>; -+ clocks = <&clk_uart1>; - reg-shift = <2>; - no-loopback-test; - status = "disabled"; -@@ -294,6 +294,14 @@ - clock-output-names = "pwm"; - clock-frequency = <100000000>; - }; -+ -+ clk_uart1: clock@6 { -+ compatible = "fixed-factor-clock"; -+ clocks = <&clk_core>; -+ #clock-cells = <0>; -+ clock-div = <1>; -+ clock-mult = <2>; -+ }; - }; - - __overrides__ { -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index f25f0a2..76d44a2 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -103,7 +103,6 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -- uart1_clkrate = <&uart1>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - -From d851a069d33dba42c5c7fa023ee13f994643fa90 Mon Sep 17 00:00:00 2001 -From: Luke Wren -Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 182/204] Add SMI driver - -Signed-off-by: Luke Wren ---- - .../bindings/misc/brcm,bcm2835-smi-dev.txt | 17 + - .../devicetree/bindings/misc/brcm,bcm2835-smi.txt | 48 + - arch/arm/boot/dts/bcm2708_common.dtsi | 11 + - arch/arm/boot/dts/overlays/Makefile | 2 + - arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + - arch/arm/boot/dts/overlays/smi-overlay.dts | 37 + - drivers/char/broadcom/Kconfig | 8 + - drivers/char/broadcom/Makefile | 2 +- - drivers/char/broadcom/bcm2835_smi_dev.c | 402 +++++++++ - drivers/misc/Kconfig | 8 + - drivers/misc/Makefile | 1 + - drivers/misc/bcm2835_smi.c | 985 +++++++++++++++++++++ - include/linux/broadcom/bcm2835_smi.h | 391 ++++++++ - 13 files changed, 1929 insertions(+), 1 deletion(-) - create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt - create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt - create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts - create mode 100644 drivers/char/broadcom/bcm2835_smi_dev.c - create mode 100644 drivers/misc/bcm2835_smi.c - create mode 100644 include/linux/broadcom/bcm2835_smi.h - -diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt -new file mode 100644 -index 0000000..68cc8eb ---- /dev/null -+++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt -@@ -0,0 +1,17 @@ -+* Broadcom BCM2835 SMI character device driver. -+ -+SMI or secondary memory interface is a peripheral specific to certain Broadcom -+SOCs, and is helpful for talking to things like parallel-interface displays -+and NAND flashes (in fact, most things with a parallel register interface). -+ -+This driver adds a character device which provides a user-space interface to -+an instance of the SMI driver. -+ -+Required properties: -+- compatible: "brcm,bcm2835-smi-dev" -+- smi_handle: a phandle to the smi node. -+ -+Optional properties: -+- None. -+ -+ -diff --git a/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt -new file mode 100644 -index 0000000..b76dc69 ---- /dev/null -+++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt -@@ -0,0 +1,48 @@ -+* Broadcom BCM2835 SMI driver. -+ -+SMI or secondary memory interface is a peripheral specific to certain Broadcom -+SOCs, and is helpful for talking to things like parallel-interface displays -+and NAND flashes (in fact, most things with a parallel register interface). -+ -+Required properties: -+- compatible: "brcm,bcm2835-smi" -+- reg: Should contain location and length of SMI registers and SMI clkman regs -+- interrupts: *the* SMI interrupt. -+- pinctrl-names: should be "default". -+- pinctrl-0: the phandle of the gpio pin node. -+- brcm,smi-clock-source: the clock source for clkman -+- brcm,smi-clock-divisor: the integer clock divisor for clkman -+- dmas: the dma controller phandle and the DREQ number (4 on a 2835) -+- dma-names: the name used by the driver to request its channel. -+ Should be "rx-tx". -+ -+Optional properties: -+- None. -+ -+Examples: -+ -+8 data pin configuration: -+ -+smi: smi@7e600000 { -+ compatible = "brcm,bcm2835-smi"; -+ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; -+ interrupts = <2 16>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&smi_pins>; -+ brcm,smi-clock-source = <6>; -+ brcm,smi-clock-divisor = <4>; -+ dmas = <&dma 4>; -+ dma-names = "rx-tx"; -+ -+ status = "okay"; -+}; -+ -+smi_pins: smi_pins { -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15>; -+ /* Alt 1: SMI */ -+ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>; -+ /* /CS, /WE and /OE are pulled high, as they are -+ generally active low signals */ -+ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0>; -+}; -+ -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4d1cc67..933711e 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -205,6 +205,17 @@ - status = "disabled"; - }; - -+ smi: smi@7e600000 { -+ compatible = "brcm,bcm2835-smi"; -+ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; -+ interrupts = <2 16>; -+ brcm,smi-clock-source = <6>; -+ brcm,smi-clock-divisor = <4>; -+ dmas = <&dma 4>; -+ dma-names = "rx-tx"; -+ status = "disabled"; -+ }; -+ - usb: usb@7e980000 { - compatible = "brcm,bcm2708-usb"; - reg = <0x7e980000 0x10000>, -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 43e9c96..f8f2c034 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,8 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/smi-dev-overlay.dts b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts -new file mode 100644 -index 0000000..b610d82 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts -@@ -0,0 +1,18 @@ -+// Description: Overlay to enable character device interface for SMI. -+// Author: Luke Wren -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ fragment@0 { -+ target = <&soc>; -+ __overlay__ { -+ smi_dev { -+ compatible = "brcm,bcm2835-smi-dev"; -+ smi_handle = <&smi>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/smi-overlay.dts b/arch/arm/boot/dts/overlays/smi-overlay.dts -new file mode 100644 -index 0000000..095f52c ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/smi-overlay.dts -@@ -0,0 +1,37 @@ -+// Description: Overlay to enable the secondary memory interface peripheral -+// Author: Luke Wren -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&smi>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&smi_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ smi_pins: smi_pins { -+ /* Don't configure the top two address bits, as -+ these are already used as ID_SD and ID_SC */ -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 -+ 16 17 18 19 20 21 22 23 24 25>; -+ /* Alt 0: SMI */ -+ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 -+ 5 5 5 5 5 5 5 5 5>; -+ /* /CS, /WE and /OE are pulled high, as they are -+ generally active low signals */ -+ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 -+ 0 0 0 0 0 0 0>; -+ }; -+ }; -+ }; -+}; -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index bc2eb1e..5489f19 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -47,3 +47,11 @@ config BCM2835_DEVGPIOMEM - on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO - register page to the user's pointer. - -+config BCM2835_SMI_DEV -+ tristate "Character device driver for BCM2835 Secondary Memory Interface" -+ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI -+ default m -+ help -+ This driver provides a character device interface (ioctl + read/write) to -+ Broadcom's Secondary Memory interface. The low-level functionality is provided -+ by the SMI driver itself. -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 664e2c4..14775c9 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -4,4 +4,4 @@ obj-$(CONFIG_BCM_VCIO) += vcio.o - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ - - obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o -- -+obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o -diff --git a/drivers/char/broadcom/bcm2835_smi_dev.c b/drivers/char/broadcom/bcm2835_smi_dev.c -new file mode 100644 -index 0000000..d6efd92 ---- /dev/null -+++ b/drivers/char/broadcom/bcm2835_smi_dev.c -@@ -0,0 +1,402 @@ -+/** -+ * Character device driver for Broadcom Secondary Memory Interface -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DEVICE_NAME "bcm2835-smi-dev" -+#define DRIVER_NAME "smi-dev-bcm2835" -+#define DEVICE_MINOR 0 -+ -+static struct cdev bcm2835_smi_cdev; -+static dev_t bcm2835_smi_devid; -+static struct class *bcm2835_smi_class; -+static struct device *bcm2835_smi_dev; -+ -+struct bcm2835_smi_dev_instance { -+ struct device *dev; -+}; -+ -+static struct bcm2835_smi_instance *smi_inst; -+static struct bcm2835_smi_dev_instance *inst; -+ -+static const char *const ioctl_names[] = { -+ "READ_SETTINGS", -+ "WRITE_SETTINGS", -+ "ADDRESS" -+}; -+ -+/**************************************************************************** -+* -+* SMI chardev file ops -+* -+***************************************************************************/ -+static long -+bcm2835_smi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long ret = 0; -+ -+ dev_info(inst->dev, "serving ioctl..."); -+ -+ switch (cmd) { -+ case BCM2835_SMI_IOC_GET_SETTINGS:{ -+ struct smi_settings *settings; -+ -+ dev_info(inst->dev, "Reading SMI settings to user."); -+ settings = bcm2835_smi_get_settings_from_regs(smi_inst); -+ if (copy_to_user((void *)arg, settings, -+ sizeof(struct smi_settings))) -+ dev_err(inst->dev, "settings copy failed."); -+ break; -+ } -+ case BCM2835_SMI_IOC_WRITE_SETTINGS:{ -+ struct smi_settings *settings; -+ -+ dev_info(inst->dev, "Setting user's SMI settings."); -+ settings = bcm2835_smi_get_settings_from_regs(smi_inst); -+ if (copy_from_user(settings, (void *)arg, -+ sizeof(struct smi_settings))) -+ dev_err(inst->dev, "settings copy failed."); -+ else -+ bcm2835_smi_set_regs_from_settings(smi_inst); -+ break; -+ } -+ case BCM2835_SMI_IOC_ADDRESS: -+ dev_info(inst->dev, "SMI address set: 0x%02x", (int)arg); -+ bcm2835_smi_set_address(smi_inst, arg); -+ break; -+ default: -+ dev_err(inst->dev, "invalid ioctl cmd: %d", cmd); -+ ret = -ENOTTY; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int bcm2835_smi_open(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ -+ dev_dbg(inst->dev, "SMI device opened."); -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, -+ "bcm2835_smi_release: Unknown minor device: %d", -+ dev); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_smi_release(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ -+ if (dev != DEVICE_MINOR) { -+ dev_err(inst->dev, -+ "bcm2835_smi_release: Unknown minor device %d", dev); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ -+static ssize_t dma_bounce_user( -+ enum dma_transfer_direction dma_dir, -+ char __user *user_ptr, -+ size_t count, -+ struct bcm2835_smi_bounce_info *bounce) -+{ -+ int chunk_size; -+ int chunk_no = 0; -+ int count_left = count; -+ -+ while (count_left) { -+ int rv; -+ void *buf; -+ -+ /* Wait for current chunk to complete: */ -+ if (down_timeout(&bounce->callback_sem, -+ msecs_to_jiffies(1000))) { -+ dev_err(inst->dev, "DMA bounce timed out"); -+ count -= (count_left); -+ break; -+ } -+ -+ if (bounce->callback_sem.count >= DMA_BOUNCE_BUFFER_COUNT - 1) -+ dev_err(inst->dev, "WARNING: Ring buffer overflow"); -+ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? -+ DMA_BOUNCE_BUFFER_SIZE : count_left; -+ buf = bounce->buffer[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; -+ if (dma_dir == DMA_DEV_TO_MEM) -+ rv = copy_to_user(user_ptr, buf, chunk_size); -+ else -+ rv = copy_from_user(buf, user_ptr, chunk_size); -+ if (rv) -+ dev_err(inst->dev, "copy_*_user() failed!: %d", rv); -+ user_ptr += chunk_size; -+ count_left -= chunk_size; -+ chunk_no++; -+ } -+ return count; -+} -+ -+static ssize_t -+bcm2835_read_file(struct file *f, char __user *user_ptr, -+ size_t count, loff_t *offs) -+{ -+ int odd_bytes; -+ -+ dev_dbg(inst->dev, "User reading %d bytes from SMI.", count); -+ /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */ -+ if (count > DMA_THRESHOLD_BYTES) -+ odd_bytes = count & 0x3; -+ else -+ odd_bytes = count; -+ count -= odd_bytes; -+ if (count) { -+ struct bcm2835_smi_bounce_info *bounce; -+ -+ count = bcm2835_smi_user_dma(smi_inst, -+ DMA_DEV_TO_MEM, user_ptr, count, -+ &bounce); -+ if (count) -+ count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr, -+ count, bounce); -+ } -+ if (odd_bytes) { -+ /* Read from FIFO directly if not using DMA */ -+ uint8_t buf[DMA_THRESHOLD_BYTES]; -+ -+ bcm2835_smi_read_buf(smi_inst, buf, odd_bytes); -+ if (copy_to_user(user_ptr, buf, odd_bytes)) -+ dev_err(inst->dev, "copy_to_user() failed."); -+ count += odd_bytes; -+ -+ } -+ return count; -+} -+ -+static ssize_t -+bcm2835_write_file(struct file *f, const char __user *user_ptr, -+ size_t count, loff_t *offs) -+{ -+ int odd_bytes; -+ -+ dev_dbg(inst->dev, "User writing %d bytes to SMI.", count); -+ if (count > DMA_THRESHOLD_BYTES) -+ odd_bytes = count & 0x3; -+ else -+ odd_bytes = count; -+ count -= odd_bytes; -+ if (count) { -+ struct bcm2835_smi_bounce_info *bounce; -+ -+ count = bcm2835_smi_user_dma(smi_inst, -+ DMA_MEM_TO_DEV, (char __user *)user_ptr, count, -+ &bounce); -+ if (count) -+ count = dma_bounce_user(DMA_MEM_TO_DEV, -+ (char __user *)user_ptr, -+ count, bounce); -+ } -+ if (odd_bytes) { -+ uint8_t buf[DMA_THRESHOLD_BYTES]; -+ -+ if (copy_from_user(buf, user_ptr, odd_bytes)) -+ dev_err(inst->dev, "copy_from_user() failed."); -+ else -+ bcm2835_smi_write_buf(smi_inst, buf, odd_bytes); -+ count += odd_bytes; -+ } -+ return count; -+} -+ -+static const struct file_operations -+bcm2835_smi_fops = { -+ .owner = THIS_MODULE, -+ .unlocked_ioctl = bcm2835_smi_ioctl, -+ .open = bcm2835_smi_open, -+ .release = bcm2835_smi_release, -+ .read = bcm2835_read_file, -+ .write = bcm2835_write_file, -+}; -+ -+ -+/**************************************************************************** -+* -+* bcm2835_smi_probe - called when the driver is loaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_dev_probe(struct platform_device *pdev) -+{ -+ int err; -+ void *ptr_err; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node, *smi_node; -+ -+ if (!node) { -+ dev_err(dev, "No device tree node supplied!"); -+ return -EINVAL; -+ } -+ -+ smi_node = of_parse_phandle(node, "smi_handle", 0); -+ -+ if (!smi_node) { -+ dev_err(dev, "No such property: smi_handle"); -+ return -ENXIO; -+ } -+ -+ smi_inst = bcm2835_smi_get(smi_node); -+ -+ if (!smi_inst) -+ return -EPROBE_DEFER; -+ -+ /* Allocate buffers and instance data */ -+ -+ inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL); -+ -+ if (!inst) -+ return -ENOMEM; -+ -+ inst->dev = dev; -+ -+ /* Create character device entries */ -+ -+ err = alloc_chrdev_region(&bcm2835_smi_devid, -+ DEVICE_MINOR, 1, DEVICE_NAME); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to allocate device number"); -+ return -ENOMEM; -+ } -+ cdev_init(&bcm2835_smi_cdev, &bcm2835_smi_fops); -+ bcm2835_smi_cdev.owner = THIS_MODULE; -+ err = cdev_add(&bcm2835_smi_cdev, bcm2835_smi_devid, 1); -+ if (err != 0) { -+ dev_err(inst->dev, "unable to register device"); -+ err = -ENOMEM; -+ goto failed_cdev_add; -+ } -+ -+ /* Create sysfs entries */ -+ -+ bcm2835_smi_class = class_create(THIS_MODULE, DEVICE_NAME); -+ ptr_err = bcm2835_smi_class; -+ if (IS_ERR(ptr_err)) -+ goto failed_class_create; -+ -+ bcm2835_smi_dev = device_create(bcm2835_smi_class, NULL, -+ bcm2835_smi_devid, NULL, -+ "smi"); -+ ptr_err = bcm2835_smi_dev; -+ if (IS_ERR(ptr_err)) -+ goto failed_device_create; -+ -+ dev_info(inst->dev, "initialised"); -+ -+ return 0; -+ -+failed_device_create: -+ class_destroy(bcm2835_smi_class); -+failed_class_create: -+ cdev_del(&bcm2835_smi_cdev); -+ err = PTR_ERR(ptr_err); -+failed_cdev_add: -+ unregister_chrdev_region(bcm2835_smi_devid, 1); -+ dev_err(dev, "could not load bcm2835_smi_dev"); -+ return err; -+} -+ -+/**************************************************************************** -+* -+* bcm2835_smi_remove - called when the driver is unloaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_dev_remove(struct platform_device *pdev) -+{ -+ device_destroy(bcm2835_smi_class, bcm2835_smi_devid); -+ class_destroy(bcm2835_smi_class); -+ cdev_del(&bcm2835_smi_cdev); -+ unregister_chrdev_region(bcm2835_smi_devid, 1); -+ -+ dev_info(inst->dev, "SMI character dev removed - OK"); -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_smi_dev_of_match[] = { -+ {.compatible = "brcm,bcm2835-smi-dev",}, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_smi_dev_of_match); -+ -+static struct platform_driver bcm2835_smi_dev_driver = { -+ .probe = bcm2835_smi_dev_probe, -+ .remove = bcm2835_smi_dev_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_smi_dev_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_smi_dev_driver); -+ -+MODULE_ALIAS("platform:smi-dev-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION( -+ "Character device driver for BCM2835's secondary memory interface"); -+MODULE_AUTHOR("Luke Wren "); -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 4e6f46c3..8b82c9b 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D - select INPUT_POLLDEV - default n - -+config BCM2835_SMI -+ tristate "Broadcom 283x Secondary Memory Interface driver" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ default m -+ help -+ Driver for enabling and using Broadcom's Secondary/Slow Memory Interface. -+ Appears as /dev/bcm2835_smi. For ioctl interface see drivers/misc/bcm2835_smi.h -+ - config AD525X_DPOT - tristate "Analog Devices Digital Potentiometers" - depends on (I2C || SPI) && SYSFS -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 43d2ac9..b668a08 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o - obj-$(CONFIG_INTEL_MID_PTI) += pti.o - obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o - obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o -+obj-$(CONFIG_BCM2835_SMI) += bcm2835_smi.o - obj-$(CONFIG_BMP085) += bmp085.o - obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o - obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o -diff --git a/drivers/misc/bcm2835_smi.c b/drivers/misc/bcm2835_smi.c -new file mode 100644 -index 0000000..63a4ea0 ---- /dev/null -+++ b/drivers/misc/bcm2835_smi.c -@@ -0,0 +1,985 @@ -+/** -+ * Broadcom Secondary Memory Interface driver -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BCM2835_SMI_IMPLEMENTATION -+#include -+ -+#define DRIVER_NAME "smi-bcm2835" -+ -+#define N_PAGES_FROM_BYTES(n) ((n + PAGE_SIZE-1) / PAGE_SIZE) -+ -+#define DMA_WRITE_TO_MEM true -+#define DMA_READ_FROM_MEM false -+ -+struct bcm2835_smi_instance { -+ struct device *dev; -+ struct smi_settings settings; -+ __iomem void *smi_regs_ptr, *cm_smi_regs_ptr; -+ dma_addr_t smi_regs_busaddr; -+ -+ struct dma_chan *dma_chan; -+ struct dma_slave_config dma_config; -+ -+ struct bcm2835_smi_bounce_info bounce; -+ -+ struct scatterlist buffer_sgl; -+ -+ int clock_source; -+ int clock_divisor; -+ -+ /* Sometimes we are called into in an atomic context (e.g. by -+ JFFS2 + MTD) so we can't use a mutex */ -+ spinlock_t transaction_lock; -+}; -+ -+/**************************************************************************** -+* -+* SMI clock manager setup -+* -+***************************************************************************/ -+ -+static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst, -+ u32 val, unsigned reg) -+{ -+ writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg); -+} -+ -+static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst, -+ unsigned reg) -+{ -+ return readl(inst->cm_smi_regs_ptr + reg); -+} -+ -+static void smi_setup_clock(struct bcm2835_smi_instance *inst) -+{ -+ dev_dbg(inst->dev, "Setting up clock..."); -+ /* Disable SMI clock and wait for it to stop. */ -+ write_smi_cm_reg(inst, 0, CM_SMI_CTL); -+ while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY) -+ ; -+ -+ write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS), -+ CM_SMI_DIV); -+ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS), -+ CM_SMI_CTL); -+ -+ /* Enable the clock */ -+ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) | -+ CM_SMI_CTL_ENAB, CM_SMI_CTL); -+} -+ -+/**************************************************************************** -+* -+* SMI peripheral setup -+* -+***************************************************************************/ -+ -+static inline void write_smi_reg(struct bcm2835_smi_instance *inst, -+ u32 val, unsigned reg) -+{ -+ writel(val, inst->smi_regs_ptr + reg); -+} -+ -+static inline u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg) -+{ -+ return readl(inst->smi_regs_ptr + reg); -+} -+ -+/* Token-paste macro for e.g SMIDSR_RSTROBE -> value of SMIDSR_RSTROBE_MASK */ -+#define _CONCAT(x, y) x##y -+#define CONCAT(x, y) _CONCAT(x, y) -+ -+#define SET_BIT_FIELD(dest, field, bits) ((dest) = \ -+ ((dest) & ~CONCAT(field, _MASK)) | (((bits) << CONCAT(field, _OFFS))& \ -+ CONCAT(field, _MASK))) -+#define GET_BIT_FIELD(src, field) (((src) & \ -+ CONCAT(field, _MASK)) >> CONCAT(field, _OFFS)) -+ -+static void smi_dump_context_labelled(struct bcm2835_smi_instance *inst, -+ const char *label) -+{ -+ dev_err(inst->dev, "SMI context dump: %s", label); -+ dev_err(inst->dev, "SMICS: 0x%08x", read_smi_reg(inst, SMICS)); -+ dev_err(inst->dev, "SMIL: 0x%08x", read_smi_reg(inst, SMIL)); -+ dev_err(inst->dev, "SMIDSR: 0x%08x", read_smi_reg(inst, SMIDSR0)); -+ dev_err(inst->dev, "SMIDSW: 0x%08x", read_smi_reg(inst, SMIDSW0)); -+ dev_err(inst->dev, "SMIDC: 0x%08x", read_smi_reg(inst, SMIDC)); -+ dev_err(inst->dev, "SMIFD: 0x%08x", read_smi_reg(inst, SMIFD)); -+ dev_err(inst->dev, " "); -+} -+ -+static inline void smi_dump_context(struct bcm2835_smi_instance *inst) -+{ -+ smi_dump_context_labelled(inst, ""); -+} -+ -+static void smi_get_default_settings(struct bcm2835_smi_instance *inst) -+{ -+ struct smi_settings *settings = &inst->settings; -+ -+ settings->data_width = SMI_WIDTH_16BIT; -+ settings->pack_data = true; -+ -+ settings->read_setup_time = 1; -+ settings->read_hold_time = 1; -+ settings->read_pace_time = 1; -+ settings->read_strobe_time = 3; -+ -+ settings->write_setup_time = settings->read_setup_time; -+ settings->write_hold_time = settings->read_hold_time; -+ settings->write_pace_time = settings->read_pace_time; -+ settings->write_strobe_time = settings->read_strobe_time; -+ -+ settings->dma_enable = true; -+ settings->dma_passthrough_enable = false; -+ settings->dma_read_thresh = 0x01; -+ settings->dma_write_thresh = 0x3f; -+ settings->dma_panic_read_thresh = 0x20; -+ settings->dma_panic_write_thresh = 0x20; -+} -+ -+void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst) -+{ -+ struct smi_settings *settings = &inst->settings; -+ int smidsr_temp = 0, smidsw_temp = 0, smics_temp, -+ smidcs_temp, smidc_temp = 0; -+ -+ spin_lock(&inst->transaction_lock); -+ -+ /* temporarily disable the peripheral: */ -+ smics_temp = read_smi_reg(inst, SMICS); -+ write_smi_reg(inst, 0, SMICS); -+ smidcs_temp = read_smi_reg(inst, SMIDCS); -+ write_smi_reg(inst, 0, SMIDCS); -+ -+ if (settings->pack_data) -+ smics_temp |= SMICS_PXLDAT; -+ else -+ smics_temp &= ~SMICS_PXLDAT; -+ -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time); -+ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time); -+ write_smi_reg(inst, smidsr_temp, SMIDSR0); -+ -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width); -+ if (settings->data_width == SMI_WIDTH_8BIT) -+ smidsw_temp |= SMIDSW_WSWAP; -+ else -+ smidsw_temp &= ~SMIDSW_WSWAP; -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time); -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time); -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time); -+ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE, -+ settings->write_strobe_time); -+ write_smi_reg(inst, smidsw_temp, SMIDSW0); -+ -+ SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh); -+ SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh); -+ SET_BIT_FIELD(smidc_temp, SMIDC_PANICR, -+ settings->dma_panic_read_thresh); -+ SET_BIT_FIELD(smidc_temp, SMIDC_PANICW, -+ settings->dma_panic_write_thresh); -+ if (settings->dma_passthrough_enable) { -+ smidc_temp |= SMIDC_DMAP; -+ smidsr_temp |= SMIDSR_RDREQ; -+ write_smi_reg(inst, smidsr_temp, SMIDSR0); -+ smidsw_temp |= SMIDSW_WDREQ; -+ write_smi_reg(inst, smidsw_temp, SMIDSW0); -+ } else -+ smidc_temp &= ~SMIDC_DMAP; -+ if (settings->dma_enable) -+ smidc_temp |= SMIDC_DMAEN; -+ else -+ smidc_temp &= ~SMIDC_DMAEN; -+ -+ write_smi_reg(inst, smidc_temp, SMIDC); -+ -+ /* re-enable (if was previously enabled) */ -+ write_smi_reg(inst, smics_temp, SMICS); -+ write_smi_reg(inst, smidcs_temp, SMIDCS); -+ -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_set_regs_from_settings); -+ -+struct smi_settings *bcm2835_smi_get_settings_from_regs -+ (struct bcm2835_smi_instance *inst) -+{ -+ struct smi_settings *settings = &inst->settings; -+ int smidsr, smidsw, smidc; -+ -+ spin_lock(&inst->transaction_lock); -+ -+ smidsr = read_smi_reg(inst, SMIDSR0); -+ smidsw = read_smi_reg(inst, SMIDSW0); -+ smidc = read_smi_reg(inst, SMIDC); -+ -+ settings->pack_data = (read_smi_reg(inst, SMICS) & SMICS_PXLDAT) ? -+ true : false; -+ -+ settings->data_width = GET_BIT_FIELD(smidsr, SMIDSR_RWIDTH); -+ settings->read_setup_time = GET_BIT_FIELD(smidsr, SMIDSR_RSETUP); -+ settings->read_hold_time = GET_BIT_FIELD(smidsr, SMIDSR_RHOLD); -+ settings->read_pace_time = GET_BIT_FIELD(smidsr, SMIDSR_RPACE); -+ settings->read_strobe_time = GET_BIT_FIELD(smidsr, SMIDSR_RSTROBE); -+ -+ settings->write_setup_time = GET_BIT_FIELD(smidsw, SMIDSW_WSETUP); -+ settings->write_hold_time = GET_BIT_FIELD(smidsw, SMIDSW_WHOLD); -+ settings->write_pace_time = GET_BIT_FIELD(smidsw, SMIDSW_WPACE); -+ settings->write_strobe_time = GET_BIT_FIELD(smidsw, SMIDSW_WSTROBE); -+ -+ settings->dma_read_thresh = GET_BIT_FIELD(smidc, SMIDC_REQR); -+ settings->dma_write_thresh = GET_BIT_FIELD(smidc, SMIDC_REQW); -+ settings->dma_panic_read_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICR); -+ settings->dma_panic_write_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICW); -+ settings->dma_passthrough_enable = (smidc & SMIDC_DMAP) ? true : false; -+ settings->dma_enable = (smidc & SMIDC_DMAEN) ? true : false; -+ -+ spin_unlock(&inst->transaction_lock); -+ -+ return settings; -+} -+EXPORT_SYMBOL(bcm2835_smi_get_settings_from_regs); -+ -+static inline void smi_set_address(struct bcm2835_smi_instance *inst, -+ unsigned int address) -+{ -+ int smia_temp = 0, smida_temp = 0; -+ -+ SET_BIT_FIELD(smia_temp, SMIA_ADDR, address); -+ SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address); -+ -+ /* Write to both address registers - user doesn't care whether we're -+ doing programmed or direct transfers. */ -+ write_smi_reg(inst, smia_temp, SMIA); -+ write_smi_reg(inst, smida_temp, SMIDA); -+} -+ -+static void smi_setup_regs(struct bcm2835_smi_instance *inst) -+{ -+ -+ dev_dbg(inst->dev, "Initialising SMI registers..."); -+ /* Disable the peripheral if already enabled */ -+ write_smi_reg(inst, 0, SMICS); -+ write_smi_reg(inst, 0, SMIDCS); -+ -+ smi_get_default_settings(inst); -+ bcm2835_smi_set_regs_from_settings(inst); -+ smi_set_address(inst, 0); -+ -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ENABLE, SMICS); -+ write_smi_reg(inst, read_smi_reg(inst, SMIDCS) | SMIDCS_ENABLE, -+ SMIDCS); -+} -+ -+/**************************************************************************** -+* -+* Low-level SMI access functions -+* Other modules should use the exported higher-level functions e.g. -+* bcm2835_smi_write_buf() unless they have a good reason to use these -+* -+***************************************************************************/ -+ -+static inline uint32_t smi_read_single_word(struct bcm2835_smi_instance *inst) -+{ -+ int timeout = 0; -+ -+ write_smi_reg(inst, SMIDCS_ENABLE, SMIDCS); -+ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_START, SMIDCS); -+ /* Make sure things happen in the right order...*/ -+ mb(); -+ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && -+ ++timeout < 10000) -+ ; -+ if (timeout < 10000) -+ return read_smi_reg(inst, SMIDD); -+ -+ dev_err(inst->dev, -+ "SMI direct read timed out (is the clock set up correctly?)"); -+ return 0; -+} -+ -+static inline void smi_write_single_word(struct bcm2835_smi_instance *inst, -+ uint32_t data) -+{ -+ int timeout = 0; -+ -+ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE, SMIDCS); -+ write_smi_reg(inst, data, SMIDD); -+ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE | SMIDCS_START, -+ SMIDCS); -+ -+ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && -+ ++timeout < 10000) -+ ; -+ if (timeout >= 10000) -+ dev_err(inst->dev, -+ "SMI direct write timed out (is the clock set up correctly?)"); -+} -+ -+/* Initiates a programmed read into the read FIFO. It is up to the caller to -+ * read data from the FIFO - either via paced DMA transfer, -+ * or polling SMICS_RXD to check whether data is available. -+ * SMICS_ACTIVE will go low upon completion. */ -+static void smi_init_programmed_read(struct bcm2835_smi_instance *inst, -+ int num_transfers) -+{ -+ int smics_temp; -+ -+ /* Disable the peripheral: */ -+ smics_temp = read_smi_reg(inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE); -+ write_smi_reg(inst, smics_temp, SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) -+ ; -+ -+ /* Program the transfer count: */ -+ write_smi_reg(inst, num_transfers, SMIL); -+ -+ /* re-enable and start: */ -+ smics_temp |= SMICS_ENABLE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ smics_temp |= SMICS_CLEAR; -+ /* Just to be certain: */ -+ mb(); -+ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) -+ ; -+ write_smi_reg(inst, smics_temp, SMICS); -+ smics_temp |= SMICS_START; -+ write_smi_reg(inst, smics_temp, SMICS); -+} -+ -+/* Initiates a programmed write sequence, using data from the write FIFO. -+ * It is up to the caller to initiate a DMA transfer before calling, -+ * or use another method to keep the write FIFO topped up. -+ * SMICS_ACTIVE will go low upon completion. -+ */ -+static void smi_init_programmed_write(struct bcm2835_smi_instance *inst, -+ int num_transfers) -+{ -+ int smics_temp; -+ -+ /* Disable the peripheral: */ -+ smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) -+ ; -+ -+ /* Program the transfer count: */ -+ write_smi_reg(inst, num_transfers, SMIL); -+ -+ /* setup, re-enable and start: */ -+ smics_temp |= SMICS_WRITE | SMICS_ENABLE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ smics_temp |= SMICS_START; -+ write_smi_reg(inst, smics_temp, SMICS); -+} -+ -+/* Initiate a read and then poll FIFO for data, reading out as it appears. */ -+static void smi_read_fifo(struct bcm2835_smi_instance *inst, -+ uint32_t *dest, int n_bytes) -+{ -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { -+ smi_dump_context_labelled(inst, -+ "WARNING: read FIFO not empty at start of read call."); -+ while (read_smi_reg(inst, SMICS)) -+ ; -+ } -+ -+ /* Dispatch the read: */ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_read(inst, n_bytes); -+ else if (inst->settings.data_width == SMI_WIDTH_16BIT) -+ smi_init_programmed_read(inst, n_bytes / 2); -+ else { -+ dev_err(inst->dev, "Unsupported data width for read."); -+ return; -+ } -+ -+ /* Poll FIFO to keep it empty */ -+ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) -+ *dest++ = read_smi_reg(inst, SMID); -+ -+ /* Ensure that the FIFO is emptied */ -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) { -+ int fifo_count; -+ -+ fifo_count = GET_BIT_FIELD(read_smi_reg(inst, SMIFD), -+ SMIFD_FCNT); -+ while (fifo_count--) -+ *dest++ = read_smi_reg(inst, SMID); -+ } -+ -+ if (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) -+ smi_dump_context_labelled(inst, -+ "WARNING: transaction finished but done bit not set."); -+ -+ if (read_smi_reg(inst, SMICS) & SMICS_RXD) -+ smi_dump_context_labelled(inst, -+ "WARNING: read FIFO not empty at end of read call."); -+ -+} -+ -+/* Initiate a write, and then keep the FIFO topped up. */ -+static void smi_write_fifo(struct bcm2835_smi_instance *inst, -+ uint32_t *src, int n_bytes) -+{ -+ int i, timeout = 0; -+ -+ /* Empty FIFOs if not already so */ -+ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) { -+ smi_dump_context_labelled(inst, -+ "WARNING: write fifo not empty at start of write call."); -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_CLEAR, -+ SMICS); -+ } -+ -+ /* Initiate the transfer */ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_write(inst, n_bytes); -+ else if (inst->settings.data_width == SMI_WIDTH_16BIT) -+ smi_init_programmed_write(inst, n_bytes / 2); -+ else { -+ dev_err(inst->dev, "Unsupported data width for write."); -+ return; -+ } -+ /* Fill the FIFO: */ -+ for (i = 0; i < (n_bytes - 1) / 4 + 1; ++i) { -+ while (!(read_smi_reg(inst, SMICS) & SMICS_TXD)) -+ ; -+ write_smi_reg(inst, *src++, SMID); -+ } -+ /* Busy wait... */ -+ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE) && ++timeout < -+ 1000000) -+ ; -+ if (timeout >= 1000000) -+ smi_dump_context_labelled(inst, -+ "Timed out on write operation!"); -+ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) -+ smi_dump_context_labelled(inst, -+ "WARNING: FIFO not empty at end of write operation."); -+} -+ -+/**************************************************************************** -+* -+* SMI DMA operations -+* -+***************************************************************************/ -+ -+/* Disable SMI and put it into the correct direction before doing DMA setup. -+ Stops spurious DREQs during setup. Peripheral is re-enabled by init_*() */ -+static void smi_disable(struct bcm2835_smi_instance *inst, -+ enum dma_transfer_direction direction) -+{ -+ int smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; -+ -+ if (direction == DMA_DEV_TO_MEM) -+ smics_temp &= ~SMICS_WRITE; -+ else -+ smics_temp |= SMICS_WRITE; -+ write_smi_reg(inst, smics_temp, SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) -+ ; -+} -+ -+static struct scatterlist *smi_scatterlist_from_buffer( -+ struct bcm2835_smi_instance *inst, -+ dma_addr_t buf, -+ size_t len, -+ struct scatterlist *sg) -+{ -+ sg_init_table(sg, 1); -+ sg_dma_address(sg) = buf; -+ sg_dma_len(sg) = len; -+ return sg; -+} -+ -+static void smi_dma_callback_user_copy(void *param) -+{ -+ /* Notify the bottom half that a chunk is ready for user copy */ -+ struct bcm2835_smi_instance *inst = -+ (struct bcm2835_smi_instance *)param; -+ -+ up(&inst->bounce.callback_sem); -+} -+ -+/* Creates a descriptor, assigns the given callback, and submits the -+ descriptor to dmaengine. Does not block - can queue up multiple -+ descriptors and then wait for them all to complete. -+ sg_len is the number of control blocks, NOT the number of bytes. -+ dir can be DMA_MEM_TO_DEV or DMA_DEV_TO_MEM. -+ callback can be NULL - in this case it is not called. */ -+static inline struct dma_async_tx_descriptor *smi_dma_submit_sgl( -+ struct bcm2835_smi_instance *inst, -+ struct scatterlist *sgl, -+ size_t sg_len, -+ enum dma_transfer_direction dir, -+ dma_async_tx_callback callback) -+{ -+ struct dma_async_tx_descriptor *desc; -+ -+ desc = dmaengine_prep_slave_sg(inst->dma_chan, -+ sgl, -+ sg_len, -+ dir, -+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK | -+ DMA_PREP_FENCE); -+ if (!desc) { -+ dev_err(inst->dev, "read_sgl: dma slave preparation failed!"); -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) & ~SMICS_ACTIVE, -+ SMICS); -+ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) -+ cpu_relax(); -+ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ACTIVE, -+ SMICS); -+ return NULL; -+ } -+ desc->callback = callback; -+ desc->callback_param = inst; -+ if (dmaengine_submit(desc) < 0) -+ return NULL; -+ return desc; -+} -+ -+/* NB this function blocks until the transfer is complete */ -+static void -+smi_dma_read_sgl(struct bcm2835_smi_instance *inst, -+ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) -+{ -+ struct dma_async_tx_descriptor *desc; -+ -+ /* Disable SMI and set to read before dispatching DMA - if SMI is in -+ * write mode and TX fifo is empty, it will generate a DREQ which may -+ * cause the read DMA to complete before the SMI read command is even -+ * dispatched! We want to dispatch DMA before SMI read so that reading -+ * is gapless, for logic analyser. -+ */ -+ -+ smi_disable(inst, DMA_DEV_TO_MEM); -+ -+ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL); -+ dma_async_issue_pending(inst->dma_chan); -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_read(inst, n_bytes); -+ else -+ smi_init_programmed_read(inst, n_bytes / 2); -+ -+ if (dma_wait_for_async_tx(desc) == DMA_ERROR) -+ smi_dump_context_labelled(inst, "DMA timeout!"); -+} -+ -+static void -+smi_dma_write_sgl(struct bcm2835_smi_instance *inst, -+ struct scatterlist *sgl, size_t sg_len, size_t n_bytes) -+{ -+ struct dma_async_tx_descriptor *desc; -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ smi_init_programmed_write(inst, n_bytes); -+ else -+ smi_init_programmed_write(inst, n_bytes / 2); -+ -+ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_MEM_TO_DEV, NULL); -+ dma_async_issue_pending(inst->dma_chan); -+ -+ if (dma_wait_for_async_tx(desc) == DMA_ERROR) -+ smi_dump_context_labelled(inst, "DMA timeout!"); -+ else -+ /* Wait for SMI to finish our writes */ -+ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) -+ cpu_relax(); -+} -+ -+ssize_t bcm2835_smi_user_dma( -+ struct bcm2835_smi_instance *inst, -+ enum dma_transfer_direction dma_dir, -+ char __user *user_ptr, size_t count, -+ struct bcm2835_smi_bounce_info **bounce) -+{ -+ int chunk_no = 0, chunk_size, count_left = count; -+ struct scatterlist *sgl; -+ void (*init_trans_func)(struct bcm2835_smi_instance *, int); -+ -+ spin_lock(&inst->transaction_lock); -+ -+ if (dma_dir == DMA_DEV_TO_MEM) -+ init_trans_func = smi_init_programmed_read; -+ else -+ init_trans_func = smi_init_programmed_write; -+ -+ smi_disable(inst, dma_dir); -+ -+ sema_init(&inst->bounce.callback_sem, 0); -+ if (bounce) -+ *bounce = &inst->bounce; -+ while (count_left) { -+ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? -+ DMA_BOUNCE_BUFFER_SIZE : count_left; -+ if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) { -+ sgl = -+ &inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; -+ } else { -+ sgl = smi_scatterlist_from_buffer( -+ inst, -+ inst->bounce.phys[ -+ chunk_no % DMA_BOUNCE_BUFFER_COUNT], -+ chunk_size, -+ &inst->buffer_sgl); -+ } -+ -+ if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir, -+ smi_dma_callback_user_copy -+ )) { -+ dev_err(inst->dev, "sgl submit failed"); -+ count = 0; -+ goto out; -+ } -+ count_left -= chunk_size; -+ chunk_no++; -+ } -+ dma_async_issue_pending(inst->dma_chan); -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) -+ init_trans_func(inst, count); -+ else if (inst->settings.data_width == SMI_WIDTH_16BIT) -+ init_trans_func(inst, count / 2); -+out: -+ spin_unlock(&inst->transaction_lock); -+ return count; -+} -+EXPORT_SYMBOL(bcm2835_smi_user_dma); -+ -+ -+/**************************************************************************** -+* -+* High level buffer transfer functions - for use by other drivers -+* -+***************************************************************************/ -+ -+/* Buffer must be physically contiguous - i.e. kmalloc, not vmalloc! */ -+void bcm2835_smi_write_buf( -+ struct bcm2835_smi_instance *inst, -+ const void *buf, size_t n_bytes) -+{ -+ int odd_bytes = n_bytes & 0x3; -+ -+ n_bytes -= odd_bytes; -+ -+ spin_lock(&inst->transaction_lock); -+ -+ if (n_bytes > DMA_THRESHOLD_BYTES) { -+ dma_addr_t phy_addr = dma_map_single( -+ inst->dev, -+ (void *)buf, -+ n_bytes, -+ DMA_MEM_TO_DEV); -+ struct scatterlist *sgl = -+ smi_scatterlist_from_buffer(inst, phy_addr, n_bytes, -+ &inst->buffer_sgl); -+ -+ if (!sgl) { -+ smi_dump_context_labelled(inst, -+ "Error: could not create scatterlist for write!"); -+ goto out; -+ } -+ smi_dma_write_sgl(inst, sgl, 1, n_bytes); -+ -+ dma_unmap_single -+ (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); -+ } else if (n_bytes) { -+ smi_write_fifo(inst, (uint32_t *) buf, n_bytes); -+ } -+ buf += n_bytes; -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) { -+ while (odd_bytes--) -+ smi_write_single_word(inst, *(uint8_t *) (buf++)); -+ } else { -+ while (odd_bytes >= 2) { -+ smi_write_single_word(inst, *(uint16_t *)buf); -+ buf += 2; -+ odd_bytes -= 2; -+ } -+ if (odd_bytes) { -+ /* Reading an odd number of bytes on a 16 bit bus is -+ a user bug. It's kinder to fail early and tell them -+ than to e.g. transparently give them the bottom byte -+ of a 16 bit transfer. */ -+ dev_err(inst->dev, -+ "WARNING: odd number of bytes specified for wide transfer."); -+ dev_err(inst->dev, -+ "At least one byte dropped as a result."); -+ dump_stack(); -+ } -+ } -+out: -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_write_buf); -+ -+void bcm2835_smi_read_buf(struct bcm2835_smi_instance *inst, -+ void *buf, size_t n_bytes) -+{ -+ -+ /* SMI is inherently 32-bit, which causes surprising amounts of mess -+ for bytes % 4 != 0. Easiest to avoid this mess altogether -+ by handling remainder separately. */ -+ int odd_bytes = n_bytes & 0x3; -+ -+ spin_lock(&inst->transaction_lock); -+ n_bytes -= odd_bytes; -+ if (n_bytes > DMA_THRESHOLD_BYTES) { -+ dma_addr_t phy_addr = dma_map_single(inst->dev, -+ buf, n_bytes, -+ DMA_DEV_TO_MEM); -+ struct scatterlist *sgl = smi_scatterlist_from_buffer( -+ inst, phy_addr, n_bytes, -+ &inst->buffer_sgl); -+ if (!sgl) { -+ smi_dump_context_labelled(inst, -+ "Error: could not create scatterlist for read!"); -+ goto out; -+ } -+ smi_dma_read_sgl(inst, sgl, 1, n_bytes); -+ dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); -+ } else if (n_bytes) { -+ smi_read_fifo(inst, (uint32_t *)buf, n_bytes); -+ } -+ buf += n_bytes; -+ -+ if (inst->settings.data_width == SMI_WIDTH_8BIT) { -+ while (odd_bytes--) -+ *((uint8_t *) (buf++)) = smi_read_single_word(inst); -+ } else { -+ while (odd_bytes >= 2) { -+ *(uint16_t *) buf = smi_read_single_word(inst); -+ buf += 2; -+ odd_bytes -= 2; -+ } -+ if (odd_bytes) { -+ dev_err(inst->dev, -+ "WARNING: odd number of bytes specified for wide transfer."); -+ dev_err(inst->dev, -+ "At least one byte dropped as a result."); -+ dump_stack(); -+ } -+ } -+out: -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_read_buf); -+ -+void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, -+ unsigned int address) -+{ -+ spin_lock(&inst->transaction_lock); -+ smi_set_address(inst, address); -+ spin_unlock(&inst->transaction_lock); -+} -+EXPORT_SYMBOL(bcm2835_smi_set_address); -+ -+struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node) -+{ -+ struct platform_device *pdev; -+ -+ if (!node) -+ return NULL; -+ -+ pdev = of_find_device_by_node(node); -+ if (!pdev) -+ return NULL; -+ -+ return platform_get_drvdata(pdev); -+} -+EXPORT_SYMBOL(bcm2835_smi_get); -+ -+/**************************************************************************** -+* -+* bcm2835_smi_probe - called when the driver is loaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_dma_setup(struct bcm2835_smi_instance *inst) -+{ -+ int i, rv = 0; -+ -+ inst->dma_chan = dma_request_slave_channel(inst->dev, "rx-tx"); -+ -+ inst->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ inst->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ inst->dma_config.src_addr = inst->smi_regs_busaddr + SMID; -+ inst->dma_config.dst_addr = inst->dma_config.src_addr; -+ /* Direction unimportant - always overridden by prep_slave_sg */ -+ inst->dma_config.direction = DMA_DEV_TO_MEM; -+ dmaengine_slave_config(inst->dma_chan, &inst->dma_config); -+ /* Alloc and map bounce buffers */ -+ for (i = 0; i < DMA_BOUNCE_BUFFER_COUNT; ++i) { -+ inst->bounce.buffer[i] = -+ dmam_alloc_coherent(inst->dev, DMA_BOUNCE_BUFFER_SIZE, -+ &inst->bounce.phys[i], -+ GFP_KERNEL); -+ if (!inst->bounce.buffer[i]) { -+ dev_err(inst->dev, "Could not allocate buffer!"); -+ rv = -ENOMEM; -+ break; -+ } -+ smi_scatterlist_from_buffer( -+ inst, -+ inst->bounce.phys[i], -+ DMA_BOUNCE_BUFFER_SIZE, -+ &inst->bounce.sgl[i] -+ ); -+ } -+ -+ return rv; -+} -+ -+static int bcm2835_smi_probe(struct platform_device *pdev) -+{ -+ int err; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct resource *ioresource; -+ struct bcm2835_smi_instance *inst; -+ -+ /* Allocate buffers and instance data */ -+ -+ inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance), -+ GFP_KERNEL); -+ -+ if (!inst) -+ return -ENOMEM; -+ -+ inst->dev = dev; -+ spin_lock_init(&inst->transaction_lock); -+ -+ /* We require device tree support */ -+ if (!node) -+ return -EINVAL; -+ -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource); -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource); -+ inst->smi_regs_busaddr = be32_to_cpu( -+ *of_get_address(node, 0, NULL, NULL)); -+ of_property_read_u32(node, -+ "brcm,smi-clock-source", -+ &inst->clock_source); -+ of_property_read_u32(node, -+ "brcm,smi-clock-divisor", -+ &inst->clock_divisor); -+ -+ err = bcm2835_smi_dma_setup(inst); -+ if (err) -+ return err; -+ -+ /* Finally, do peripheral setup */ -+ -+ smi_setup_clock(inst); -+ smi_setup_regs(inst); -+ -+ platform_set_drvdata(pdev, inst); -+ -+ dev_info(inst->dev, "initialised"); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* bcm2835_smi_remove - called when the driver is unloaded. -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev); -+ struct device *dev = inst->dev; -+ -+ dev_info(dev, "SMI device removed - OK"); -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_smi_of_match[] = { -+ {.compatible = "brcm,bcm2835-smi",}, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_smi_of_match); -+ -+static struct platform_driver bcm2835_smi_driver = { -+ .probe = bcm2835_smi_probe, -+ .remove = bcm2835_smi_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_smi_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_smi_driver); -+ -+MODULE_ALIAS("platform:smi-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Device driver for BCM2835's secondary memory interface"); -+MODULE_AUTHOR("Luke Wren "); -diff --git a/include/linux/broadcom/bcm2835_smi.h b/include/linux/broadcom/bcm2835_smi.h -new file mode 100644 -index 0000000..ee3a75e ---- /dev/null -+++ b/include/linux/broadcom/bcm2835_smi.h -@@ -0,0 +1,391 @@ -+/** -+ * Declarations and definitions for Broadcom's Secondary Memory Interface -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * Copyright (c) 2010-2012 Broadcom. All rights reserved. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+ -+#ifndef BCM2835_SMI_H -+#define BCM2835_SMI_H -+ -+#include -+ -+#ifndef __KERNEL__ -+#include -+#include +diff --git a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c +index 4b32941..0eb0f35 100644 +--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c +@@ -1187,7 +1187,9 @@ static void free_wrapper(struct gadget_wrapper *d) + /* should have been done already by driver model core */ + DWC_WARN("driver '%s' is still registered\n", + d->driver->driver.name); ++#ifdef CONFIG_USB_GADGET + usb_gadget_unregister_driver(d->driver); +#endif -+ -+#define BCM2835_SMI_IOC_MAGIC 0x1 -+#define BCM2835_SMI_INVALID_HANDLE (~0) -+ -+/* IOCTLs 0x100...0x1ff are not device-specific - we can use them */ -+#define BCM2835_SMI_IOC_GET_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 0) -+#define BCM2835_SMI_IOC_WRITE_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 1) -+#define BCM2835_SMI_IOC_ADDRESS _IO(BCM2835_SMI_IOC_MAGIC, 2) -+#define BCM2835_SMI_IOC_MAX 2 -+ -+#define SMI_WIDTH_8BIT 0 -+#define SMI_WIDTH_16BIT 1 -+#define SMI_WIDTH_9BIT 2 -+#define SMI_WIDTH_18BIT 3 -+ -+/* max number of bytes where DMA will not be used */ -+#define DMA_THRESHOLD_BYTES 128 -+#define DMA_BOUNCE_BUFFER_SIZE (1024 * 1024 / 2) -+#define DMA_BOUNCE_BUFFER_COUNT 3 -+ -+ -+struct smi_settings { -+ int data_width; -+ /* Whether or not to pack multiple SMI transfers into a -+ single 32 bit FIFO word */ -+ bool pack_data; -+ -+ /* Timing for reads (writes the same but for WE) -+ * -+ * OE ----------+ +-------------------- -+ * | | -+ * +----------+ -+ * SD -<==============================>----------- -+ * SA -<=========================================>- -+ * <-setup-> <-strobe -> <-hold -> <- pace -> -+ */ -+ -+ int read_setup_time; -+ int read_hold_time; -+ int read_pace_time; -+ int read_strobe_time; -+ -+ int write_setup_time; -+ int write_hold_time; -+ int write_pace_time; -+ int write_strobe_time; -+ -+ bool dma_enable; /* DREQs */ -+ bool dma_passthrough_enable; /* External DREQs */ -+ int dma_read_thresh; -+ int dma_write_thresh; -+ int dma_panic_read_thresh; -+ int dma_panic_write_thresh; -+}; -+ -+/**************************************************************************** -+* -+* Declare exported SMI functions -+* -+***************************************************************************/ -+ -+#ifdef __KERNEL__ -+ -+#include /* for enum dma_transfer_direction */ -+#include -+#include -+ -+struct bcm2835_smi_instance; -+ -+struct bcm2835_smi_bounce_info { -+ struct semaphore callback_sem; -+ void *buffer[DMA_BOUNCE_BUFFER_COUNT]; -+ dma_addr_t phys[DMA_BOUNCE_BUFFER_COUNT]; -+ struct scatterlist sgl[DMA_BOUNCE_BUFFER_COUNT]; -+}; -+ -+ -+void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *); -+ -+struct smi_settings *bcm2835_smi_get_settings_from_regs( -+ struct bcm2835_smi_instance *inst); -+ -+void bcm2835_smi_write_buf( -+ struct bcm2835_smi_instance *inst, -+ const void *buf, -+ size_t n_bytes); -+ -+void bcm2835_smi_read_buf( -+ struct bcm2835_smi_instance *inst, -+ void *buf, -+ size_t n_bytes); -+ -+void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, -+ unsigned int address); -+ -+ssize_t bcm2835_smi_user_dma( -+ struct bcm2835_smi_instance *inst, -+ enum dma_transfer_direction dma_dir, -+ char __user *user_ptr, -+ size_t count, -+ struct bcm2835_smi_bounce_info **bounce); -+ -+struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node); -+ -+#endif /* __KERNEL__ */ -+ -+/**************************************************************** -+* -+* Implementation-only declarations -+* -+****************************************************************/ -+ -+#ifdef BCM2835_SMI_IMPLEMENTATION -+ -+/* Clock manager registers for SMI clock: */ -+#define CM_SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x1010b0) -+/* Clock manager "password" to protect registers from spurious writes */ -+#define CM_PWD (0x5a << 24) -+ -+#define CM_SMI_CTL 0x00 -+#define CM_SMI_DIV 0x04 -+ -+#define CM_SMI_CTL_FLIP (1 << 8) -+#define CM_SMI_CTL_BUSY (1 << 7) -+#define CM_SMI_CTL_KILL (1 << 5) -+#define CM_SMI_CTL_ENAB (1 << 4) -+#define CM_SMI_CTL_SRC_MASK (0xf) -+#define CM_SMI_CTL_SRC_OFFS (0) -+ -+#define CM_SMI_DIV_DIVI_MASK (0xf << 12) -+#define CM_SMI_DIV_DIVI_OFFS (12) -+#define CM_SMI_DIV_DIVF_MASK (0xff << 4) -+#define CM_SMI_DIV_DIVF_OFFS (4) -+ -+/* SMI register mapping:*/ -+#define SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x600000) -+ -+#define SMICS 0x00 /* control + status register */ -+#define SMIL 0x04 /* length/count (n external txfers) */ -+#define SMIA 0x08 /* address register */ -+#define SMID 0x0c /* data register */ -+#define SMIDSR0 0x10 /* device 0 read settings */ -+#define SMIDSW0 0x14 /* device 0 write settings */ -+#define SMIDSR1 0x18 /* device 1 read settings */ -+#define SMIDSW1 0x1c /* device 1 write settings */ -+#define SMIDSR2 0x20 /* device 2 read settings */ -+#define SMIDSW2 0x24 /* device 2 write settings */ -+#define SMIDSR3 0x28 /* device 3 read settings */ -+#define SMIDSW3 0x2c /* device 3 write settings */ -+#define SMIDC 0x30 /* DMA control registers */ -+#define SMIDCS 0x34 /* direct control/status register */ -+#define SMIDA 0x38 /* direct address register */ -+#define SMIDD 0x3c /* direct data registers */ -+#define SMIFD 0x40 /* FIFO debug register */ -+ -+ -+ -+/* Control and Status register bits: -+ * SMICS_RXF : RX fifo full: 1 when RX fifo is full -+ * SMICS_TXE : TX fifo empty: 1 when empty. -+ * SMICS_RXD : RX fifo contains data: 1 when there is data. -+ * SMICS_TXD : TX fifo can accept data: 1 when true. -+ * SMICS_RXR : RX fifo needs reading: 1 when fifo more than 3/4 full, or -+ * when "DONE" and fifo not emptied. -+ * SMICS_TXW : TX fifo needs writing: 1 when less than 1/4 full. -+ * SMICS_AFERR : AXI FIFO error: 1 when fifo read when empty or written -+ * when full. Write 1 to clear. -+ * SMICS_EDREQ : 1 when external DREQ received. -+ * SMICS_PXLDAT : Pixel data: write 1 to enable pixel transfer modes. -+ * SMICS_SETERR : 1 if there was an error writing to setup regs (e.g. -+ * tx was in progress). Write 1 to clear. -+ * SMICS_PVMODE : Set to 1 to enable pixel valve mode. -+ * SMICS_INTR : Set to 1 to enable interrupt on RX. -+ * SMICS_INTT : Set to 1 to enable interrupt on TX. -+ * SMICS_INTD : Set to 1 to enable interrupt on DONE condition. -+ * SMICS_TEEN : Tear effect mode enabled: Programmed transfers will wait -+ * for a TE trigger before writing. -+ * SMICS_PAD1 : Padding settings for external transfers. For writes: the -+ * number of bytes initially written to the TX fifo that -+ * SMICS_PAD0 : should be ignored. For reads: the number of bytes that will -+ * be read before the data, and should be dropped. -+ * SMICS_WRITE : Transfer direction: 1 = write to external device, 0 = read -+ * SMICS_CLEAR : Write 1 to clear the FIFOs. -+ * SMICS_START : Write 1 to start the programmed transfer. -+ * SMICS_ACTIVE : Reads as 1 when a programmed transfer is underway. -+ * SMICS_DONE : Reads as 1 when transfer finished. For RX, not set until -+ * FIFO emptied. -+ * SMICS_ENABLE : Set to 1 to enable the SMI peripheral, 0 to disable. -+ */ -+ -+#define SMICS_RXF (1 << 31) -+#define SMICS_TXE (1 << 30) -+#define SMICS_RXD (1 << 29) -+#define SMICS_TXD (1 << 28) -+#define SMICS_RXR (1 << 27) -+#define SMICS_TXW (1 << 26) -+#define SMICS_AFERR (1 << 25) -+#define SMICS_EDREQ (1 << 15) -+#define SMICS_PXLDAT (1 << 14) -+#define SMICS_SETERR (1 << 13) -+#define SMICS_PVMODE (1 << 12) -+#define SMICS_INTR (1 << 11) -+#define SMICS_INTT (1 << 10) -+#define SMICS_INTD (1 << 9) -+#define SMICS_TEEN (1 << 8) -+#define SMICS_PAD1 (1 << 7) -+#define SMICS_PAD0 (1 << 6) -+#define SMICS_WRITE (1 << 5) -+#define SMICS_CLEAR (1 << 4) -+#define SMICS_START (1 << 3) -+#define SMICS_ACTIVE (1 << 2) -+#define SMICS_DONE (1 << 1) -+#define SMICS_ENABLE (1 << 0) -+ -+/* Address register bits: */ -+ -+#define SMIA_DEVICE_MASK ((1 << 9) | (1 << 8)) -+#define SMIA_DEVICE_OFFS (8) -+#define SMIA_ADDR_MASK (0x3f) /* bits 5 -> 0 */ -+#define SMIA_ADDR_OFFS (0) -+ -+/* DMA control register bits: -+ * SMIDC_DMAEN : DMA enable: set 1: DMA requests will be issued. -+ * SMIDC_DMAP : DMA passthrough: when set to 0, top two data pins are used by -+ * SMI as usual. When set to 1, the top two pins are used for -+ * external DREQs: pin 16 read request, 17 write. -+ * SMIDC_PANIC* : Threshold at which DMA will panic during read/write. -+ * SMIDC_REQ* : Threshold at which DMA will generate a DREQ. -+ */ -+ -+#define SMIDC_DMAEN (1 << 28) -+#define SMIDC_DMAP (1 << 24) -+#define SMIDC_PANICR_MASK (0x3f << 18) -+#define SMIDC_PANICR_OFFS (18) -+#define SMIDC_PANICW_MASK (0x3f << 12) -+#define SMIDC_PANICW_OFFS (12) -+#define SMIDC_REQR_MASK (0x3f << 6) -+#define SMIDC_REQR_OFFS (6) -+#define SMIDC_REQW_MASK (0x3f) -+#define SMIDC_REQW_OFFS (0) -+ -+/* Device settings register bits: same for all 4 (or 3?) device register sets. -+ * Device read settings: -+ * SMIDSR_RWIDTH : Read transfer width. 00 = 8bit, 01 = 16bit, -+ * 10 = 18bit, 11 = 9bit. -+ * SMIDSR_RSETUP : Read setup time: number of core cycles between chip -+ * select/address and read strobe. Min 1, max 64. -+ * SMIDSR_MODE68 : 1 for System 68 mode (i.e. enable + direction pins, -+ * rather than OE + WE pin) -+ * SMIDSR_FSETUP : If set to 1, setup time only applies to first -+ * transfer after address change. -+ * SMIDSR_RHOLD : Number of core cycles between read strobe going -+ * inactive and CS/address going inactive. Min 1, max 64 -+ * SMIDSR_RPACEALL : When set to 1, this device's RPACE value will always -+ * be used for the next transaction, even if it is not -+ * to this device. -+ * SMIDSR_RPACE : Number of core cycles spent waiting between CS -+ * deassert and start of next transfer. Min 1, max 128 -+ * SMIDSR_RDREQ : 1 = use external DMA request on SD16 to pace reads -+ * from device. Must also set DMAP in SMICS. -+ * SMIDSR_RSTROBE : Number of cycles to assert the read strobe. -+ * min 1, max 128. -+ */ -+#define SMIDSR_RWIDTH_MASK ((1<<31)|(1<<30)) -+#define SMIDSR_RWIDTH_OFFS (30) -+#define SMIDSR_RSETUP_MASK (0x3f << 24) -+#define SMIDSR_RSETUP_OFFS (24) -+#define SMIDSR_MODE68 (1 << 23) -+#define SMIDSR_FSETUP (1 << 22) -+#define SMIDSR_RHOLD_MASK (0x3f << 16) -+#define SMIDSR_RHOLD_OFFS (16) -+#define SMIDSR_RPACEALL (1 << 15) -+#define SMIDSR_RPACE_MASK (0x7f << 8) -+#define SMIDSR_RPACE_OFFS (8) -+#define SMIDSR_RDREQ (1 << 7) -+#define SMIDSR_RSTROBE_MASK (0x7f) -+#define SMIDSR_RSTROBE_OFFS (0) -+ -+/* Device write settings: -+ * SMIDSW_WWIDTH : Write transfer width. 00 = 8bit, 01 = 16bit, -+ * 10= 18bit, 11 = 9bit. -+ * SMIDSW_WSETUP : Number of cycles between CS assert and write strobe. -+ * Min 1, max 64. -+ * SMIDSW_WFORMAT : Pixel format of input. 0 = 16bit RGB 565, -+ * 1 = 32bit RGBA 8888 -+ * SMIDSW_WSWAP : 1 = swap pixel data bits. (Use with SMICS_PXLDAT) -+ * SMIDSW_WHOLD : Time between WE deassert and CS deassert. 1 to 64 -+ * SMIDSW_WPACEALL : 1: this device's WPACE will be used for the next -+ * transfer, regardless of that transfer's device. -+ * SMIDSW_WPACE : Cycles between CS deassert and next CS assert. -+ * Min 1, max 128 -+ * SMIDSW_WDREQ : Use external DREQ on pin 17 to pace writes. DMAP must -+ * be set in SMICS. -+ * SMIDSW_WSTROBE : Number of cycles to assert the write strobe. -+ * Min 1, max 128 -+ */ -+#define SMIDSW_WWIDTH_MASK ((1<<31)|(1<<30)) -+#define SMIDSW_WWIDTH_OFFS (30) -+#define SMIDSW_WSETUP_MASK (0x3f << 24) -+#define SMIDSW_WSETUP_OFFS (24) -+#define SMIDSW_WFORMAT (1 << 23) -+#define SMIDSW_WSWAP (1 << 22) -+#define SMIDSW_WHOLD_MASK (0x3f << 16) -+#define SMIDSW_WHOLD_OFFS (16) -+#define SMIDSW_WPACEALL (1 << 15) -+#define SMIDSW_WPACE_MASK (0x7f << 8) -+#define SMIDSW_WPACE_OFFS (8) -+#define SMIDSW_WDREQ (1 << 7) -+#define SMIDSW_WSTROBE_MASK (0x7f) -+#define SMIDSW_WSTROBE_OFFS (0) -+ -+/* Direct transfer control + status register -+ * SMIDCS_WRITE : Direction of transfer: 1 -> write, 0 -> read -+ * SMIDCS_DONE : 1 when a transfer has finished. Write 1 to clear. -+ * SMIDCS_START : Write 1 to start a transfer, if one is not already underway. -+ * SMIDCE_ENABLE: Write 1 to enable SMI in direct mode. -+ */ -+ -+#define SMIDCS_WRITE (1 << 3) -+#define SMIDCS_DONE (1 << 2) -+#define SMIDCS_START (1 << 1) -+#define SMIDCS_ENABLE (1 << 0) -+ -+/* Direct transfer address register -+ * SMIDA_DEVICE : Indicates which of the device settings banks should be used. -+ * SMIDA_ADDR : The value to be asserted on the address pins. -+ */ -+ -+#define SMIDA_DEVICE_MASK ((1<<9)|(1<<8)) -+#define SMIDA_DEVICE_OFFS (8) -+#define SMIDA_ADDR_MASK (0x3f) -+#define SMIDA_ADDR_OFFS (0) -+ -+/* FIFO debug register -+ * SMIFD_FLVL : The high-tide mark of FIFO count during the most recent txfer -+ * SMIFD_FCNT : The current FIFO count. -+ */ -+#define SMIFD_FLVL_MASK (0x3f << 8) -+#define SMIFD_FLVL_OFFS (8) -+#define SMIFD_FCNT_MASK (0x3f) -+#define SMIFD_FCNT_OFFS (0) -+ -+#endif /* BCM2835_SMI_IMPLEMENTATION */ -+ -+#endif /* BCM2835_SMI_H */ - -From f657d984e244c7348152e2edc09cd5decb2f5b55 Mon Sep 17 00:00:00 2001 -From: Luke Wren -Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 183/204] Add SMI NAND driver - -Signed-off-by: Luke Wren ---- - .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++ - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 ++++++ - arch/arm/configs/bcm2709_defconfig | 7 + - arch/arm/configs/bcmrpi_defconfig | 7 + - drivers/mtd/nand/Kconfig | 7 + - drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++ - 8 files changed, 402 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt - create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts - create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c - -diff --git a/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt -new file mode 100644 -index 0000000..159544d ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt -@@ -0,0 +1,42 @@ -+* BCM2835 SMI NAND flash -+ -+This driver is a shim between the BCM2835 SMI driver (SMI is a peripheral for -+talking to parallel register interfaces) and Linux's MTD layer. -+ -+Required properties: -+- compatible: "brcm,bcm2835-smi-nand" -+- status: "okay" -+ -+Optional properties: -+- partition@n, where n is an integer from a consecutive sequence starting at 0 -+ - Difficult to store partition table on NAND device - normally put it -+ in the source code, kernel bootparams, or device tree (the best way!) -+ - Sub-properties: -+ - label: the partition name, as shown by mtdinfo /dev/mtd* -+ - reg: the size and offset of this partition. -+ - (optional) read-only: an empty property flagging as read only -+ -+Example: -+ -+nand: flash@0 { -+ compatible = "brcm,bcm2835-smi-nand"; -+ status = "okay"; -+ -+ partition@0 { -+ label = "stage2"; -+ // 128k -+ reg = <0 0x20000>; -+ read-only; -+ }; -+ partition@1 { -+ label = "firmware"; -+ // 16M -+ reg = <0x20000 0x1000000>; -+ read-only; -+ }; -+ partition@2 { -+ label = "root"; -+ // 2G -+ reg = <0x1020000 0x80000000>; -+ }; -+}; -\ No newline at end of file -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index f8f2c034..dfd23a1 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -15,6 +15,7 @@ endif - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/smi-nand-overlay.dts b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts -new file mode 100644 -index 0000000..13ce0b7 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts -@@ -0,0 +1,69 @@ -+// Description: Overlay to enable NAND flash through -+// the secondary memory interface -+// Author: Luke Wren -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&smi>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&smi_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ nand: flash@0 { -+ compatible = "brcm,bcm2835-smi-nand"; -+ smi_handle = <&smi>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ status = "okay"; -+ -+ partition@0 { -+ label = "stage2"; -+ // 128k -+ reg = <0 0x20000>; -+ read-only; -+ }; -+ partition@1 { -+ label = "firmware"; -+ // 16M -+ reg = <0x20000 0x1000000>; -+ read-only; -+ }; -+ partition@2 { -+ label = "root"; -+ // 2G (will need to use 64 bit for >=4G) -+ reg = <0x1020000 0x80000000>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ smi_pins: smi_pins { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15>; -+ /* Alt 1: SMI */ -+ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 -+ 5 5 5 5 5>; -+ /* /CS, /WE and /OE are pulled high, as they are -+ generally active low signals */ -+ brcm,pull = <2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 16a8354..c7671bf 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -392,6 +392,10 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_UBI=m - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1142,6 +1146,9 @@ CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m - CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 7dd4fd4..75fa1d0 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -385,6 +385,10 @@ CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - CONFIG_DMA_CMA=y - CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_UBI=m - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1135,6 +1139,9 @@ CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m - CONFIG_SQUASHFS=m - CONFIG_SQUASHFS_XATTR=y - CONFIG_SQUASHFS_LZO=y -diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 5897d8d..82c4b4b 100644 ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -41,6 +41,13 @@ config MTD_SM_COMMON - tristate - default n - -+config MTD_NAND_BCM2835_SMI -+ tristate "Use Broadcom's Secondary Memory Interface as a NAND controller (BCM283x)" -+ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI && MTD_NAND -+ default m -+ help -+ Uses the BCM2835's SMI peripheral as a NAND controller. -+ - config MTD_NAND_DENALI - tristate "Support Denali NAND controller" - depends on HAS_DMA -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 582bbd05..f1393b0 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o - obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o - obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o - obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o -+obj-$(CONFIG_MTD_NAND_BCM2835_SMI) += bcm2835_smi_nand.o - obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o - obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o - obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o -diff --git a/drivers/mtd/nand/bcm2835_smi_nand.c b/drivers/mtd/nand/bcm2835_smi_nand.c -new file mode 100644 -index 0000000..b747326 ---- /dev/null -+++ b/drivers/mtd/nand/bcm2835_smi_nand.c -@@ -0,0 +1,268 @@ -+/** -+ * NAND flash driver for Broadcom Secondary Memory Interface -+ * -+ * Written by Luke Wren -+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. -+ * -+ * 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, -+ * without modification. -+ * 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. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DEVICE_NAME "bcm2835-smi-nand" -+#define DRIVER_NAME "smi-nand-bcm2835" -+ -+struct bcm2835_smi_nand_host { -+ struct bcm2835_smi_instance *smi_inst; -+ struct nand_chip nand_chip; -+ struct mtd_info mtd; -+ struct device *dev; -+}; -+ -+/**************************************************************************** -+* -+* NAND functionality implementation -+* -+****************************************************************************/ -+ -+#define SMI_NAND_CLE_PIN 0x01 -+#define SMI_NAND_ALE_PIN 0x02 -+ -+static inline void bcm2835_smi_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ uint32_t cmd32 = cmd; -+ uint32_t addr = ~(SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ if (ctrl & NAND_CLE) -+ addr |= SMI_NAND_CLE_PIN; -+ if (ctrl & NAND_ALE) -+ addr |= SMI_NAND_ALE_PIN; -+ /* Lower ALL the CS pins! */ -+ if (ctrl & NAND_NCE) -+ addr &= (SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN); -+ -+ bcm2835_smi_set_address(inst, addr); -+ -+ if (cmd != NAND_CMD_NONE) -+ bcm2835_smi_write_buf(inst, &cmd32, 1); -+} -+ -+static inline uint8_t bcm2835_smi_nand_read_byte(struct mtd_info *mtd) -+{ -+ uint8_t byte; -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_read_buf(inst, &byte, 1); -+ return byte; -+} -+ -+static inline void bcm2835_smi_nand_write_byte(struct mtd_info *mtd, -+ uint8_t byte) -+{ -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_write_buf(inst, &byte, 1); -+} -+ -+static inline void bcm2835_smi_nand_write_buf(struct mtd_info *mtd, -+ const uint8_t *buf, int len) -+{ -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_write_buf(inst, buf, len); -+} -+ -+static inline void bcm2835_smi_nand_read_buf(struct mtd_info *mtd, -+ uint8_t *buf, int len) -+{ -+ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent); -+ struct bcm2835_smi_instance *inst = host->smi_inst; -+ -+ bcm2835_smi_read_buf(inst, buf, len); -+} -+ -+/**************************************************************************** -+* -+* Probe and remove functions -+* -+***************************************************************************/ -+ -+static int bcm2835_smi_nand_probe(struct platform_device *pdev) -+{ -+ struct bcm2835_smi_nand_host *host; -+ struct nand_chip *this; -+ struct mtd_info *mtd; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node, *smi_node; -+ struct mtd_part_parser_data ppdata; -+ struct smi_settings *smi_settings; -+ struct bcm2835_smi_instance *smi_inst; -+ int ret = -ENXIO; -+ -+ if (!node) { -+ dev_err(dev, "No device tree node supplied!"); -+ return -EINVAL; -+ } -+ -+ smi_node = of_parse_phandle(node, "smi_handle", 0); -+ -+ /* Request use of SMI peripheral: */ -+ smi_inst = bcm2835_smi_get(smi_node); -+ -+ if (!smi_inst) { -+ dev_err(dev, "Could not register with SMI."); -+ return -EPROBE_DEFER; -+ } -+ -+ /* Set SMI timing and bus width */ -+ -+ smi_settings = bcm2835_smi_get_settings_from_regs(smi_inst); -+ -+ smi_settings->data_width = SMI_WIDTH_8BIT; -+ smi_settings->read_setup_time = 2; -+ smi_settings->read_hold_time = 1; -+ smi_settings->read_pace_time = 1; -+ smi_settings->read_strobe_time = 3; -+ -+ smi_settings->write_setup_time = 2; -+ smi_settings->write_hold_time = 1; -+ smi_settings->write_pace_time = 1; -+ smi_settings->write_strobe_time = 3; -+ -+ bcm2835_smi_set_regs_from_settings(smi_inst); -+ -+ host = devm_kzalloc(dev, sizeof(struct bcm2835_smi_nand_host), -+ GFP_KERNEL); -+ if (!host) -+ return -ENOMEM; -+ -+ host->dev = dev; -+ host->smi_inst = smi_inst; -+ -+ platform_set_drvdata(pdev, host); -+ -+ /* Link the structures together */ -+ -+ this = &host->nand_chip; -+ mtd = &host->mtd; -+ mtd->priv = this; -+ mtd->owner = THIS_MODULE; -+ mtd->dev.parent = dev; -+ mtd->name = DRIVER_NAME; -+ ppdata.of_node = node; -+ -+ /* 20 us command delay time... */ -+ this->chip_delay = 20; -+ -+ this->priv = host; -+ this->cmd_ctrl = bcm2835_smi_nand_cmd_ctrl; -+ this->read_byte = bcm2835_smi_nand_read_byte; -+ this->write_byte = bcm2835_smi_nand_write_byte; -+ this->write_buf = bcm2835_smi_nand_write_buf; -+ this->read_buf = bcm2835_smi_nand_read_buf; -+ -+ this->ecc.mode = NAND_ECC_SOFT; -+ -+ /* Should never be accessed directly: */ -+ -+ this->IO_ADDR_R = (void *)0xdeadbeef; -+ this->IO_ADDR_W = (void *)0xdeadbeef; -+ -+ /* First scan to find the device and get the page size */ -+ -+ if (nand_scan_ident(mtd, 1, NULL)) -+ return -ENXIO; -+ -+ /* Second phase scan */ -+ -+ if (nand_scan_tail(mtd)) -+ return -ENXIO; -+ -+ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); -+ if (!ret) -+ return 0; -+ -+ nand_release(mtd); -+ return -EINVAL; -+} -+ -+static int bcm2835_smi_nand_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_smi_nand_host *host = platform_get_drvdata(pdev); -+ -+ nand_release(&host->mtd); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* Register the driver with device tree -+* -+***************************************************************************/ -+ -+static const struct of_device_id bcm2835_smi_nand_of_match[] = { -+ {.compatible = "brcm,bcm2835-smi-nand",}, -+ { /* sentinel */ } -+}; -+ -+MODULE_DEVICE_TABLE(of, bcm2835_smi_nand_of_match); -+ -+static struct platform_driver bcm2835_smi_nand_driver = { -+ .probe = bcm2835_smi_nand_probe, -+ .remove = bcm2835_smi_nand_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_smi_nand_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2835_smi_nand_driver); -+ -+MODULE_ALIAS("platform:smi-nand-bcm2835"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION -+ ("Driver for NAND chips using Broadcom Secondary Memory Interface"); -+MODULE_AUTHOR("Luke Wren "); - -From a3bf36473505511198d71fdf19e6b28b4ee55195 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 16 Sep 2015 17:28:41 +0100 -Subject: [PATCH 184/204] BCM270X_DT: Document SMI overlay - ---- - arch/arm/boot/dts/overlays/Makefile | 6 +++--- - arch/arm/boot/dts/overlays/README | 18 ++++++++++++++++++ - 2 files changed, 21 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index dfd23a1..192bda7 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,9 +13,6 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -@@ -48,6 +45,9 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0aa5aa1..4ab4c695 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -530,6 +530,24 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - debug Enable debug output (default off) - - -+Name: smi -+Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! -+Load: dtoverlay=smi -+Params: -+ -+ -+Name: smi-dev -+Info: Enables the userspace interface for the SMI driver -+Load: dtoverlay=smi-dev -+Params: -+ -+ -+Name: smi-nand -+Info: Enables access to NAND flash via the SMI interface -+Load: dtoverlay=smi-nand -+Params: -+ -+ - Name: spi-bcm2708 - Info: Selects the bcm2708-spi SPI driver - Load: dtoverlay=spi-bcm2708 - -From 24a9683edd38171e27a170b95a42133c2bd3890f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Sep 2015 17:13:42 +0100 -Subject: [PATCH 185/204] dwc_otg: Force host mode to fix incorrect compute - module boards - ---- - drivers/usb/host/dwc_otg/dwc_otg_cil.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c -index e40060f..beaa8b3 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_cil.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c -@@ -192,7 +192,7 @@ dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr) - core_if->hptxfsiz.d32 = - DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); - gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); -- gusbcfg.b.force_host_mode = 0; -+ gusbcfg.b.force_host_mode = 1; - DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); - dwc_mdelay(100); } + + device_unregister(&d->gadget.dev); +@@ -1275,86 +1277,4 @@ void pcd_remove(dwc_bus_dev_t *_dev) + otg_dev->pcd = 0; + } + +-/** +- * This function registers a gadget driver with the PCD. +- * +- * When a driver is successfully registered, it will receive control +- * requests including set_configuration(), which enables non-control +- * requests. then usb traffic follows until a disconnect is reported. +- * then a host may connect again, or the driver might get unbound. +- * +- * @param driver The driver being registered +- * @param bind The bind function of gadget driver +- */ +- +-int usb_gadget_probe_driver(struct usb_gadget_driver *driver) +-{ +- int retval; +- +- DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", +- driver->driver.name); +- +- if (!driver || driver->max_speed == USB_SPEED_UNKNOWN || +- !driver->bind || +- !driver->unbind || !driver->disconnect || !driver->setup) { +- DWC_DEBUGPL(DBG_PCDV, "EINVAL\n"); +- return -EINVAL; +- } +- if (gadget_wrapper == 0) { +- DWC_DEBUGPL(DBG_PCDV, "ENODEV\n"); +- return -ENODEV; +- } +- if (gadget_wrapper->driver != 0) { +- DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver); +- return -EBUSY; +- } +- +- /* hook up the driver */ +- gadget_wrapper->driver = driver; +- gadget_wrapper->gadget.dev.driver = &driver->driver; +- +- DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name); +- retval = driver->bind(&gadget_wrapper->gadget, gadget_wrapper->driver); +- if (retval) { +- DWC_ERROR("bind to driver %s --> error %d\n", +- driver->driver.name, retval); +- gadget_wrapper->driver = 0; +- gadget_wrapper->gadget.dev.driver = 0; +- return retval; +- } +- DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n", +- driver->driver.name); +- return 0; +-} +-EXPORT_SYMBOL(usb_gadget_probe_driver); +- +-/** +- * This function unregisters a gadget driver +- * +- * @param driver The driver being unregistered +- */ +-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +-{ +- //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); +- +- if (gadget_wrapper == 0) { +- DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__, +- -ENODEV); +- return -ENODEV; +- } +- if (driver == 0 || driver != gadget_wrapper->driver) { +- DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__, +- -EINVAL); +- return -EINVAL; +- } +- +- driver->unbind(&gadget_wrapper->gadget); +- gadget_wrapper->driver = 0; +- +- DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name); +- return 0; +-} +- +-EXPORT_SYMBOL(usb_gadget_unregister_driver); +- + #endif /* DWC_HOST_ONLY */ -From 4f8563760264a9aedad6fec09e8adb8c3929c1a3 Mon Sep 17 00:00:00 2001 +From 0ae54a1f7e53f7f8b7e491ca96295c7d14e6d89c Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Tue, 15 Sep 2015 15:16:24 +0100 -Subject: [PATCH 186/204] config: Add CIFS_DFS_UPCALL, CIFS_ACL, CIFS_SMB2, - CIFS_FSCACHE +Date: Wed, 21 Oct 2015 23:36:07 +0100 +Subject: [PATCH 101/113] config: remove CONFIG_CPU_SW_DOMAIN_PAN it causes + panics --- - arch/arm/configs/bcm2709_defconfig | 4 ++++ - arch/arm/configs/bcmrpi_defconfig | 4 ++++ - 2 files changed, 8 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index c7671bf..60f8357 100644 +index 66a1c1399..b87e731 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -1167,6 +1167,10 @@ CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_SMB2=y -+CONFIG_CIFS_FSCACHE=y - CONFIG_9P_FS=m - CONFIG_9P_FS_POSIX_ACL=y - CONFIG_NLS_DEFAULT="utf8" +@@ -47,6 +47,7 @@ CONFIG_VMSPLIT_2G=y + CONFIG_PREEMPT=y + CONFIG_AEABI=y + CONFIG_OABI_COMPAT=y ++# CONFIG_CPU_SW_DOMAIN_PAN is not set + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y + CONFIG_CMA=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 75fa1d0..8ebc8d5 100644 +index 3e1ac5a..64a169d 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1160,6 +1160,10 @@ CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_SMB2=y -+CONFIG_CIFS_FSCACHE=y - CONFIG_9P_FS=m - CONFIG_9P_FS_POSIX_ACL=y - CONFIG_NLS_DEFAULT="utf8" +@@ -42,6 +42,7 @@ CONFIG_BCM2708_DT=y + CONFIG_PREEMPT=y + CONFIG_AEABI=y + CONFIG_OABI_COMPAT=y ++# CONFIG_CPU_SW_DOMAIN_PAN is not set + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y + CONFIG_CMA=y -From dee40d2ad759e6f0d9737f15c9c00a9149d55b73 Mon Sep 17 00:00:00 2001 -From: David Lechner -Date: Mon, 14 Sep 2015 19:08:36 -0500 -Subject: [PATCH 187/204] Use dts-dirs feature for overlays. - -The kernel makefiles have a dts-dirs target that is for vendor subdirectories. - -Using this fixes the install_dtbs target, which previously did not install the overlays. ---- - arch/arm/boot/dts/Makefile | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 12de305..faf293f 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -15,6 +15,9 @@ endif - ifeq ($(CONFIG_ARCH_BCM2835),y) - RPI_DT_OVERLAYS=y - endif -+ifeq ($(RPI_DT_OVERLAYS),y) -+ dts-dirs += overlays -+endif - - dtb-$(CONFIG_ARCH_ALPINE) += \ - alpine-db.dtb -@@ -683,11 +686,10 @@ targets += $(dtb-y) - endif - - always := $(dtb-y) -+subdir-y := $(dts-dirs) - clean-files := *.dtb - - # Enable fixups to support overlays on BCM2708 platforms - ifeq ($(RPI_DT_OVERLAYS),y) - DTC_FLAGS ?= -@ - endif -- --subdir-y += overlays - -From 51ccad4fd102f2eb4d2a8115ff2a06ec01676acd Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 10 Sep 2015 09:32:14 +0000 -Subject: [PATCH 192/204] backport: spi: bcm2835: BUG: fix wrong use of - PAGE_MASK - -There is a bug in the alignment checking of transfers, -that results in DMA not being used for un-aligned -transfers that do not cross page-boundries, which is valid. - -This is due to a missconception of the meaning PAGE_MASK -when implementing that check originally - (PAGE_SIZE - 1) -should have been used instead. - -Also fixes a copy/paste error. - -Reported-by: -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown -Cc: stable@vger.kernel.org ---- - drivers/spi/spi-bcm2835.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index b68991c..3835332 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, - /* otherwise we only allow transfers within the same page - * to avoid wasting time on dma_mapping when it is not practical - */ -- if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { -+ if (((size_t)tfr->tx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); - return false; - } -- if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { -+ if (((size_t)tfr->rx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) { - dev_warn_once(&spi->dev, -- "Unaligned spi tx-transfer bridging page\n"); -+ "Unaligned spi rx-transfer bridging page\n"); - return false; - } - - -From 16e92c1ffaf2b25fc3b410ba8e1dc6a457b645f7 Mon Sep 17 00:00:00 2001 -From: Stuart MacLean -Date: Fri, 2 Oct 2015 15:12:59 +0100 -Subject: [PATCH 193/204] Add support for the HiFiBerry DAC+ Pro. - -The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. - -An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. ---- - .../dts/overlays/hifiberry-dacplus-overlay.dts | 15 +- - drivers/clk/Makefile | 1 + - drivers/clk/clk-hifiberry-dacpro.c | 160 ++++++++++++++ - sound/soc/bcm/hifiberry_dacplus.c | 244 +++++++++++++++++++-- - sound/soc/codecs/pcm512x.c | 3 +- - 5 files changed, 396 insertions(+), 27 deletions(-) - create mode 100644 drivers/clk/clk-hifiberry-dacpro.c - -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -index deb9c625..f923a48 100644 ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -6,6 +6,16 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -+ target-path = "/clocks"; -+ __overlay__ { -+ dacpro_osc: dacpro_osc { -+ compatible = "hifiberry,dacpro-clk"; -+ #clock-cells = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { - target = <&sound>; - __overlay__ { - compatible = "hifiberry,hifiberry-dacplus"; -@@ -14,14 +24,14 @@ - }; - }; - -- fragment@1 { -+ fragment@2 { - target = <&i2s>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -32,6 +42,7 @@ - #sound-dai-cells = <0>; - compatible = "ti,pcm5122"; - reg = <0x4d>; -+ clocks = <&dacpro_osc>; - status = "okay"; - }; - }; -diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index 3d00c25..f949266 100644 ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o - obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o - obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o - obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o - obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o - obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o - obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o -diff --git a/drivers/clk/clk-hifiberry-dacpro.c b/drivers/clk/clk-hifiberry-dacpro.c -new file mode 100644 -index 0000000..3e35d45 ---- /dev/null -+++ b/drivers/clk/clk-hifiberry-dacpro.c -@@ -0,0 +1,160 @@ -+/* -+ * Clock Driver for HiFiBerry DAC Pro -+ * -+ * Author: Stuart MacLean -+ * Copyright 2015 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+/** -+ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro -+ * @hw: clk_hw for the common clk framework -+ * @mode: 0 => CLK44EN, 1 => CLK48EN -+ */ -+struct clk_hifiberry_hw { -+ struct clk_hw hw; -+ uint8_t mode; -+}; -+ -+#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) -+ -+static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { -+ { .compatible = "hifiberry,dacpro-clk",}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); -+ -+static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : -+ CLK_48EN_RATE; -+} -+ -+static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long *parent_rate) -+{ -+ long actual_rate; -+ -+ if (rate <= CLK_44EN_RATE) { -+ actual_rate = (long)CLK_44EN_RATE; -+ } else if (rate >= CLK_48EN_RATE) { -+ actual_rate = (long)CLK_48EN_RATE; -+ } else { -+ long diff44Rate = (long)(rate - CLK_44EN_RATE); -+ long diff48Rate = (long)(CLK_48EN_RATE - rate); -+ -+ if (diff44Rate < diff48Rate) -+ actual_rate = (long)CLK_44EN_RATE; -+ else -+ actual_rate = (long)CLK_48EN_RATE; -+ } -+ return actual_rate; -+} -+ -+ -+static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ unsigned long actual_rate; -+ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); -+ -+ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, -+ &parent_rate); -+ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; -+ return 0; -+} -+ -+ -+const struct clk_ops clk_hifiberry_dacpro_rate_ops = { -+ .recalc_rate = clk_hifiberry_dacpro_recalc_rate, -+ .round_rate = clk_hifiberry_dacpro_round_rate, -+ .set_rate = clk_hifiberry_dacpro_set_rate, -+}; -+ -+static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct clk_hifiberry_hw *proclk; -+ struct clk *clk; -+ struct device *dev; -+ struct clk_init_data init; -+ -+ dev = &pdev->dev; -+ -+ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); -+ if (!proclk) -+ return -ENOMEM; -+ -+ init.name = "clk-hifiberry-dacpro"; -+ init.ops = &clk_hifiberry_dacpro_rate_ops; -+ init.flags = CLK_IS_ROOT | CLK_IS_BASIC; -+ init.parent_names = NULL; -+ init.num_parents = 0; -+ -+ proclk->mode = 0; -+ proclk->hw.init = &init; -+ -+ clk = devm_clk_register(dev, &proclk->hw); -+ if (!IS_ERR(clk)) { -+ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, -+ clk); -+ } else { -+ dev_err(dev, "Fail to register clock driver\n"); -+ kfree(proclk); -+ ret = PTR_ERR(clk); -+ } -+ return ret; -+} -+ -+static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) -+{ -+ of_clk_del_provider(pdev->dev.of_node); -+ return 0; -+} -+ -+static struct platform_driver clk_hifiberry_dacpro_driver = { -+ .probe = clk_hifiberry_dacpro_probe, -+ .remove = clk_hifiberry_dacpro_remove, -+ .driver = { -+ .name = "clk-hifiberry-dacpro", -+ .of_match_table = clk_hifiberry_dacpro_dt_ids, -+ }, -+}; -+ -+static int __init clk_hifiberry_dacpro_init(void) -+{ -+ return platform_driver_register(&clk_hifiberry_dacpro_driver); -+} -+core_initcall(clk_hifiberry_dacpro_init); -+ -+static void __exit clk_hifiberry_dacpro_exit(void) -+{ -+ platform_driver_unregister(&clk_hifiberry_dacpro_driver); -+} -+module_exit(clk_hifiberry_dacpro_exit); -+ -+MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:clk-hifiberry-dacpro"); -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index 11e4f39..a6b651c 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -1,8 +1,8 @@ - /* -- * ASoC Driver for HiFiBerry DAC+ -+ * ASoC Driver for HiFiBerry DAC+ / DAC Pro - * -- * Author: Daniel Matuschek -- * Copyright 2014 -+ * Author: Daniel Matuschek, Stuart MacLean -+ * Copyright 2014-2015 - * based on code by Florian Meier - * - * This program is free software; you can redistribute it and/or -@@ -17,6 +17,13 @@ - - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - #include - #include -@@ -26,34 +33,222 @@ - - #include "../codecs/pcm512x.h" - -+#define HIFIBERRY_DACPRO_NOCLOCK 0 -+#define HIFIBERRY_DACPRO_CLK44EN 1 -+#define HIFIBERRY_DACPRO_CLK48EN 2 -+ -+struct pcm512x_priv { -+ struct regmap *regmap; -+ struct clk *sclk; -+}; -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+static bool snd_rpi_hifiberry_is_dacpro; -+ -+static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, -+ int clk_id) -+{ -+ switch (clk_id) { -+ case HIFIBERRY_DACPRO_NOCLOCK: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); -+ break; -+ case HIFIBERRY_DACPRO_CLK44EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); -+ break; -+ case HIFIBERRY_DACPRO_CLK48EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); -+ break; -+ } -+} -+ -+static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec) -+{ -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec) -+{ -+ int sck; -+ -+ sck = snd_soc_read(codec, PCM512x_RATE_DET_4); -+ return (!(sck & 0x40)); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( -+ struct snd_soc_codec *codec) -+{ -+ msleep(2); -+ return snd_rpi_hifiberry_dacplus_is_sclk(codec); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec) -+{ -+ bool isClk44EN, isClk48En, isNoClk; -+ -+ snd_rpi_hifiberry_dacplus_clk_gpio(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN); -+ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK); -+ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN); -+ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ return (isClk44EN && isClk48En && !isNoClk); -+} -+ -+static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate) -+{ -+ int type; -+ -+ switch (sample_rate) { -+ case 11025: -+ case 22050: -+ case 44100: -+ case 88200: -+ case 176400: -+ type = HIFIBERRY_DACPRO_CLK44EN; -+ break; -+ default: -+ type = HIFIBERRY_DACPRO_CLK48EN; -+ break; -+ } -+ return type; -+} -+ -+static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec, -+ int sample_rate) -+{ -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ -+ if (!IS_ERR(pcm512x->sclk)) { -+ int ctype; -+ -+ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate); -+ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) -+ ? CLK_44EN_RATE : CLK_48EN_RATE); -+ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype); -+ } -+} -+ - static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) - { - struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *priv; -+ -+ snd_rpi_hifiberry_is_dacpro -+ = snd_rpi_hifiberry_dacplus_is_pro_card(codec); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_dai_link *dai = rtd->dai_link; -+ -+ dai->name = "HiFiBerry DAC+ Pro"; -+ dai->stream_name = "HiFiBerry DAC+ Pro HiFi"; -+ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBM_CFM; -+ -+ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); -+ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03); -+ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); -+ } else { -+ priv = snd_soc_codec_get_drvdata(codec); -+ priv->sclk = ERR_PTR(-ENOENT); -+ } -+ - snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -- snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_update_rate_den( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ struct snd_ratnum *rats_no_pll; -+ unsigned int num = 0, den = 0; -+ int err; -+ -+ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); -+ if (!rats_no_pll) -+ return -ENOMEM; -+ -+ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; -+ rats_no_pll->den_min = 1; -+ rats_no_pll->den_max = 128; -+ rats_no_pll->den_step = 1; -+ -+ err = snd_interval_ratnum(hw_param_interval(params, -+ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); -+ if (err >= 0 && den) { -+ params->rate_num = num; -+ params->rate_den = den; -+ } -+ -+ devm_kfree(rtd->dev, rats_no_pll); - return 0; - } - --static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params) -+static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro( -+ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params) - { -+ int bratio = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio); -+} -+ -+static int snd_rpi_hifiberry_dacplus_hw_params( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -- return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ snd_rpi_hifiberry_dacplus_set_sclk(codec, -+ params_rate(params)); -+ -+ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai, -+ params); -+ if (!ret) -+ ret = snd_rpi_hifiberry_dacplus_update_rate_den( -+ substream, params); -+ } else { -+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ } -+ return ret; - } - --static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+static int snd_rpi_hifiberry_dacplus_startup( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); - return 0; - } - --static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { -+static void snd_rpi_hifiberry_dacplus_shutdown( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); - } - - /* machine stream operations */ -@@ -90,19 +285,20 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -- - if (pdev->dev.of_node) { -- struct device_node *i2s_node; -- struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -- i2s_node = of_parse_phandle(pdev->dev.of_node, -- "i2s-controller", 0); -- -- if (i2s_node) { -- dai->cpu_dai_name = NULL; -- dai->cpu_of_node = i2s_node; -- dai->platform_name = NULL; -- dai->platform_of_node = i2s_node; -- } -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai; -+ -+ dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } - } - - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); -diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c -index e12764d..8d16b2f 100644 ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -856,7 +856,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, - int fssp; - int gpio; - -- lrclk_div = snd_soc_params_to_frame_size(params); -+ lrclk_div = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); - if (lrclk_div == 0) { - dev_err(dev, "No LRCLK?\n"); - return -EINVAL; - -From f1c2c5ab06e1597d0aa0593c5dec52cf580332e3 Mon Sep 17 00:00:00 2001 +From a32ae7cd9db25a303aad442c459a69841add7220 Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 194/204] rpi_display: add backlight driver and overlay +Subject: [PATCH 102/113] rpi_display: add backlight driver and overlay Add a mailbox-driven backlight controller for the Raspberry Pi DSI touchscreen display. Requires updated GPU firmware to recognise the @@ -150272,7 +140623,7 @@ Signed-off-by: Gordon Hollingworth create mode 100644 drivers/video/backlight/rpi_backlight.c diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 192bda7..2e82be5 100644 +index 9411ec8..2236c85 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -38,6 +38,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb @@ -150284,7 +140635,7 @@ index 192bda7..2e82be5 100644 dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4ab4c695..b57bd11 100644 +index 6a9b270..dd1dad2 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -463,6 +463,12 @@ Load: dtoverlay=raspidac3 @@ -150328,10 +140679,10 @@ index 0000000..c021d02 + }; +}; diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 60f8357..6f4021b 100644 +index b87e731..39769f2 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -802,6 +802,7 @@ CONFIG_FB_BCM2708=y +@@ -803,6 +803,7 @@ CONFIG_FB_BCM2708=y CONFIG_FB_SSD1307=m CONFIG_FB_RPISENSE=m # CONFIG_BACKLIGHT_GENERIC is not set @@ -150340,10 +140691,10 @@ index 60f8357..6f4021b 100644 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 8ebc8d5..015540b 100644 +index 64a169d..abbe478 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -795,6 +795,7 @@ CONFIG_FB_BCM2708=y +@@ -796,6 +796,7 @@ CONFIG_FB_BCM2708=y CONFIG_FB_SSD1307=m CONFIG_FB_RPISENSE=m # CONFIG_BACKLIGHT_GENERIC is not set @@ -150352,10 +140703,10 @@ index 8ebc8d5..015540b 100644 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig -index 2d9923a..78d02bd 100644 +index 5ffa4b4..c3023ab 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig -@@ -263,6 +263,12 @@ config BACKLIGHT_PWM +@@ -265,6 +265,12 @@ config BACKLIGHT_PWM If you have a LCD backlight adjustable by PWM, say Y to enable this driver. @@ -150369,12 +140720,12 @@ index 2d9923a..78d02bd 100644 tristate "Backlight Driver for DA9030/DA9034 using WLED" depends on PMIC_DA903X diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile -index d67073f..e36907a 100644 +index 16ec534..00eff87 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile -@@ -49,6 +49,7 @@ obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o - obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o +@@ -50,6 +50,7 @@ obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o + obj-$(CONFIG_BACKLIGHT_PM8941_WLED) += pm8941-wled.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o +obj-$(CONFIG_BACKLIGHT_RPI) += rpi_backlight.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o @@ -150517,674 +140868,498 @@ index d3933af..ffb0f82 100644 RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, +From 7a91c278bb2ef86a66020fa12edcbbb5d1948bc1 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 12 Oct 2015 12:18:14 +0200 +Subject: [PATCH 104/113] BCM270X_DT: configure I2S DMA channels - -From ed66fe22cf07f1240e693bf6e7628ac9c42d36d4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 6 Oct 2015 10:16:58 +0100 -Subject: [PATCH 196/204] bcm2835-gpiomem: Fix for ARCH_BCM2835 builds - -Build on ARCH_BCM2835, and fail to probe if no IO resource. - -See: https://github.com/raspberrypi/linux/issues/1154 +Signed-off-by: Matthias Reichl --- - drivers/char/broadcom/bcm2835-gpiomem.c | 25 ++++++++++--------------- - 1 file changed, 10 insertions(+), 15 deletions(-) + arch/arm/boot/dts/bcm2708_common.dtsi | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) -diff --git a/drivers/char/broadcom/bcm2835-gpiomem.c b/drivers/char/broadcom/bcm2835-gpiomem.c -index 0085e13..911f5b7 100644 ---- a/drivers/char/broadcom/bcm2835-gpiomem.c -+++ b/drivers/char/broadcom/bcm2835-gpiomem.c -@@ -143,7 +143,6 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) - int err; - void *ptr_err; - struct device *dev = &pdev->dev; -- struct device_node *node = dev->of_node; - struct resource *ioresource; +diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi +index 5d9081a..73f2db1e 100644 +--- a/arch/arm/boot/dts/bcm2708_common.dtsi ++++ b/arch/arm/boot/dts/bcm2708_common.dtsi +@@ -119,8 +119,7 @@ + reg = <0x7e203000 0x24>, + <0x7e101098 0x08>; - /* Allocate buffers and instance data */ -@@ -157,6 +156,15 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) +- //dmas = <&dma 2>, +- // <&dma 3>; ++ dmas = <&dma 2>, <&dma 3>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + +From f4db2c33a3793419315f95b4ecfa9eb526c1a1fa Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 16:44:05 +0200 +Subject: [PATCH 105/113] bcm2835-i2s: get base address for DMA from devicetree + +Code copied from spi-bcm2835. Get physical address from devicetree +instead of using hardcoded constant. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 5a75f4b..11c209d 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include - inst->dev = dev; + #include + #include +@@ -158,10 +159,6 @@ static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { + #define BCM2835_I2S_INT_RXR BIT(1) + #define BCM2835_I2S_INT_TXW BIT(0) -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (ioresource) { -+ inst->gpio_regs_phys = ioresource->start; -+ } else { -+ dev_err(inst->dev, "failed to get IO resource"); -+ err = -ENOENT; -+ goto failed_get_resource; +-/* I2S DMA interface */ +-/* FIXME: Needs IOMMU support */ +-#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000) +- + /* General device struct */ + struct bcm2835_i2s_dev { + struct device *dev; +@@ -791,6 +788,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + int ret; + struct regmap *regmap[2]; + struct resource *mem[2]; ++ const __be32 *addr; ++ dma_addr_t dma_reg_base; ++ ++ addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); ++ if (!addr) { ++ dev_err(&pdev->dev, "could not get DMA-register address\n"); ++ return -ENODEV; + } -+ - /* Create character device entries */ ++ dma_reg_base = be32_to_cpup(addr); - err = alloc_chrdev_region(&bcm2835_gpiomem_devid, -@@ -187,20 +195,6 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) - if (IS_ERR(ptr_err)) - goto failed_device_create; + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { +@@ -817,12 +823,10 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) -- /* Get address from device tree if available (*_resource() correctly -- converts the bus address in device tree to a physical address), -- or use hardcoded offset + BCM2708_PERI_BASE if not. -- (In spite of its name 2708 actually seems to have the correct -- mach-dependent value on 2709 etc, as it is defined in -- mach-bcm270x/platform.h) */ -- -- if (node) { -- ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- inst->gpio_regs_phys = ioresource->start; -- } else { -- inst->gpio_regs_phys = GPIO_BASE; -- } -- - dev_info(inst->dev, "Initialised: Registers at 0x%08lx", - inst->gpio_regs_phys); + /* Set the DMA address */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = +- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG +- + BCM2835_VCMMU_SHIFT; ++ dma_reg_base + BCM2835_I2S_FIFO_A_REG; -@@ -214,6 +208,7 @@ static int bcm2835_gpiomem_probe(struct platform_device *pdev) - failed_cdev_add: - unregister_chrdev_region(bcm2835_gpiomem_devid, 1); - failed_alloc_chrdev: -+failed_get_resource: - kfree(inst); - failed_inst_alloc: - dev_err(inst->dev, "could not load bcm2835_gpiomem"); - -From 9223ca1be3362490e689e00156fa792e04910284 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 5 Oct 2015 10:47:45 +0100 -Subject: [PATCH 197/204] BCM270X_DT: Add at86rf233 overlay - -Add an overlay to support the Atmel AT86RF233 WPAN transceiver on spi0.0. - -See: https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 21 +++++++-- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 54 ++++++++++++++++++++++++ - 3 files changed, 72 insertions(+), 4 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 2e82be5..b370eb0 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = +- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG +- + BCM2835_VCMMU_SHIFT; ++ dma_reg_base + BCM2835_I2S_FIFO_A_REG; - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index b57bd11..014675a 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -69,13 +69,14 @@ DT parameters: - - Parameters always have default values, although in some cases (e.g. "w1-gpio") - it is necessary to provided multiple overlays in order to get the desired --behaviour. See the list of overlays below for a description of the parameters and their defaults. -+behaviour. See the list of overlays below for a description of the parameters -+and their defaults. - - The Overlay and Parameter Reference - =================================== - --N.B. When editing this file, please preserve the indentation levels to make it simple to parse --programmatically. NO HARD TABS. -+N.B. When editing this file, please preserve the indentation levels to make it -+simple to parse programmatically. NO HARD TABS. - - - Name: -@@ -149,7 +150,7 @@ Name: ads7846 - Info: ADS7846 Touch controller - Load: dtoverlay=ads7846,= - Params: cs SPI bus Chip Select (default 1) -- speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) - penirq GPIO used for PENIRQ. REQUIRED - penirq_pull Set GPIO pull (default 0=none, 2=pullup) - swapxy Swap x and y axis -@@ -170,6 +171,18 @@ Params: cs SPI bus Chip Select (default 1) - www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt - - -+Name: at86rf233 -+Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, -+ connected to spi0.0 -+Load: dtoverlay=at86rf233,= -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 750000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) -+ -+ - Name: bmp085_i2c-sensor - Info: Configures the BMP085/BMP180 digital barometric pressure and temperature - sensors from Bosch Sensortec -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -new file mode 100644 -index 0000000..70f50ea ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -0,0 +1,54 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ lowpan0: at86rf233@0 { -+ compatible = "atmel,at86rf233"; -+ reg = <0>; -+ interrupt-parent = <&gpio>; -+ interrupts = <23 4>; /* active high */ -+ reset-gpio = <&gpio 24 1>; -+ sleep-gpio = <&gpio 25 1>; -+ spi-max-frequency = <7500000>; -+ xtal-trim = /bits/ 8 <0xf>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lowpan0_pins: lowpan0_pins { -+ brcm,pins = <23 24 25>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ interrupt = <&lowpan0>, "interrupts:0", -+ <&lowpan0_pins>, "brcm,pins:0"; -+ reset = <&lowpan0>, "reset-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:4"; -+ sleep = <&lowpan0>, "sleep-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:8"; -+ speed = <&lowpan0>, "spi-max-frequency:0"; -+ trim = <&lowpan0>, "xtal-trim.0"; -+ }; -+}; + /* Set the bus width */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = -From c089bd70a6d37cb4a05626d48eaebcdfcef0bf41 Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Sun, 18 Oct 2015 17:07:24 -0700 -Subject: [PATCH 198/204] New overlay for PiScreen2r +From bbdb22a1df4ba9153fca8c50fb3d9ee464936044 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:13:35 +0200 +Subject: [PATCH 106/113] configs: enable SND_BCM2835_SOC_I2S ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 +++ - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 100 ++++++++++++++++++++++ - 3 files changed, 115 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index b370eb0..f4b2817 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -34,6 +34,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 014675a..3276312 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -411,6 +411,20 @@ Params: speed Display SPI bus speed - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: piscreen2r -+Info: PiScreen 2 with resistive TP display by OzzMaker.com -+Load: dtoverlay=piscreen,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= -diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -new file mode 100644 -index 0000000..7c018e0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -0,0 +1,100 @@ -+ /* -+ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen2_pins: piscreen2_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen2: piscreen2@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen2_pins>; -+ bgr; -+ spi-max-frequency = <64000000>; -+ rotate = <90>; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ txbuflen = <32768>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c0 0x11 0x09 -+ 0x10000c1 0x41 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000b6 0x00 0x02 -+ 0x10000f7 0xa9 0x51 0x2c 0x2 -+ 0x10000be 0x00 0x04 -+ 0x10000e9 0x00 -+ 0x1000011 -+ 0x1000029>; -+ -+ }; -+ -+ piscreen2_ts: piscreen2-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,swap-xy; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen2>,"spi-max-frequency:0"; -+ rotate = <&piscreen2>,"rotate:0"; -+ fps = <&piscreen2>,"fps:0"; -+ debug = <&piscreen2>,"debug:0"; -+ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -+ - -From 30a73891df28c2922fcad40317f474914ccf4434 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 9 Oct 2015 10:49:00 +0100 -Subject: [PATCH 199/204] BCM270X_DT: Make mmc overlay compatible with current - firmware - -The original DT overlay logic followed a merge-then-patch procedure, -i.e. parameters are applied to the loaded overlay before the overlay -is merged into the base DTB. This sequence has been changed to -patch-then-merge, in order to support parameterised node names, and -to protect against bad overlays. As a result, overrides (parameters) -must only target labels in the overlay, but the overlay can obviously target nodes in the base DTB. - -mmc-overlay.dts (that switches back to the original mmc sdcard -driver) is the only overlay violating that rule, and this patch -fixes it. ---- - arch/arm/boot/dts/overlays/mmc-overlay.dts | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts -index 0a37cf4..4579ff2 100644 ---- a/arch/arm/boot/dts/overlays/mmc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -7,13 +7,13 @@ - fragment@0 { - target = <&mmc>; - -- __overlay__ { -+ frag0: __overlay__ { - brcm,overclock-50 = <0>; - }; - }; - - __overrides__ { -- overclock_50 = <&mmc>,"brcm,overclock-50:0"; -- force_pio = <&mmc>,"brcm,force-pio?"; -+ overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; - }; - }; - -From 25dc64a6491a98e8df7b387e54dfe1d2be1ea5e8 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 12 Oct 2015 08:52:00 +0100 -Subject: [PATCH 200/204] BCM270X_DT: Reduce default at86rf233 SPI frequency - -The AT86RF233 has been found to be unreliable on a 7.5MHz SPI bus, -so reduce the default frequency to 6MHz. - -See: https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/README | 2 +- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 3276312..42a5876 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -178,7 +178,7 @@ Load: dtoverlay=at86rf233,= - Params: interrupt GPIO used for INT (default 23) - reset GPIO used for Reset (default 24) - sleep GPIO used for Sleep (default 25) -- speed SPI bus speed in Hz (default 750000) -+ speed SPI bus speed in Hz (default 6000000) - trim Fine tuning of the internal capacitance - arrays (0=+0pF, 15=+4.5pF, default 15) - -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -index 70f50ea..0460269 100644 ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -25,7 +25,7 @@ - interrupts = <23 4>; /* active high */ - reset-gpio = <&gpio 24 1>; - sleep-gpio = <&gpio 25 1>; -- spi-max-frequency = <7500000>; -+ spi-max-frequency = <6000000>; - xtal-trim = /bits/ 8 <0xf>; - }; - }; - -From 625d90e2f7b2de52e0ba82e66e076915402e9c8b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 1 Oct 2015 11:49:11 +0100 -Subject: [PATCH 201/204] config: Add CONFIG_UHID +Allow bcm2835-i2s compilation on BCM270x and enable in bcm2709_defconfig +and bcmrpi_defconfig +Signed-off-by: Matthias Reichl --- arch/arm/configs/bcm2709_defconfig | 1 + arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) + sound/soc/bcm/Kconfig | 2 +- + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6f4021b..6a914fb 100644 +index 39769f2..e4df400 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -843,6 +843,7 @@ CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y -+CONFIG_UHID=m - CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m +@@ -830,6 +830,7 @@ CONFIG_SND_USB_CAIAQ=m + CONFIG_SND_USB_CAIAQ_INPUT=y + CONFIG_SND_USB_6FIRE=m + CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 015540b..7a477e3 100644 +index abbe478..84aeada 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -836,6 +836,7 @@ CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_SOUND_PRIME=m - CONFIG_HIDRAW=y -+CONFIG_UHID=m - CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m +@@ -823,6 +823,7 @@ CONFIG_SND_USB_CAIAQ=m + CONFIG_SND_USB_CAIAQ_INPUT=y + CONFIG_SND_USB_6FIRE=m + CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index f465dd2..fd3aaa4 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -1,6 +1,6 @@ + config SND_BCM2835_SOC_I2S + tristate "SoC Audio support for the Broadcom BCM2835 I2S module" +- depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on ARCH_BCM2835 || MACH_BCM2708 || MACH_BCM2709 || COMPILE_TEST + select SND_SOC_GENERIC_DMAENGINE_PCM + select REGMAP_MMIO + help -From 7a8dc0c298b4619fe8658481d0b3ae0ac1231a5e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 4 Oct 2015 12:30:01 +0100 -Subject: [PATCH 202/204] config: Add CONFIG_CRYPTO_USER_API_SKCIPHER +From 48ce0895d05eefded0897a67ec03aeefacaf42f1 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:21:16 +0200 +Subject: [PATCH 107/113] bcm2835-i2s: add 24bit support, update bclk_ratio to + more correct values +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit 62c05a0b5328d9376d39c9e74da10b8a2465c234 ("ASoC: BCM2708: +Add 24 bit support") + +This adds 24 bit support to the I2S driver of the BCM2708. +Besides enabling the 24 bit flags, it includes two bug fixes: + +MMAP is not supported. Claiming this leads to strange issues +when the format of driver and file do not match. + +The datasheet states that the width extension bit should be set +for widths greater than 24, but greater or equal would be correct. +This follows from the definition of the width field. + +Signed-off-by: Florian Meier + +RPi commit 3e8c672bc4e92d457aa4654bbb4cfd79a18a2327 ("bcm2708-i2s: +Update bclk_ratio to more correct values") + +Discussion about blck_ratio affecting sound quality: +https://github.com/raspberrypi/linux/issues/681 + +Signed-off-by: Matthias Reichl --- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) + sound/soc/bcm/bcm2835-i2s.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6a914fb..05383c0 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1239,6 +1239,7 @@ CONFIG_CRYPTO_WP512=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_USER_API_SKCIPHER=m - # CONFIG_CRYPTO_HW is not set - CONFIG_ARM_CRYPTO=y - CONFIG_CRYPTO_SHA1_ARM_NEON=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 7a477e3..0f315d8 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1235,6 +1235,7 @@ CONFIG_CRYPTO_WP512=m - CONFIG_CRYPTO_CAST5=m - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_USER_API_SKCIPHER=m - # CONFIG_CRYPTO_HW is not set - CONFIG_ARM_CRYPTO=y - CONFIG_CRYPTO_SHA1_ARM=m - -From c7158fd021cf31f5fb67768796aecabde5ff6727 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 4 Oct 2015 12:36:44 +0100 -Subject: [PATCH 203/204] config: Add options for supporting openlabs 802.15.4 - radio - ---- - arch/arm/configs/bcm2709_defconfig | 6 ++++++ - arch/arm/configs/bcmrpi_defconfig | 6 ++++++ - 2 files changed, 12 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 05383c0..fb402e8 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -283,6 +283,9 @@ CONFIG_VLAN_8021Q=m - CONFIG_VLAN_8021Q_GVRP=y - CONFIG_ATALK=m - CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_CBQ=m - CONFIG_NET_SCH_HTB=m -@@ -529,6 +532,9 @@ CONFIG_ZD1211RW=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m - CONFIG_INPUT_POLLDEV=m - # CONFIG_INPUT_MOUSEDEV_PSAUX is not set - CONFIG_INPUT_JOYDEV=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0f315d8..eb81555e 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -276,6 +276,9 @@ CONFIG_VLAN_8021Q=m - CONFIG_VLAN_8021Q_GVRP=y - CONFIG_ATALK=m - CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_CBQ=m - CONFIG_NET_SCH_HTB=m -@@ -522,6 +525,9 @@ CONFIG_ZD1211RW=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m - CONFIG_INPUT_POLLDEV=m - # CONFIG_INPUT_MOUSEDEV_PSAUX is not set - CONFIG_INPUT_JOYDEV=m - -From 6c1d6379ed6d95956ba255936da39f06543ddb7f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 8 Oct 2015 13:33:28 +0100 -Subject: [PATCH 204/204] scripts/mkknlimg: Improve ARCH_BCM2835 detection - -The board support code contains sufficient strings to be able to -distinguish 2708 vs. 2835 builds, so remove the check for -bcm2835-pm-wdt which could exist in either. - -Also, since the canned configuration is no longer built in (it's -a module), remove the config string checking. - -See: https://github.com/raspberrypi/linux/issues/1157 ---- - scripts/mkknlimg | 41 +++++------------------------------------ - 1 file changed, 5 insertions(+), 36 deletions(-) - -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -index 3dff948..3998d43 100755 ---- a/scripts/mkknlimg -+++ b/scripts/mkknlimg -@@ -50,12 +50,6 @@ if (! -r $kernel_file) - usage(); - } +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 11c209d..1c44a34 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -340,11 +340,15 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + data_length = 16; +- bclk_ratio = 40; ++ bclk_ratio = 50; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ data_length = 24; ++ bclk_ratio = 50; + break; + case SNDRV_PCM_FORMAT_S32_LE: + data_length = 32; +- bclk_ratio = 80; ++ bclk_ratio = 100; + break; + default: + return -EINVAL; +@@ -420,7 +424,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + /* Setup the frame format */ + format = BCM2835_I2S_CHEN; --my @wanted_config_lines = --( -- 'CONFIG_BCM2708_DT', -- 'CONFIG_ARCH_BCM2835' --); +- if (data_length > 24) ++ if (data_length >= 24) + format |= BCM2835_I2S_CHWEX; + + format |= BCM2835_I2S_CHWID((data_length-8)&0xf); +@@ -711,6 +715,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE + | SNDRV_PCM_FMTBIT_S32_LE + }, + .capture = { +@@ -718,6 +723,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE + | SNDRV_PCM_FMTBIT_S32_LE + }, + .ops = &bcm2835_i2s_dai_ops, + +From baab4d800282582ca2c1b17a469fcebbd951f07a Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:25:51 +0200 +Subject: [PATCH 108/113] bcm2835-i2s: setup clock only if CPU is clock master + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit c14827ecdaa36607f6110f9ce8df96e698672191 ("bcm2708: Allow +option card devices to be configured via DT") + +Original work by Zoltan Szenczi, committed to RPi tree by +Phil Elwell. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 1c44a34..2a5d9d6 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -411,15 +411,25 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + divf = dividend & BCM2835_CLK_DIVF_MASK; + } + +- /* Set clock divider */ +- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD +- | BCM2835_CLK_DIVI(divi) +- | BCM2835_CLK_DIVF(divf)); - - my @wanted_strings = - ( - 'bcm2708_fb', -@@ -63,7 +57,8 @@ my @wanted_strings = - 'brcm,bcm2835-sdhost', - 'brcm,bcm2708-pinctrl', - 'brcm,bcm2835-gpio', -- 'brcm,bcm2835-pm-wdt' -+ 'brcm,bcm2835', -+ 'brcm,bcm2836' - ); +- /* Setup clock, but don't start it yet */ +- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD +- | BCM2835_CLK_MASH(mash) +- | BCM2835_CLK_SRC(clk_src)); ++ /* Clock should only be set up here if CPU is clock master */ ++ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ case SND_SOC_DAIFMT_CBS_CFM: ++ /* Set clock divider */ ++ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, ++ BCM2835_CLK_PASSWD ++ | BCM2835_CLK_DIVI(divi) ++ | BCM2835_CLK_DIVF(divf)); ++ ++ /* Setup clock, but don't start it yet */ ++ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, ++ BCM2835_CLK_PASSWD ++ | BCM2835_CLK_MASH(mash) ++ | BCM2835_CLK_SRC(clk_src)); ++ break; ++ default: ++ break; ++ } - my $res = try_extract($kernel_file, $tmpfile1); -@@ -98,12 +93,11 @@ if ($res) - config_bool($res, 'brcm,bcm2835-mmc') || - config_bool($res, 'brcm,bcm2835-sdhost')) + /* Setup the frame format */ + format = BCM2835_I2S_CHEN; + +From 2d1ce550ee0c8fc1dd65d9ccc8091b85d9f3da62 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:49:51 +0200 +Subject: [PATCH 109/113] bcm2835-i2s: Eliminate debugfs directory error + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit fd7d7a3dbe9262d16971ef81c234ed28c6499dd7 ("bcm2708: +Eliminate i2s debugfs directory error") + +Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') +to avoid the name clash when registering debugfs entries. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 2a5d9d6..8db6d90 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -782,6 +782,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { + .precious_reg = bcm2835_i2s_precious_reg, + .volatile_reg = bcm2835_i2s_volatile_reg, + .cache_type = REGCACHE_RBTREE, ++ .name = "i2s", + }, { -- $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); -- $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); - $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); - $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); -- $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); -- $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt'); -+ $is_283x ||= config_bool($res, 'brcm,bcm2835'); -+ $is_283x ||= config_bool($res, 'brcm,bcm2836'); -+ $dtok ||= $is_283x; - $append_trailer = 1; - } - else -@@ -205,31 +199,6 @@ sub try_extract - $res->{$match} = 1; + .reg_bits = 32, +@@ -790,6 +791,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { + .max_register = BCM2835_CLK_PCMDIV_REG, + .volatile_reg = bcm2835_clk_volatile_reg, + .cache_type = REGCACHE_RBTREE, ++ .name = "clk", + }, + }; + + +From 905fbd8a8a81de4cec733e92e3bf99f9c7ccad2e Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:35:20 +0200 +Subject: [PATCH 110/113] bcm2835-i2s: Register PCM device + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit ba46b4935a23aa2caac1855ead52a035d4776680 ("ASoC: Add +support for BCM2708") + +This driver adds support for digital audio (I2S) +for the BCM2708 SoC that is used by the +Raspberry Pi. External audio codecs can be +connected to the Raspberry Pi via P5 header. + +It relies on cyclic DMA engine support for BCM2708. + +Signed-off-by: Florian Meier + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 8db6d90..6ce6c3f 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -799,6 +799,25 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { + .name = "bcm2835-i2s-comp", + }; + ++static const struct snd_pcm_hardware bcm2835_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_JOINT_DUPLEX, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE, ++ .period_bytes_min = 32, ++ .period_bytes_max = 64 * PAGE_SIZE, ++ .periods_min = 2, ++ .periods_max = 255, ++ .buffer_bytes_max = 128 * PAGE_SIZE, ++}; ++ ++static const struct snd_dmaengine_pcm_config bcm2835_dmaengine_pcm_config = { ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++ .pcm_hardware = &bcm2835_pcm_hardware, ++ .prealloc_buffer_size = 256 * PAGE_SIZE, ++}; ++ + static int bcm2835_i2s_probe(struct platform_device *pdev) + { + struct bcm2835_i2s_dev *dev; +@@ -870,7 +889,9 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + return ret; } -- my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$'; -- my $cf1 = 'IKCFG_ST\037\213\010'; -- my $cf2 = '0123456789'; -- -- my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`; -- if ($pos) -- { -- $pos =~ s/:.*[\r\n]*$//s; -- $pos += 8; -- my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8); -- if (($err == 0) || ($err == 2)) -- { -- if (open(my $fh, '<', $tmp)) -- { -- while (my $line = <$fh>) -- { -- chomp($line); -- $res->{$1} = $2 if ($line =~ /$config_pattern/); -- } -- -- close($fh); -- } -- } -- } -- - return $res; - } +- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); ++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, ++ &bcm2835_dmaengine_pcm_config, ++ SND_DMAENGINE_PCM_FLAG_COMPAT); + if (ret) { + dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); + return ret; + +From 7cf1bac3f8f5fc8d41f4598a4245f1d0e9974742 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 11 Oct 2015 15:55:21 +0200 +Subject: [PATCH 111/113] bcm2835-i2s: Enable MMAP support via a DT property + +Code ported from bcm2708-i2s driver in Raspberry Pi tree. + +RPi commit 7ee829fd77a30127db5d0b3c7d79b8718166e568 ("bcm2708-i2s: +Enable MMAP support via a DT property and overlay") + +The i2s driver used to claim to support MMAP, but that feature was disabled +when some problems were found. Add the ability to enable this feature +through Device Tree, using the i2s-mmap overlay. + +See: #1004 + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/bcm2835-i2s.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 6ce6c3f..2a6334b 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -799,7 +799,7 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { + .name = "bcm2835-i2s-comp", + }; +-static const struct snd_pcm_hardware bcm2835_pcm_hardware = { ++static struct snd_pcm_hardware bcm2835_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_JOINT_DUPLEX, + .formats = SNDRV_PCM_FMTBIT_S16_LE | +@@ -835,6 +835,11 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + } + dma_reg_base = be32_to_cpup(addr); + ++ if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) ++ bcm2835_pcm_hardware.info |= ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID; ++ + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { + void __iomem *base; + +From 5178cffda1705dcc2735c4d59b8b9165d97e1aa6 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 12 Oct 2015 12:19:16 +0200 +Subject: [PATCH 112/113] BCM270X_DT: switch to bcm2835-i2s + +I2S soundcard drivers with proper devicetree support (i.e. not linking +to the cpu_dai/platform via name but to cpu/platform via of_node) +will work out of the box without any modifications. + +When the kernel is compiled without devicetree support the platform +code will instantiate the bcm2708-i2s driver and I2S soundcard drivers +will link to it via name, as before. + +Signed-off-by: Matthias Reichl +--- + arch/arm/boot/dts/bcm2708_common.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi +index 73f2db1e..c658c7b 100644 +--- a/arch/arm/boot/dts/bcm2708_common.dtsi ++++ b/arch/arm/boot/dts/bcm2708_common.dtsi +@@ -115,7 +115,7 @@ + }; + + i2s: i2s@7e203000 { +- compatible = "brcm,bcm2708-i2s"; ++ compatible = "brcm,bcm2835-i2s"; + reg = <0x7e203000 0x24>, + <0x7e101098 0x08>; + + +From 59d68c0263ecaa076d524c8a5667da285e318434 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Wed, 14 Oct 2015 13:14:02 +0200 +Subject: [PATCH 113/113] config: fix RaspiDAC Rev.3x dependencies + +Change depends to SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +like the other I2S soundcard drivers. + +Signed-off-by: Matthias Reichl +--- + sound/soc/bcm/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index fd3aaa4..794ff7a 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -70,7 +70,7 @@ config SND_BCM2708_SOC_IQAUDIO_DAC + + config SND_BCM2708_SOC_RASPIDAC3 + tristate "Support for RaspiDAC Rev.3x" +- depends on SND_BCM2708_SOC_I2S ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_PCM512x_I2C + select SND_SOC_TPA6130A2 + help