Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Linux driver for TerraTec DMX 6Fire USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Device communications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author:	Torsten Schenk <torsten.schenk@zoho.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Created:	Jan 01, 2011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright:	(C) Torsten Schenk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "comm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "chip.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "midi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	COMM_EP = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	COMM_FPGA_EP = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		u8 *buffer, void *context, void(*handler)(struct urb *urb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	usb_init_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	urb->transfer_buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	urb->complete = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	urb->context = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	urb->interval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	urb->dev = rt->chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static void usb6fire_comm_receiver_handler(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct comm_runtime *rt = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct midi_runtime *midi_rt = rt->chip->midi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	if (!urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		if (rt->receiver_buffer[0] == 0x10) /* midi in event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			if (midi_rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 				midi_rt->in_received(midi_rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 						rt->receiver_buffer + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 						rt->receiver_buffer[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (!rt->chip->shutdown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		urb->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		urb->actual_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			dev_warn(&urb->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 					"comm data receiver aborted.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static void usb6fire_comm_init_buffer(u8 *buffer, u8 id, u8 request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		u8 reg, u8 vl, u8 vh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	buffer[0] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	buffer[2] = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	buffer[3] = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		buffer[1] = 0x05; /* length (starting at buffer[2]) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		buffer[4] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		buffer[5] = vl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		buffer[6] = vh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	case 0x12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		buffer[1] = 0x0b; /* length (starting at buffer[2]) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		buffer[4] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		buffer[5] = 0x18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		buffer[6] = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		buffer[7] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		buffer[8] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		buffer[9] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		buffer[10] = 0x9e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		buffer[11] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		buffer[12] = vl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	case 0x21:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	case 0x22:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		buffer[1] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		buffer[4] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		buffer[5] = vl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	int actual_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			buffer, buffer[1] + 2, &actual_len, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	else if (actual_len != buffer[1] + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* 13: maximum length of message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	buffer = kmalloc(13, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		u8 reg, u8 vl, u8 vh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* 13: maximum length of message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	buffer = kmalloc(13, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int usb6fire_comm_init(struct sfire_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (!rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (!rt->receiver_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		kfree(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	urb = &rt->receiver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	rt->serial = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	rt->chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	usb_init_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	rt->init_urb = usb6fire_comm_init_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	rt->write8 = usb6fire_comm_write8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	rt->write16 = usb6fire_comm_write16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	/* submit an urb that receives communication data from device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	urb->transfer_buffer = rt->receiver_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	urb->transfer_buffer_length = COMM_RECEIVER_BUFSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	urb->pipe = usb_rcvintpipe(chip->dev, COMM_EP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	urb->dev = chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	urb->complete = usb6fire_comm_receiver_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	urb->context = rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	urb->interval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	ret = usb_submit_urb(urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		kfree(rt->receiver_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		kfree(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		dev_err(&chip->dev->dev, "cannot create comm data receiver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	chip->comm = rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) void usb6fire_comm_abort(struct sfire_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct comm_runtime *rt = chip->comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		usb_poison_urb(&rt->receiver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void usb6fire_comm_destroy(struct sfire_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	struct comm_runtime *rt = chip->comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	kfree(rt->receiver_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	kfree(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	chip->comm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }