drivers/media/dvb-frontends/m88ds3103.c

Source file repositories/reference/linux-study-clean/drivers/media/dvb-frontends/m88ds3103.c

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/m88ds3103.c
Extension
.c
Size
51441 bytes
Lines
2250
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (dev->chiptype == M88DS3103_CHIPTYPE_3103C) {
			ret = regmap_read(dev->regmap, 0x0d, &utmp);
			if (ret)
				goto err;

			if ((utmp & 0xf7) == 0xf7)
				*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
					  FE_HAS_VITERBI | FE_HAS_SYNC |
					  FE_HAS_LOCK;
		} else {
			ret = regmap_read(dev->regmap, 0xd1, &utmp);
			if (ret)
				goto err;

			if ((utmp & 0x07) == 0x07)
				*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
					  FE_HAS_VITERBI | FE_HAS_SYNC |
					  FE_HAS_LOCK;
		}
		break;
	case SYS_DVBS2:
		ret = regmap_read(dev->regmap, 0x0d, &utmp);
		if (ret)
			goto err;

		if ((utmp & 0x8f) == 0x8f)
			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
				  FE_HAS_VITERBI | FE_HAS_SYNC |
				  FE_HAS_LOCK;
		break;
	default:
		dev_dbg(&client->dev, "invalid delivery_system\n");
		ret = -EINVAL;
		goto err;
	}

	dev->fe_status = *status;
	dev_dbg(&client->dev, "lock=%02x status=%02x\n", utmp, *status);

	/* CNR */
	if (dev->fe_status & FE_HAS_VITERBI) {
		unsigned int cnr, noise, signal, noise_tot, signal_tot;

		cnr = 0;
		/* more iterations for more accurate estimation */
		#define M88DS3103_SNR_ITERATIONS 3

		switch (c->delivery_system) {
		case SYS_DVBS:
			itmp = 0;

			for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
				ret = regmap_read(dev->regmap, 0xff, &utmp);
				if (ret)
					goto err;

				itmp += utmp;
			}

			/* use of single register limits max value to 15 dB */
			/* SNR(X) dB = 10 * ln(X) / ln(10) dB */
			itmp = DIV_ROUND_CLOSEST(itmp, 8 * M88DS3103_SNR_ITERATIONS);
			if (itmp)
				cnr = div_u64((u64) 10000 * intlog2(itmp), intlog2(10));
			break;
		case SYS_DVBS2:
			noise_tot = 0;
			signal_tot = 0;

			for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
				ret = regmap_bulk_read(dev->regmap, 0x8c, buf, 3);
				if (ret)
					goto err;

				noise = buf[1] << 6;    /* [13:6] */
				noise |= buf[0] & 0x3f; /*  [5:0] */
				noise >>= 2;
				signal = buf[2] * buf[2];
				signal >>= 1;

				noise_tot += noise;
				signal_tot += signal;
			}

			noise = noise_tot / M88DS3103_SNR_ITERATIONS;
			signal = signal_tot / M88DS3103_SNR_ITERATIONS;

			/* SNR(X) dB = 10 * log10(X) dB */
			if (signal > noise) {
				itmp = signal / noise;

Annotation

Implementation Notes