drivers/media/test-drivers/vivid/vivid-rds-gen.c

Source file repositories/reference/linux-study-clean/drivers/media/test-drivers/vivid/vivid-rds-gen.c

File Facts

System
Linux kernel
Corpus path
drivers/media/test-drivers/vivid/vivid-rds-gen.c
Extension
.c
Size
4715 bytes
Lines
158
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (grp) {
		case 0 ... 3:
		case 22 ... 25:
		case 44 ... 47: /* Group 0B */
			idx = (grp % 22) % 4;
			data[1].lsb |= (rds->ta << 4) | (rds->ms << 3);
			data[1].lsb |= vivid_get_di(rds, idx);
			data[1].msb |= 1 << 3;
			data[2].lsb = rds->picode & 0xff;
			data[2].msb = rds->picode >> 8;
			data[2].block = V4L2_RDS_BLOCK_C_ALT | (V4L2_RDS_BLOCK_C_ALT << 3);
			data[3].lsb = rds->psname[2 * idx + 1];
			data[3].msb = rds->psname[2 * idx];
			break;
		case 4 ... 19:
		case 26 ... 41: /* Group 2A */
			idx = ((grp - 4) % 22) % 16;
			data[1].lsb |= idx;
			data[1].msb |= 4 << 3;
			data[2].msb = rds->radiotext[4 * idx];
			data[2].lsb = rds->radiotext[4 * idx + 1];
			data[2].block = V4L2_RDS_BLOCK_C | (V4L2_RDS_BLOCK_C << 3);
			data[3].msb = rds->radiotext[4 * idx + 2];
			data[3].lsb = rds->radiotext[4 * idx + 3];
			break;
		case 56:
			/*
			 * Group 4A
			 *
			 * Uses the algorithm from Annex G of the RDS standard
			 * EN 50067:1998 to convert a UTC date to an RDS Modified
			 * Julian Day.
			 */
			time64_to_tm(ktime_get_real_seconds(), 0, &tm);
			l = tm.tm_mon <= 1;
			date = 14956 + tm.tm_mday + ((tm.tm_year - l) * 1461) / 4 +
				((tm.tm_mon + 2 + l * 12) * 306001) / 10000;
			time = (tm.tm_hour << 12) |
			       (tm.tm_min << 6) |
			       (sys_tz.tz_minuteswest >= 0 ? 0x20 : 0) |
			       (abs(sys_tz.tz_minuteswest) / 30);
			data[1].lsb &= ~3;
			data[1].lsb |= date >> 15;
			data[1].msb |= 8 << 3;
			data[2].lsb = (date << 1) & 0xfe;
			data[2].lsb |= (time >> 16) & 1;
			data[2].msb = (date >> 7) & 0xff;
			data[2].block = V4L2_RDS_BLOCK_C | (V4L2_RDS_BLOCK_C << 3);
			data[3].lsb = time & 0xff;
			data[3].msb = (time >> 8) & 0xff;
			break;
		default: /* Group 15B */
			data[1].lsb |= (rds->ta << 4) | (rds->ms << 3);
			data[1].lsb |= vivid_get_di(rds, grp % 22);
			data[1].msb |= 0x1f << 3;
			data[2].lsb = rds->picode & 0xff;
			data[2].msb = rds->picode >> 8;
			data[2].block = V4L2_RDS_BLOCK_C_ALT | (V4L2_RDS_BLOCK_C_ALT << 3);
			data[3].lsb = rds->pty << 5;
			data[3].lsb |= (rds->ta << 4) | (rds->ms << 3);
			data[3].lsb |= vivid_get_di(rds, grp % 22);
			data[3].msb |= rds->pty >> 3;
			data[3].msb |= 0x1f << 3;
			break;
		}
	}
}

void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq,
			  bool alt)
{
	/* Alternate PTY between Info and Weather */
	if (rds->use_rbds) {
		rds->picode = 0x2e75; /* 'KLNX' call sign */
		rds->pty = alt ? 29 : 2;
	} else {
		rds->picode = 0x8088;
		rds->pty = alt ? 16 : 3;
	}
	rds->mono_stereo = true;
	rds->art_head = false;
	rds->compressed = false;
	rds->dyn_pty = false;
	rds->tp = true;
	rds->ta = alt;
	rds->ms = true;
	snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d",
		 (freq / 16) % 1000000, (((freq & 0xf) * 10) / 16) % 10);
	if (alt)
		strscpy(rds->radiotext,

Annotation

Implementation Notes