sound/pci/cs46xx/dsp_spos.c

Source file repositories/reference/linux-study-clean/sound/pci/cs46xx/dsp_spos.c

File Facts

System
Linux kernel
Corpus path
sound/pci/cs46xx/dsp_spos.c
Extension
.c
Size
53794 bytes
Lines
1966
Domain
Driver Families
Bucket
sound/pci
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

if (ins->code.offset > 0) {
			mop_operands = (hival >> 6) & 0x03fff;
			mop_type = mop_operands >> 10;
      
			/* check for wide type instruction */
			if (mop_type == 0 &&
			    (mop_operands & WIDE_LADD_INSTR_MASK) == 0 &&
			    (mop_operands & WIDE_INSTR_MASK) != 0) {
				wide_op = loval & 0x7f;
				for (j = 0;j < ARRAY_SIZE(wide_opcodes); ++j) {
					if (wide_opcodes[j] == wide_op) {
						/* need to reallocate instruction */
						address  = (hival & 0x00FFF) << 5;
						address |=  loval >> 15;
            
						dev_dbg(chip->card->dev,
							"handle_wideop[1]: %05x:%05x addr %04x\n",
							hival, loval, address);
            
						if ( !(address & 0x8000) ) {
							address += (ins->code.offset / 2) - overlay_begin_address;
						} else {
							dev_dbg(chip->card->dev,
								"handle_wideop[1]: ROM symbol not reallocated\n");
						}
            
						hival &= 0xFF000;
						loval &= 0x07FFF;
            
						hival |= ( (address >> 5)  & 0x00FFF);
						loval |= ( (address << 15) & 0xF8000);
            
						address  = (hival & 0x00FFF) << 5;
						address |=  loval >> 15;
            
						dev_dbg(chip->card->dev,
							"handle_wideop:[2] %05x:%05x addr %04x\n",
							hival, loval, address);
						nreallocated++;
					} /* wide_opcodes[j] == wide_op */
				} /* for */
			} /* mod_type == 0 ... */
		} /* ins->code.offset > 0 */

		ins->code.data[ins->code.size++] = loval;
		ins->code.data[ins->code.size++] = hival;
	}

	dev_dbg(chip->card->dev,
		"dsp_spos: %d instructions reallocated\n", nreallocated);
	return nreallocated;
}

static struct dsp_segment_desc * get_segment_desc (struct dsp_module_desc * module, int seg_type)
{
	int i;
	for (i = 0;i < module->nsegments; ++i) {
		if (module->segments[i].segment_type == seg_type) {
			return (module->segments + i);
		}
	}

	return NULL;
};

static int find_free_symbol_index (struct dsp_spos_instance * ins)
{
	int index = ins->symbol_table.nsymbols,i;

	for (i = ins->symbol_table.highest_frag_index; i < ins->symbol_table.nsymbols; ++i) {
		if (ins->symbol_table.symbols[i].deleted) {
			index = i;
			break;
		}
	}

	return index;
}

static int add_symbols (struct snd_cs46xx * chip, struct dsp_module_desc * module)
{
	int i;
	struct dsp_spos_instance * ins = chip->dsp_spos_instance;

	if (module->symbol_table.nsymbols > 0) {
		if (!strcmp(module->symbol_table.symbols[0].symbol_name, "OVERLAYBEGINADDRESS") &&
		    module->symbol_table.symbols[0].symbol_type == SYMBOL_CONSTANT ) {
			module->overlay_begin_address = module->symbol_table.symbols[0].address;
		}
	}

Annotation

Implementation Notes