Skip to content

Instantly share code, notes, and snippets.

@alesandar
Created June 7, 2020 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alesandar/d4265522bc42f25a77d1467264c8c11b to your computer and use it in GitHub Desktop.
Save alesandar/d4265522bc42f25a77d1467264c8c11b to your computer and use it in GitHub Desktop.
--- linux/drivers/firewire/ohci.c
+++ linux/drivers/firewire/ohci.c
@@ -275,6 +275,8 @@
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
+#define PCI_DEVICE_ID_RICOH_R5C832 0x0832
+#define PCI_DEVICE_ID_RICOH_R5C832_E 0xe832
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025
@@ -289,6 +291,7 @@
#define QUIRK_NO_MSI 0x10
#define QUIRK_TI_SLLZ059 0x20
#define QUIRK_IR_WAKE 0x40
+#define QUIRK_RICOH_FIFO_SIZE 0x80
/* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct {
@@ -315,6 +318,12 @@
{PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_NO_MSI},
+ {PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER | QUIRK_RICOH_FIFO_SIZE},
+
+ {PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832_E, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER | QUIRK_NO_MSI | QUIRK_RICOH_FIFO_SIZE},
+
{PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
@@ -354,8 +363,14 @@
", disable MSI = " __stringify(QUIRK_NO_MSI)
", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059)
", IR wake unreliable = " __stringify(QUIRK_IR_WAKE)
+ ", Ricoh FIFO configurable = " __stringify(QUIRK_RICOH_FIFO_SIZE)
")");
+static bool param_ricoh_audio;
+module_param_named(ricoh_audio, param_ricoh_audio, bool, 0444);
+MODULE_PARM_DESC(ricoh_audio,
+ "Prioritize audio over disk traffic on Ricoh controllers");
+
#define OHCI_PARAM_DEBUG_AT_AR 1
#define OHCI_PARAM_DEBUG_SELFIDS 2
#define OHCI_PARAM_DEBUG_IRQS 4
@@ -2279,6 +2294,40 @@
return 1;
}
+static void configure_ricoh_fifo(struct fw_ohci *ohci)
+{
+ struct pci_dev *dev = to_pci_dev(ohci->card.device);
+ int where;
+ u32 val;
+
+ switch (dev->device) {
+ case PCI_DEVICE_ID_RICOH_R5C832:
+ where = 0x88;
+ break;
+ case PCI_DEVICE_ID_RICOH_R5C832_E:
+ where = 0xe8;
+ break;
+ default:
+ return;
+ }
+
+ /* undocumented magic */
+ pci_read_config_dword(dev, where, &val);
+ val &= ~(0xff << 24);
+ if (param_ricoh_audio)
+ val |= 0x20 << 24;
+ pci_write_config_dword(dev, where, val);
+
+ /* adjust the max_rec field */
+ val = reg_read(ohci, OHCI1394_BusOptions);
+ val &= ~(0xf << 12);
+ if (param_ricoh_audio)
+ val |= 0x8 << 12; /* 512 bytes */
+ else
+ val |= 0xa << 12; /* 2048 bytes */
+ reg_write(ohci, OHCI1394_BusOptions, val);
+}
+
static int ohci_enable(struct fw_card *card,
const __be32 *config_rom, size_t length)
{
@@ -2331,6 +2380,9 @@
ohci->quirks &= ~QUIRK_TI_SLLZ059;
}
+ if (ohci->quirks & QUIRK_RICOH_FIFO_SIZE)
+ configure_ricoh_fifo(ohci);
+
reg_write(ohci, OHCI1394_HCControlClear,
OHCI1394_HCControl_noByteSwapData);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment