Although you can fake this with an extension to HashMap (as mentioned in another answer), I don't think that's a good solution: in order to make the map's behaviour fully consistent, you'd probably need to override lots of methods. (For example, it would be hard to ensure that it maintained the case-insensitivity if you update the map via its keySet. And there are probably many more gotchas along the way.)
In most cases, you don't really need a HashMap specifically — you just need a Map implementation. And so an alternative is to use another type of map that lets you provide your own Comparator, e.g.:
val items = TreeMap<String, Int>{ a, b ->
a.toLowerCase().compareTo(b.toLowerCase())
}
TreeMap is an implementation of SortedMap — a special type of Map that keeps its keys in order: either their natural ordering, or one you provide. In this case, I've given a simple Comparator implementation which compares the lower-case versions of the two strings.
With this definition, the rest of the code in the question runs fine, and prints out:
C = 70
key1 = 80
…i.e. it has recognised that "Key1" should be treated the same as "key1", and updated that value instead of adding a new one. I think this is the behaviour you want.
You don't need to take account of the fact that the map is sorted; that's just an added bonus. You can still treat it like any other Map implementation, and everything should work.
(This is yet another example of why it's better to program to the interface, not the implementation. If you write code that can use any Map implementation, you can give it a HashMap or a TreeMap or any other sort of map without any changes.)