18c2ecf20Sopenharmony_ci#!/usr/bin/awk -f
28c2ecf20Sopenharmony_ci#
38c2ecf20Sopenharmony_ci# Copyright 2010 Ben Dooks <ben-linux@fluff.org>
48c2ecf20Sopenharmony_ci#
58c2ecf20Sopenharmony_ci# Released under GPLv2
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci# example usage
88c2ecf20Sopenharmony_ci# ./clksrc-change-registers.awk arch/arm/plat-s5pc1xx/include/plat/regs-clock.h < src > dst
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cifunction extract_value(s)
118c2ecf20Sopenharmony_ci{
128c2ecf20Sopenharmony_ci    eqat = index(s, "=")
138c2ecf20Sopenharmony_ci    comat = index(s, ",")
148c2ecf20Sopenharmony_ci    return substr(s, eqat+2, (comat-eqat)-2)
158c2ecf20Sopenharmony_ci}
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_cifunction remove_brackets(b)
188c2ecf20Sopenharmony_ci{
198c2ecf20Sopenharmony_ci    return substr(b, 2, length(b)-2)
208c2ecf20Sopenharmony_ci}
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cifunction splitdefine(l, p)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci    r = split(l, tp)
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci    p[0] = tp[2]
278c2ecf20Sopenharmony_ci    p[1] = remove_brackets(tp[3])
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cifunction find_length(f)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci    if (0)
338c2ecf20Sopenharmony_ci	printf "find_length " f "\n" > "/dev/stderr"
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci    if (f ~ /0x1/)
368c2ecf20Sopenharmony_ci	return 1
378c2ecf20Sopenharmony_ci    else if (f ~ /0x3/)
388c2ecf20Sopenharmony_ci	return 2
398c2ecf20Sopenharmony_ci    else if (f ~ /0x7/)
408c2ecf20Sopenharmony_ci	return 3
418c2ecf20Sopenharmony_ci    else if (f ~ /0xf/)
428c2ecf20Sopenharmony_ci	return 4
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci    printf "unknown length " f "\n" > "/dev/stderr"
458c2ecf20Sopenharmony_ci    exit
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cifunction find_shift(s)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci    id = index(s, "<")
518c2ecf20Sopenharmony_ci    if (id <= 0) {
528c2ecf20Sopenharmony_ci	printf "cannot find shift " s "\n" > "/dev/stderr"
538c2ecf20Sopenharmony_ci	exit
548c2ecf20Sopenharmony_ci    }
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci    return substr(s, id+2)
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciBEGIN {
618c2ecf20Sopenharmony_ci    if (ARGC < 2) {
628c2ecf20Sopenharmony_ci	print "too few arguments" > "/dev/stderr"
638c2ecf20Sopenharmony_ci	exit
648c2ecf20Sopenharmony_ci    }
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci# read the header file and find the mask values that we will need
678c2ecf20Sopenharmony_ci# to replace and create an associative array of values
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci    while (getline line < ARGV[1] > 0) {
708c2ecf20Sopenharmony_ci	if (line ~ /\#define.*_MASK/ &&
718c2ecf20Sopenharmony_ci	    !(line ~ /USB_SIG_MASK/)) {
728c2ecf20Sopenharmony_ci	    splitdefine(line, fields)
738c2ecf20Sopenharmony_ci	    name = fields[0]
748c2ecf20Sopenharmony_ci	    if (0)
758c2ecf20Sopenharmony_ci		printf "MASK " line "\n" > "/dev/stderr"
768c2ecf20Sopenharmony_ci	    dmask[name,0] = find_length(fields[1])
778c2ecf20Sopenharmony_ci	    dmask[name,1] = find_shift(fields[1])
788c2ecf20Sopenharmony_ci	    if (0)
798c2ecf20Sopenharmony_ci		printf "=> '" name "' LENGTH=" dmask[name,0] " SHIFT=" dmask[name,1] "\n" > "/dev/stderr"
808c2ecf20Sopenharmony_ci	} else {
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci    }
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci    delete ARGV[1]
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci/clksrc_clk.*=.*{/ {
888c2ecf20Sopenharmony_ci    shift=""
898c2ecf20Sopenharmony_ci    mask=""
908c2ecf20Sopenharmony_ci    divshift=""
918c2ecf20Sopenharmony_ci    reg_div=""
928c2ecf20Sopenharmony_ci    reg_src=""
938c2ecf20Sopenharmony_ci    indent=1
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci    print $0
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci    for(; indent >= 1;) {
988c2ecf20Sopenharmony_ci	if ((getline line) <= 0) {
998c2ecf20Sopenharmony_ci	    printf "unexpected end of file" > "/dev/stderr"
1008c2ecf20Sopenharmony_ci	    exit 1;
1018c2ecf20Sopenharmony_ci	}
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	if (line ~ /\.shift/) {
1048c2ecf20Sopenharmony_ci	    shift = extract_value(line)
1058c2ecf20Sopenharmony_ci	} else if (line ~ /\.mask/) {
1068c2ecf20Sopenharmony_ci	    mask = extract_value(line)
1078c2ecf20Sopenharmony_ci	} else if (line ~ /\.reg_divider/) {
1088c2ecf20Sopenharmony_ci	    reg_div = extract_value(line)
1098c2ecf20Sopenharmony_ci	} else if (line ~ /\.reg_source/) {
1108c2ecf20Sopenharmony_ci	    reg_src = extract_value(line)
1118c2ecf20Sopenharmony_ci	} else if (line ~ /\.divider_shift/) {
1128c2ecf20Sopenharmony_ci	    divshift = extract_value(line)
1138c2ecf20Sopenharmony_ci	} else if (line ~ /{/) {
1148c2ecf20Sopenharmony_ci		indent++
1158c2ecf20Sopenharmony_ci		print line
1168c2ecf20Sopenharmony_ci	    } else if (line ~ /}/) {
1178c2ecf20Sopenharmony_ci	    indent--
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	    if (indent == 0) {
1208c2ecf20Sopenharmony_ci		if (0) {
1218c2ecf20Sopenharmony_ci		    printf "shift '" shift   "' ='" dmask[shift,0] "'\n" > "/dev/stderr"
1228c2ecf20Sopenharmony_ci		    printf "mask  '" mask    "'\n" > "/dev/stderr"
1238c2ecf20Sopenharmony_ci		    printf "dshft '" divshift "'\n" > "/dev/stderr"
1248c2ecf20Sopenharmony_ci		    printf "rdiv  '" reg_div "'\n" > "/dev/stderr"
1258c2ecf20Sopenharmony_ci		    printf "rsrc  '" reg_src "'\n" > "/dev/stderr"
1268c2ecf20Sopenharmony_ci		}
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci		generated = mask
1298c2ecf20Sopenharmony_ci		sub(reg_src, reg_div, generated)
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci		if (0) {
1328c2ecf20Sopenharmony_ci		    printf "/* rsrc " reg_src " */\n"
1338c2ecf20Sopenharmony_ci		    printf "/* rdiv " reg_div " */\n"
1348c2ecf20Sopenharmony_ci		    printf "/* shift " shift " */\n"
1358c2ecf20Sopenharmony_ci		    printf "/* mask " mask " */\n"
1368c2ecf20Sopenharmony_ci		    printf "/* generated " generated " */\n"
1378c2ecf20Sopenharmony_ci		}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci		if (reg_div != "") {
1408c2ecf20Sopenharmony_ci		    printf "\t.reg_div = { "
1418c2ecf20Sopenharmony_ci		    printf ".reg = " reg_div ", "
1428c2ecf20Sopenharmony_ci		    printf ".shift = " dmask[generated,1] ", "
1438c2ecf20Sopenharmony_ci		    printf ".size = " dmask[generated,0] ", "
1448c2ecf20Sopenharmony_ci		    printf "},\n"
1458c2ecf20Sopenharmony_ci		}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci		printf "\t.reg_src = { "
1488c2ecf20Sopenharmony_ci		printf ".reg = " reg_src ", "
1498c2ecf20Sopenharmony_ci		printf ".shift = " dmask[mask,1] ", "
1508c2ecf20Sopenharmony_ci		printf ".size = " dmask[mask,0] ", "
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci		printf "},\n"
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	    }
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	    print line
1578c2ecf20Sopenharmony_ci	} else {
1588c2ecf20Sopenharmony_ci	    print line
1598c2ecf20Sopenharmony_ci	}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	if (0)
1628c2ecf20Sopenharmony_ci	    printf indent ":" line "\n" > "/dev/stderr"
1638c2ecf20Sopenharmony_ci    }
1648c2ecf20Sopenharmony_ci}
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci// && ! /clksrc_clk.*=.*{/ { print $0 }
167